/*jslint browser: true, white: false, plusplus: false, evil: true, undef: false, bitwise: false, nomen: false */

/* 
	var dojo,escape,unescape,window,widget,object,CFKIT_GLOBAL;
*/




/* General purpose object for handling cookies. 

NOTE: The word delete can not be used as a function name so clear was used instead.
The cookie code was build using code found here: http://www.irt.org/articles/js064/index.htm

Modified by M.Scherzer, cfavatar.com

public domain cookie code written by:
Bill Dortch, hIdaho Design
(bdortch@netw.com)
*/
var cookie = {
	getExpDate : function (days, hours, minutes) {
		var expDate = new Date();
		if (typeof days === 'number' && typeof hours === 'number' && typeof minutes === 'number') {
			expDate.setDate(expDate.getDate() + parseInt(days,10));
			expDate.setHours(expDate.getHours() + parseInt(hours,10));
			expDate.setMinutes(expDate.getMinutes() + parseInt(minutes,10));
			return expDate.toUTCString();
		}
		return;
	},

	get : function (name) {
		var start,len,end;
		start = document.cookie.indexOf(name+"=");
	    len = start+name.length+1;
	    if ((!start) && (name !== document.cookie.substring(0,name.length))) {
return null;
}
	if (start === -1) {
		return null;
	}
	end = document.cookie.indexOf(";",len);
	if (end === -1) {
		end = document.cookie.length;
	}
	return unescape(document.cookie.substring(len,end));
	},

	set : function (name, value, expires, path, domain, secure) {
		document.cookie = name + "=" + escape(value) +
((expires) ? ";expires=" + expires : "") +
((path) ? ";path=" + path : "") +
((domain) ? ";domain=" + domain : "") +
((secure) ? ";secure" : "");
return;
	},

	clear : function (name, path, domain) {
		if (this.get(name)){ 
			document.cookie = name + "=" +
	((path) ? ";path=" + path : "") +
	((domain) ? ";domain=" + domain : "") +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
		}
		return;
	}
};


/* 
	The utility object bundles a set of frequently used functions into their own namespace. 
*/
var cfkit_util = {
	/* 
		Controls the display state of an HTML Elements.
		id= The ID of the html element.
		show= True shows the object, False hides the object.
		WARNING: When showing an object the display is set to block, this may not be what is desired.
	 */
	display : function (id, show) {
		var panel = dojo.byId(id);
		if(show){
			panel.style.display = 'block';
		}else{
			panel.style.display = 'none';
		}
		return;
	},
	
	/*
	Get the position of the view port. 
	*/
	getViewPortY : function(){
		var y = window.pageYOffset;
		if(y === undefined){
			y = document.documentElement.scrollTop;
		}
		return y;
	},
	
	
	/*
		For use when NOT using dojo.
		Alternate cross browser method for referencing a HTML element by its ID. 
		Use this when we are NOT using the dojo library. In dojo we would use dojo.byId
		WARNING: The dojo implementation has more functionality then this light weight version.
	*/
	byId : function(x) {
		if (document.getElementById) {
			return document.getElementById(x);
		}
	else if (document.all) {
		return document.all[x];
	}
	else if (document.layers){
		 return document.layers[x];
	}
	else{
			return null;
	}
	},
	
	
	/*
		GUP = Get Url Parameter.
		Searches the URL parameters in the currect document address. If a parameter matches
		the value given as name returns the value of the parameter.
		
		If the parameter is not defined returns an empty string.
	*/
	gup : function(name){	/* Get URL parameter value of name */
	  var regexS,regex,results;
	  
	  name = name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");
	  /* name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); This line is the original line before modifying the code to suit jslint.  */
	  regexS = "[\\?&]"+name+"=([^&#]*)";
	  regex = new RegExp( regexS );
	  results = regex.exec( window.location.href );
	  if( results === null ){
		return "";
	}  
	  else{
	    return results[1];
	  }
	},
	
	/* 
		Following is a set of functions for converting 
		Units from metric to imperial and back. 
	*/
	m2km : function(m) {
		return m * 0.001;
	},
	km2m : function(km) {
		return km * 1000;
	},
	miles2m : function(miles) {
		return miles * 1609.344;
	},
	m2miles:function(m){
		return m * 6.213712e-4;
	},
	m2ft:function(m){
		return m * 3.28084;
	},
	ft2m:function(ft){
		return ft * 0.3048;
	},
	fromMetersTo:function(unit,value){
		switch(unit){
			case 'km':
			return cfkit_util.m2km(value);	
			case 'm':
			return value;	
			case 'miles':
			return cfkit_util.m2miles(value);	
			case 'ft':
			return cfkit_util.m2ft(value);	
			default:
			alert('Unknown conversion in fromMeterTo');
		}		
		return 0;
	},
	toMetersFrom:function(unit,value){
		switch(unit){
			case 'km':
			return cfkit_util.km2m(value);	
			case 'm':
			return value;	
			case 'miles':
			return cfkit_util.miles2m(value);	
			case 'ft':
			return cfkit_util.ft2m(value);	
			default:
			alert('Unknown conversion in fromMeterTo');
		}		
		return 0;
	},
	/* 
	Formatting functions. 
	*/
	money:function(value,currency,localeid){
		/* This logic must be kept in sync with the cfml equivalant in the display component. 
		   Also the symbols and currency must be kept with the cfkit.utl.getCurrency() method.
		*/
		var tmp,symbol;
		switch(currency){
			case 'AUD':
				symbol = 'A$';
				break;
			case 'EUR':
				symbol = '€';
				break;
			case 'USD':
				symbol = '$';
				break;
			case 'CAD':
				symbol = 'C$';
				break;
			case 'CHF':
				symbol = 'CHF';
				break;
			case 'GBP':
				symbol = '£';
				break;
			case 'SEK':
				symbol = 'kr';
				break;
			default:
			symbol = '$';
		}
		
		switch(localeid){
			case 1:
			tmp = value.toFixed(2).toString(); /* Stop LINT from complaining that switch should be an if. */
			break;
			case 2:
			tmp = value.toFixed(2).toString();
			tmp = tmp.replace('.',',');
			break;
			default:
			tmp = value.toFixed(2).toString();
		}
		
		return symbol + String.fromCharCode(32) + tmp;
	},
	
	/* 
		Date conversion functions. 
		fromDBdate and toDBdate handle converting a javascript date object to a odbcFormated string and back.
	*/
	fromDBdate:function(value){	
		return new Date(value.substring(5,9),(value.substring(10,12) - 1),value.substring(13,15),value.substring(16,18),value.substring(19,21),value.substring(22,24));
	},
	
	toDBdate:function(date){
		var string = "{ts '"; 
		string = string + date.getFullYear() + '-';
		string = string + cfkit_util.padDigit((date.getMonth() + 1),2) + '-';
		string = string + cfkit_util.padDigit(date.getDate(),2) + ' ';/* Insert One Space */
		string = string + cfkit_util.padDigit(date.getHours(),2) + ':';
		string = string + cfkit_util.padDigit(date.getMinutes(),2) + ':';
		string = string + cfkit_util.padDigit(date.getSeconds(),2) + "'}";
		return string;
	},
	
	
	/* 
		String functions. 
		Ensures that value is at least as long as len. Any missing positions are left padded
		with the number zero (0). 
	*/
	padDigit:function(value,len){  
        var pd,i; 
        pd = '';
	value = value.toString();
        if (len > value.length) 
        { 
            for (i=0; i < (len-value.length); i++) 
            { 
                pd += '0'; 
            } 
        } 
        return pd + value.toString(); 
    },
    
    /* Trims white space from the beginning and end of a string */
    trim:function (stringToTrim) {
		return stringToTrim.replace(/^\s+|\s+$/g,"");
	},
	
	/* Trims white space from the beginning of a string */
	ltrim:function(stringToTrim) {
		return stringToTrim.replace(/^\s+/,"");
	},

	/* Trims white space from the end of a string */
	rtrim:function(stringToTrim) {
		return stringToTrim.replace(/\s+$/,"");
	},
	
	
	/* 
	Sort array of objects using the shell sort algorithm.
	Key is the objects property to sort on.
	
	date = Array of objects.
	key = Is the object property which contains the values on which to be sorted.
	*/
	sort:function(data,key){	
		var j,n,inc,i,tmp;
		if(data.length === 0){
			return data;
		}
		j = 0;
		n = data.length;
		inc=cfkit_util.round(n/2,0);
		while(inc > 0) {
			for(i=inc;i<= n-1;i++){
				tmp = data[i];
				j = i;
				while(j>= inc && data[j-inc][key] > tmp[key]){
					data[j] = data[j-inc];
					j = j - inc;
				}
				data[j] = tmp;
			}
			inc=cfkit_util.round(inc/2.2,0);
		}
		return data;
	},

	/* 
		Math Functions.
		
		Round the given value to decimal number of places.
	*/
	round : function(value, decimals) {
	    var tmp = Math.round((value * Math.pow(10,decimals)));
	    return (tmp / Math.pow(10, decimals));
	},
	
	
	/* 
		createGUID creates a pseudo GUID for unique ajax request.
	
		Not a real GUID, and not compatible with CF UUID, 
		good enough for unique requests! 
	*/
	createGUID : function() { 
		return (this._S4()+this._S4()+"-"+this._S4()+"-"+this._S4()+"-"+this._S4()+"-"+this._S4()+this._S4()+this._S4());
	},
	
	/* Helper for the createGUID method. */
	_S4:function(){
		return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
	},
	
	/* 
		Animation. 
		
		fade in the html element with the given elementId.
	*/
	fadeIn : function(elementId) {		
		var easingFunc = function(x){
							return Math.pow(x,10);
						};
		dojo.fadeIn({
		    node: elementId,
		    duration: 2000,
		    easing:easingFunc,
		    beforeBegin: function() {
		        var node = dojo.byId(elementId);
		        dojo.style(node, "opacity", 0);
		        dojo.style(node, "display", "block");
		    }
		}).play();
		return;
	},
	
	/* fade out the html element with the given elementId. */
	fadeOut:function(elementId){
		var easingFunc = function(x){
							return Math.pow(x,10);
						};
		dojo.fadeOut({
			node:widget,
		    duration: 2000,
		    easing:easingFunc
		}).play();
		return;
	},
	
	/* blends in then blends out the html element with the given elementId. Useful for given a brief status update. */
	fadeInOut:function(elementId){		
		var easingFunc = function(x){
							return Math.pow(x,10);
						};
		dojo.fadeIn({
			node:elementId,
			duration: 1000,
			easing:easingFunc,
		    beforeBegin: function() {
		        var node = dojo.byId(elementId);
		        dojo.style(node, "opacity", 0);
		        dojo.style(node, "display", "block");
			return;
		},
		    onEnd: function(){
			dojo.fadeOut({
					node:elementId,
					duration: 2000,
					easing:easingFunc,
					delay:2500,
					onEnd: function(){
						var node = dojo.byId(elementId);
						dojo.style(node, "display", "none");
						return;
					}
				}).play();
				return;
			}
		}).play();
		return;
	},
	
	/* Javascript redirect. Takes the user to a differnt page. As specified by target. */
	redirect:function(target){
		//location.href=target;
		window.location = target;
		return;
	}
};

var cfkit_InfoPane = function(prefix){
	this.init(prefix);
	return;
};

cfkit_InfoPane.prototype = {
	prefix:'',
	pnl_overlay:'',
	pnl_container:'',
	pnl_busy:'',
	pnl_msg:'',
	init:function(prefix){
		this.prefix = prefix;
		this.pnl_overlay = prefix + '_overlay';
		this.pnl_container = prefix + '_container';
		this.pnl_busy = prefix + '_busy';
		this.pnl_msg = prefix + '_msg';
	},
	
	busy:function(){
		cfkit_util.display(this.pnl_overlay,true);
		cfkit_util.display(this.pnl_container,true);
		cfkit_util.display(this.pnl_busy,true);
		cfkit_util.display(this.pnl_msg,false);
		return;
	},
	
	hide:function(){
		cfkit_util.display(this.pnl_overlay,false);
		cfkit_util.display(this.pnl_container,false);
		cfkit_util.display(this.pnl_busy,false);
		cfkit_util.display(this.pnl_msg,false);
		return;	
	},
	
	log:function(msg,fixed){
		var viewPortY;
		dojo.byId(this.prefix + '_msg_inset').innerHTML = msg;
		cfkit_util.display(this.pnl_overlay,true);
		cfkit_util.display(this.pnl_container,true);
		cfkit_util.display(this.pnl_busy,false);
		cfkit_util.display(this.pnl_msg,true);
		cfkit_util.display(this.prefix + '_msg_close',false);
		
		if(fixed!==undefined && fixed){
			viewPortY = cfkit_util.getViewPortY();
			dojo.byId(this.pnl_msg).style.top = cfkit_util.getViewPortY() + 'px';
		}
		
		return;
	},
	
	msg:function(msg,screenY,fnClose,fixed){
		var viewPortY, closeBtn;
		dojo.byId(this.prefix + '_msg_inset').innerHTML = msg;
		cfkit_util.display(this.pnl_overlay,true);
		cfkit_util.display(this.pnl_container,true);
		cfkit_util.display(this.pnl_busy,false);
		cfkit_util.display(this.pnl_msg,true);
		cfkit_util.display(this.prefix + '_msg_close',true);
		dojo.byId(this.prefix + '_btnClose').focus();
		/*
		See how the application works when we always try to show 
		the message using fixed positioning. Also see code below!
		if(screenY === undefined && fixed === undefined){
			window.scrollTo(0,0);
		} else if(screenY >= 0){
			window.scrollTo(0,screenY);
		}
		
		if(fixed!==undefined && fixed){
			viewPortY = cfkit_util.getViewPortY();
			dojo.byId(this.pnl_msg).style.top = cfkit_util.getViewPortY() + 'px';
		}
		*/
		viewPortY = cfkit_util.getViewPortY();
		dojo.byId(this.pnl_msg).style.top = cfkit_util.getViewPortY() + 'px';
		
		if(fnClose!==undefined){	
			closeBtn = dojo.byId(this.prefix + '_btnClose');
			if(window.addEventListener){ // Mozilla, Netscape, Firefox
				closeBtn.addEventListener('click',fnClose, false);
			} else { // IE
				closeBtn.attachEvent('onclick', fnClose);
			}
		}
		
		return;
	}
};


var cfkit_ctx = {
	initialised:false,
	locale:'',
	init:function(){
		cfkit_ctx.locale = cookie.get('CFKITINT');
		if(!cfkit_ctx.locale){
			/* Defaul to united states, do not override context. */
			cfkit_ctx.locale = new Array(5);
			cfkit_ctx.locale[0] = 2; 
			cfkit_ctx.locale[1] = 'en';
			cfkit_ctx.locale[2] = '2';
			cfkit_ctx.locale[3] = '0';
		}else
		{
			cfkit_ctx.locale = cfkit_ctx.locale.split( "|" );
		}
		cfkit_ctx.initialised = true;
		return;
	},
	getLanguage:function(){
		if(!cfkit_ctx.initialised) {
			cfkit_ctx.init();
		}
		return cfkit_ctx.locale[1];
	},
	getLocaleID:function(){
		if(!cfkit_ctx.initialised){
			cfkit_ctx.init();
		}
		return cfkit_ctx.locale[2];
	},
	getTZ:function(){
		if(!cfkit_ctx.initialised) {
			cfkit_ctx.init();
		}
		return cfkit_ctx.locale[3];
	}
};


var localeWidget = {
	setLocale : function (){
		var i,frm, locale, newLocale;
		
		frm = document.getElementById("frmIntPref");
		locale = cookie.get('CFKITINT');
		newLocale = '';
	
		if(!locale){
			locale = new Array(5);
		}else
		{
			locale = locale.split( "|" );
		}
		/* See ctx object cfc for details. */
		locale[0] = 1; 
		locale[1] = frm.language.options[frm.language.selectedIndex].value;
		locale[2] = frm.localeID.options[frm.localeID.selectedIndex].value;
		locale[3] = frm.tz.options[frm.tz.selectedIndex].value;
		locale[4] = frm.tzSummerTime.options[frm.tzSummerTime.selectedIndex].value;
		locale[5] = frm.isMetric.options[frm.isMetric.selectedIndex].value;
	
		newLocale = locale[0];
		for(i=1;i<locale.length;i++){
			newLocale = newLocale + '|' + locale[i];
		}
	
		cookie.set('CFKITINT',newLocale,cookie.getExpDate(365,0,0),'/');
	
		this.hide();
	
		/*  DO NOT USE .reload as this may repeat post requests! */
		if(dojo.byId("request_method").value === 'get'){
			if(dojo.byId("cfkit_L10N").value === 'dynamic'){
				window.location.reload();	
			}else{
				window.location = '/';
			}
		}else{
			alert('Changes will be applied on next page request.');
		}
		
		return;
	},
	
	show :function(){
		var widget = document.getElementById("localeWidget");
		widget.style.display = 'block';
		return;
	},
	
	hide : function(){
		var widget = document.getElementById("localeWidget");
		widget.style.display = 'none';
		return;
	},
	
	toggle : function(){
		var widget = document.getElementById("localeWidget");
		if(widget.style.display === 'none'){
			this.show();
		}else{
			this.hide();
		}
		return;
	}
};


/* 
	Translation object, used to localize an application at runtime using javascript.
	
	txt
	Replaces the content of the element specified by id.
	
	id = The element for which content will be replaced.
	vars = 
		Allows replacing of variables in the txt. Variables are indicated with a %1, %2, %3 etc.
		vars is an array of variables which are replaced in the string. If vars is a string or number
		only %1 is replaced.
	key = The key to use for looking up the text that is to be translated. If key is not specified it defaults
		to the value of the passed in ID.
*/
var loc = {
	language:'',
	txt:function(id,vars,key){
		var element = '';
		
		if(typeof(key)==='undefined'){
			key = id;
		}
		element = dojo.byId(id);
		
		if(element === null){
			alert('Could not find id:' + id);
		}else{
			element.innerHTML = loc.get(key,vars);
		}
		
		return;
	},
	
	get:function(key,vars){
		/* Looks up the specified key and replaces the contained parameters with vars
		 vars is optional.
		 if vars is a string or number only one variable is replaced.
		 if vars is an array each element is replaced. NOTE: Place holders start at %1.
		*/
		var i,lookup,text,str;
		switch(loc.language){
			case 'de':
				lookup = de;
			break;
			case 'en':
				lookup = en;
			break;
			default:
				lookup = en;
		}
		
		text = lookup[key];
		str = '';
		
		if(typeof(vars)==='undefined') {
			return text;
		}
		if(typeof(vars)==='string' || typeof(vars)==='number'){
			return text.replace('%1',vars);
		}
		if(vars !== null){
			for(i=0;i<vars.length;i++){
				str = '%' + (i+1);
				text = text.replace(str,vars[i]);
			}
		}	
		
		return text;
	}	
};


function detectLanguage(){
	var lan,str,pos; 
	lan = cfkit_util.gup('ctx_lan');
	
	if(lan===''){
		lan = cfkit_ctx.getLanguage();
	}
	
	if(lan!==''){
		loc.language = lan;
		return;
	}

	str = /de/;
	pos = document.domain.search(str);
	if(pos !== -1){
		loc.language = 'de';
		return;
	}
	
	loc.language = 'en';
	return;
}

/* ###################################################### */
/* Global class used to work with a radio group. */
/* 
  Usage: 
  Pass in the name of the radioGroup (The value of the name attribute)
  
  eg. var survey = new RadioGroup("statButtons");
  
  Notes: 
  The name of the radiogroup must be unique per document.
  
  IMPORTANT: Only works if the RadioGroup object is instantiated after the document has loaded.
 * */
var RadioGroup = function(name){
	var grp,i;
	this.name = name;
	this.data = [];
	this.selectedIndex = 0;
	grp = document.getElementsByName(name);
	
	for(i=0;i<grp.length;i++){
		this.data[i] = {};/*new Object()*/
		this.data[i].btn = grp[i];
		if(this.data[i].btn.checked){
			this.selectedIndex=i;
		}
	}
	return;
};

RadioGroup.prototype = {
	set:function(value){
		value = value.toString();
		this.selectedIndex = 0;
		for(var i=0;i<this.data.length;i++){
			this.data[i].btn.checked = (this.data[i].btn.value.toString() === value) ?  true : false;
			if(this.data[i].btn.checked){
				this.selectedIndex = i;
			}
		}
		return this.selectedIndex;
	
	},
	get:function(){
		for(var i=0;i<this.data.length;i++){
			if(this.data[i].btn.checked) {
				return this.data[i].btn.value;
			}
		}
		return null;
	}
};
/* ###################################################### */





/* ###################################################### */
/* Global class used to work with drop down select boxes. */
var SelectBox = function(id){
	this.id = id;
	return;
};

SelectBox.prototype = {
	id : '',
	setValue:function(value){
		var widget,i;
		value = value.toString();
		widget = dojo.byId(this.id);
		for(i=0;i<widget.options.length;i++){
			if(widget.options[i].value.toString() === value){
				widget.selectedIndex = i;
			}
		}
		return widget.selectedIndex;
	},
	
	getValue:function(){
		var widget = dojo.byId(this.id);
		return widget.options[widget.selectedIndex].value;
	},
	
	getText:function(){
		var widget = dojo.byId(this.id);
		return widget.options[widget.selectedIndex].text;
	},
	
	getSelectedIndex:function(){
		var widget = dojo.byId(this.id);
		return widget.selectedIndex;
	}
};
/* ###################################################### */




/* ###################################################### */
/* Global class used to work with a popups group. */
var pop_up;
function open_popup(url,name,width,height)
{
	pop_up = window.open(url,name,'width=' + width + ',height=' + height + ',toolbar=0,menubar=0,scrollbars=1');
	if (window.focus) {
		pop_up.focus();
	}
	return pop_up;
}

function viewProfile(userID){
	var url = '/usr/profile.cfm?userid=' + userID;
	cfkit_util.redirect(url);
	/* 
	 var url = '/usr/profile.cfm?popup=true&userid=' + userID;
	 open_popup(url,'profile',600,600); 
	 */
	return;
}
/* ###################################################### */





/* ###################################################### */
function help(tag){
	open_popup('/xmas/' + CFKIT_GLOBAL.language + '/help.cfm?popup=1#'+tag,'Help',400,400);
	return;
}


function vIE(){
	return (navigator.appName==='Microsoft Internet Explorer')?parseFloat((new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})")).exec(navigator.userAgent)[1]):-1;
}

function blockIE(){
	var ie = vIE();
	if (ie === -1 || ie > 6) {
		return;
	}
	document.location = '/xmas/legacy.htm';
	return;
}

var cfkit_award = {
	display:function(award){
		if(!award.AWARDED) {
			return;
		}
		dojo.byId('awardContent').innerHTML = award.MSG.DISPLAYTXT;
		cfkit_util.fadeInOut('awardWidget');
		return;
	}
};
/* ###################################################### */