﻿/*
*
* Various utility functions
*/
/// define the global namespace




var RJCTK = {};
    
/// define the Utils namespace
RJCTK.Utils = {};

// Cookie management************************************************************************************************

/// Sets a cooke given certain specifications.  It overrides any existing
/// cookie with the same name.
///

RJCTK.Utils.writeCookie = function ( name, value, expires, domain, path, secure ) 
{
// set time, it's in milliseconds
var today = new Date();
today.setTime( today.getTime() );

/*
if the expires variable is set, make the correct 
expires time, the current script below will set 
it for x number of days, to make it for hours, 
delete * 24, for minutes, delete * 60 * 24
*/
if ( expires )
 {
   expires = expires * 1000 * 60 * 60 * 24;
 }
var expires_date = new Date( today.getTime() + (expires) );

document.cookie = name + "=" +escape( value ) +
( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
( ( path ) ? ";path=" + path : "" ) + 
( ( domain ) ? ";domain=" + domain : "" ) +
( ( secure ) ? ";secure" : "" );
};

/**
 * Retrieves the value of a cookie.
 *
 * @param name [string] the cookie name
 * @return [string or null] a string with the cookie value, or null if it can't be found.
 */
RJCTK.Utils.getCookie= function ( name ) {
	
var start = document.cookie.indexOf( name + "=" );
var len = start + name.length + 1;
if ( ( !start ) &&
( name != document.cookie.substring( 0, name.length ) ) )
    {
    return null;
    }
if ( start == -1 )
    {
    return null;
    }
var end = document.cookie.indexOf( ";", len );
if ( end == -1 ) {end = document.cookie.length;}
return unescape( document.cookie.substring( len, end ) );
};


// this deletes the cookie when called
RJCTK.Utils.deleteCookie=function ( name, path, domain ) {
if ( Get_Cookie( name ) ){ document.cookie = name + "=" +
( ( path ) ? ";path=" + path : "") +
( ( domain ) ? ";domain=" + domain : "" ) +
";expires=Thu, 01-Jan-1970 00:00:01 GMT";}
};

/// Retrieves the absolute position (relative to <body>) of a given element.
///
/// @param el [HTMLElement] reference to the element.
/// @return [object] { x, y } containing the position.
RJCTK.Utils.getAbsolutePos = function(el) {        
    
    var SL = 0, ST = 0;
    var is_div = /^div$/i.test(el.tagName);
    if (is_div && el.scrollLeft) {SL = el.scrollLeft;}
    if (is_div && el.scrollTop) {ST = el.scrollTop;}
    var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
    if (el.offsetParent) {
        var tmp = this.getAbsolutePos(el.offsetParent);
        r.x += tmp.x;
        r.y += tmp.y;
    }
    return r;
};

RJCTK.Utils.moveElementNear = function (el, moveElement)
{
    var pos = RJCTK.Utils.getAbsolutePos(el);
    var size= RJCTK.Utils.getAbsoluteSize(el);
    moveElement.style.left = pos.x + size.x;
    moveElement.style.top = pos.y + size.y/2;
    var elementSize=RJCTK.Utils.getAbsoluteSize(moveElement);    
    if (pos.x + size.x+elementSize.x> document.body.clientWidth)
    {
        moveElement.style.left= document.body.clientWidth-elementSize.x;
        }
    
};

/// Retrieves the absolute size of a given element.
///
/// @param el [HTMLElement] reference to the element.
/// @return [object] { x, y } containing the position.
RJCTK.Utils.getAbsoluteSize= function(el) {
 var r = { x: el.offsetWidth, y: el.offsetHeight};
 return r;
};
/// Remove a certain [CSS] class from the given element.
/// @param el [HTMLElement] reference to the element.
/// @param className [string] the class to remove.
RJCTK.Utils.removeClass = function(el, className) {
    if (!(el && el.className)) {
        return;
    }
    var cls = el.className.split(" ");
    var ar = [];
    for (var i = cls.length; i > 0;) {
        if (cls[--i] != className) {
            ar[ar.length] = cls[i];
        }
    }
    el.className = ar.join(" ");
};

var hD="0123456789ABCDEF";
RJCTK.Utils.hex = function (d)
{
var h = hD.substr(d&15,1);
while(d>15) {d>>=4;h=hD.substr(d&15,1)+h;}
return h;
};
RJCTK.Utils.LighterColor = function (c, difference)
{
       var r = parseInt(c.substring(1,3),16)+difference;
       var g = parseInt(c.substring(3,5),16)+difference;
       var b = parseInt(c.substring(5,7),16)+difference;
       if (r>255) {r=255;}if (r<0) {r=0;}
       if (g>255) {g=255;}if (g<0) {g=0;}
       if (b>255) {b=255;}if (b<0) {b=0;}
       return  "#"+ RJCTK.Utils.hex(r) + RJCTK.Utils.hex(g)+ RJCTK.Utils.hex(b);
};
/// Appends a certain [CSS] class to the given element.
/// @param el [HTMLElement] reference to the element.
/// @param className [string] the class to append.
RJCTK.Utils.addClass = function(el, className) {
    RJCTK.Utils.removeClass(el, className);
    el.className += " " + className;
};
RJCTK.Utils.IsClass = function(el,className)
{
     if (!(el && el.className)) {
            return;
        }
        var cls = el.className.split(" ");        
        for (var i = cls.length; i > 0;) {
        if (cls[--i] == className) {
            return true;
        }
    }
    return false;
};
RJCTK.Utils.ToggleClass = function(el,className1,className2)
{
        if (!(el && el.className)) {
            return;
        }
        if (RJCTK.Utils.IsClass(el,className1))
            {
                RJCTK.Utils.removeClass(el,className1);
                RJCTK.Utils.addClass(el,className2);
            }
       else 
            {
                RJCTK.Utils.removeClass(el,className2);
                RJCTK.Utils.addClass(el,className1);
            }
};
/// Adds an event handler to a certain element.  This function adds a handler
/// using the DOM2 addEventListener (or attachEvent for MSIE).  Doing this
/// means that you can add multiple handlers for the same element and same
/// event name, and they will be called in order.
///
/// WARNING: for really old browsers that don't support attachEvent nor
/// addEventListener, it falls back to the default way: el.onclick = func.
/// This means that you CANNOT add multiple handlers in those browsers, as a
/// new one will override the old one.
///
/// @param el [HTMLElement] reference to the element.
/// @param evname [string] the event name, excluding the "on" prefix.
/// @param func event handler function.
RJCTK.Utils.addEvent = function(el, evname, func) {
    if (el.attachEvent) { // IE
        el.attachEvent("on" + evname, func);
    } else if (el.addEventListener) { // Gecko / W3C
        el.addEventListener(evname, func, false);
    } else {
        el["on" + evname] = func;
    }
};

/// Removes an event handler added with RJCTK.Utils.removeEvent().  The
/// prototype scheme is the same.
RJCTK.Utils.removeEvent = function(el, evname, func) {
    if (el.detachEvent) { // IE
        el.detachEvent("on" + evname, func);
    } else if (el.removeEventListener) { // Gecko / W3C
        el.removeEventListener(evname, func, false);
    } else {
        el["on" + evname] = null;
    }
};

RJCTK.Utils.getTargetElement = function(ev) {
    if (RJCTK.is_ie) {
        return window.event.srcElement;
    } else {
        return ev.target;
    }
};
/// Create an element of a certain type using document.createElement().  A
/// function was needed in order to add some common attributes to all created
/// elements, but also in order to be able to use it in XHTML too (Gecko and
/// other W3C-compliant browsers).
///
/// This function will create an element of the given type and set certain
/// properties to it: unselectable for IE, and the CSS "-moz-user-select" for
/// Gecko, in order to make the element unselectable in these browsers.
/// Optionally, if the second argument is passed, it will appendChild() the
/// newly created element to its parent.
///
/// @param type [string] the tag name of the new element.
/// @param parent [HTMLElement, optional] a parent for the new element.
/// @return [HTMLElement] reference to the new element.
RJCTK.Utils.createElement = function(type, parent) {
    var el = null;
    if (window.self.document.createElementNS)
    {
        // use the XHTML namespace; IE won't normally get here unless
        // _they_ "fix" the DOM2 implementation.
        el = window.self.document.createElementNS("http://www.w3.org/1999/xhtml", type);}
    else
        {el = window.self.document.createElement(type);}
    if (typeof parent != "undefined"){ parent.appendChild(el);}
    if (RJCTK.is_ie){
        el.setAttribute("unselectable", true);}
    if (RJCTK.is_gecko){
        el.style.setProperty("-moz-user-select", "none", "");}
    return el;
};

// Date management************************************************************************************************

RJCTK.Utils.DaysNames           =["Su","Mo","Tu","We","Th","Fr","Sa"];
RJCTK.Utils.MonthNames          =["January","February","March","April","Mai","June","July","August","September","Octomber","November","December"];
function LZ(x) {return(x<0||x>9?"":"0")+x;}
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		//if (token.length < minlength) { return null; }		
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
RJCTK.Utils.formatDate = function(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value= { y:"" };
	if (y.length < 4) {y=""+(y-0+1900);}
	value.y=""+y;
	value.yyyy=y;
	value.yy=y.substring(2,4);
	value.M=LZ(M);
	value.MM=LZ(M);
	value.MMM=RJCTK.Utils.MonthNames[M-1];
	value.NNN=RJCTK.Utils.MonthNames[M+11];
	value.d=LZ(d);
	value.dd=LZ(d);
	value.E=RJCTK.Utils.DaysNames[E+7];
	value.EE=RJCTK.Utils.DaysNames[E];
	value.H=LZ(H);
	value.HH=LZ(H);
	if (H===0){value.h=12;}
	else if (H>12){value.h=H-12;}
	else {value.h=H;}
	value.hh=LZ(value.h);
	if (H>11){value.K=H-12;} else {value.K=H;}
	value.k=H+1;
	value.KK=LZ(value.K);
	value.kk=LZ(value.k);
	if (H > 11) { value.a="PM"; }
	else { value.a="AM"; }
	value.m=LZ(m);     //minutes and months are overlapping
	value.mm=LZ(m);
	value.s=LZ(s);
	value.ss=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	};
	
RJCTK.Utils.getDateFromFormat=function (val,format) {
    
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	var i;
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}   
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year===null) { return 0; }
			i_val += year.length;
			if (year.length==2) {			
			        
				        if (year > 70) { year=1900+(year-0); }
				        else { year=2000+(year-0); }
				    				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (i=0; i<RJCTK.Utils.MonthNames.length; i++) {
				var month_name=RJCTK.Utils.MonthNames[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (i=0; i<RJCTK.Utils.DaysNames.length; i++) {
				var day_name=RJCTK.Utils.DaysNames[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month===null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date===null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh===null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh===null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh===null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh===null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm===null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss===null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {
			            var newdate=new Date(year,month-1,date,hh,mm,ss);
	                    return newdate.getTime();
			}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		};
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		};
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; };
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	};
	
	
RJCTK.Utils.ReplaceValue = function(val,start,newvalue)
{
 var returnValue="";
 var varNewValue =""+newvalue;
 if (start>0)
   returnValue=val.substring(0,start);
   
 returnValue= returnValue + varNewValue;
 
 var endpos = start + varNewValue.length; 
  if (endpos < val.length) 
    {
        returnValue =returnValue+ val.substring(endpos,val.length);
    };
   
  return returnValue; 
};
RJCTK.Utils.getCorrectDateFromFormat=function (val,format) {
		
	val=val+"";
	var returnVal = val;
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < val.length) {	    
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < val.length)) {
			token += format.charAt(i_format++);
			};
			
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; };
			if (token=="yy")   { x=2;y=2; };
			if (token=="y")    { x=2;y=4; };
			year=_getInt(val,i_val,x,y);
			if (year==null) { year=now.getYear();};
			
			if (year.length < y)
			{
			    if (year.length - y ==-3)
			      year = year*1000;
			    else if (year.length -y ==-2)
			     year = year*100;
			     else if (year.length -y ==-1)
			     year = year*10;
			    
			};
			if (year.length==2) {
			
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); };
			
				};
		    if (year<1900) year=1900;
		    if (year>2100) year=2100;
			year=year+"";
			
			returnVal=	RJCTK.Utils.ReplaceValue(returnVal,i_val,year);
			i_val += year.length;
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<RJCTK.Utils.MonthNames.length; i++) {
				var month_name=RJCTK.Utils.MonthNames[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; };
						returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,month_name);
						i_val += month_name.length;
						break;
						};
					};
				};
			if ((month < 1)||(month>12)){return returnVal;};
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<RJCTK.Utils.DaysNames.length; i++) {
				var day_name=RJCTK.Utils.DaysNames[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
				    returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,day_name);
					i_val += day_name.length;
					break;
					};
				};
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,1,2);
			
			if (month==null){return "";}
			if (month<0) month=1+"";
			if (month>12) month=12+"";
			returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,month);
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,1,2);
			if(date==null){			
			    return returnVal;};
			if (date<0) date=0+"";
			if (date>31) date=31+"";
			returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,date);
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,1,2);
			if(hh==null||(hh<1)||(hh>12)){return returnVal;};
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,1,2);
			if(hh==null){return returnVal;};
			if (hh<0) hh=0+"";
			if (hh>23) hh=23+"";
			returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,hh);
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return returnVal;};
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return returnVal;};
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,1,2);
			if(mm==null){return returnVal;};
			if (mm<0) mm=0+"";
			if (mm>59) mm=59+"";
			returnVal =	RJCTK.Utils.ReplaceValue(returnVal,i_val,mm);
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return returnVal;};
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return "";};
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return returnVal;}
			else {i_val+=token.length;};
			};
		};
		
	return returnVal;
	};


// WCH management************************************************************************************************
// ugly little bug in IE that shows dynamic content on top of everything else..
RJCTK.Utils.__wch_id = 0;    /**< [number, static] used to create ID-s for the WCH objects */

/**
 * Create an WCH object.  This function does nothing if the browser is not
 * IE5.5 or IE6.0.  A WCH object is one of the most bizarre tricks to avoid a
 * notorious IE bug: IE normally shows "windowed controls" on top of any HTML
 * elements, regardless of any z-index that might be specified in CSS.  This
 * technique is described at: http://www.aplus.co.yu/WCH/
 *
 * A "WCH object" is actually an HTMLIFrame element having a certain "CSS
 * filter" (proprietary MSIE extension) that forces opacity zero.  This object,
 * displayed on top of a windowed control such as a select box, will completely
 * hide the select box, allowing us to place other HTMLElement objects above.
 *
 * WCH stands for "Windowed Controls Hider".
 *
 * @param element [HTMLElement, optional] -- Create the WCH IFRAME inside this.
 *
 *
 * @return [HTMLIFrame or null] a new WCH object if the browser is "supported", null otherwise.
 */
RJCTK.Utils.createWCH = function(element) {
    var f = null;
    element = element || window.self.document.body;
    if (RJCTK.is_ie && !RJCTK.is_ie5) {
        var filter = 'filter:progid:DXImageTransform.Microsoft.alpha(style=0,opacity=0);';
        var id = "WCH" + (++RJCTK.Utils.__wch_id);
        element.insertAdjacentHTML
            ('beforeEnd', '<iframe id="' + id + '" scroll="no" frameborder="0" ' +
             'style="z-index:0;position:absolute;visibility:hidden;' + filter +
             'border:0;top:0;left:0;width:0;height:0;" ' +
             'src="javascript:false;"></iframe>');
        f = window.self.document.getElementById(id);
    };
    return f;
};
RJCTK.Utils.setupWCH_el = function(f, el, el2) {
    if (f) {
        var pos = RJCTK.Utils.getAbsolutePos(el),
            X1 = pos.x,
            Y1 = pos.y,
            X2 = X1 + el.offsetWidth,
            Y2 = Y1 + el.offsetHeight;
        if (el2) {
            var p2 = RJCTK.Utils.getAbsolutePos(el2),
                XX1 = p2.x,
                YY1 = p2.y,
                XX2 = XX1 + el2.offsetWidth,
                YY2 = YY1 + el2.offsetHeight;
            if (X1 > XX1)
                X1 = XX1;
            if (Y1 > YY1)
                Y1 = YY1;
            if (X2 < XX2)
                X2 = XX2;
            if (Y2 < YY2)
                Y2 = YY2;
        };
        RJCTK.Utils.setupWCH(f, X1, Y1, X2-X1, Y2-Y1);
    };
};

/**
 * Configure a WCH object to cover a certain part of the screen.
 *
 * @param f [HTMLIFrame] the WCH object.
 * @param x [number] the X coordinate.
 * @param y [number] the Y coordinate.
 * @param w [number] the width of the area.
 * @param h [number] the height of the area.
 */
RJCTK.Utils.setupWCH = function(f, x, y, w, h) {
    if (f) {
        var s = f.style;
        (typeof x != "undefined") && (s.left = x + "px");
        (typeof y != "undefined") && (s.top = y + "px");
        (typeof w != "undefined") && (s.width = w + "px");
        (typeof h != "undefined") && (s.height = h + "px");
        s.visibility = "inherit";
    };
};

//Animation management************************************************************************************************

RJCTK.Utils.an_AnimElement=null;    //list of tweens we need to animate one way or another
RJCTK.Utils.an_HasAnims= false;
RJCTK.Utils.an_CallbackSemaphore=false;
//RJCTK.Utils.an_tweenStepW = [0.55,1.09,1.62,2.13,2.62,3.08,3.51,3.89,4.24,4.54,4.79,4.98,5.13,5.21,5.24,5.21,5.13,4.98,4.79,4.54,3.89,3.51,3.08,2.62,2.13,1.62,1.09,0.55];
//RJCTK.Utils.an_tweenStepH = [1.23,2.43,3.57,4.63,5.57,6.37,7.01,7.48,7.77,7.87,7.77,7.48,7.01,6.37,5.57,4.63,3.57,2.43,1.23,0,0,0,0,0,0,0,0,0,0];
RJCTK.Utils.an_tweenStepW = [30,30,15,10,5,4,3,2,1];
RJCTK.Utils.Tween = function (element,StartFrom,EndTo,timestep)
{
    this.element    = element;
    this.StartFrom  = StartFrom;
    this.EndTo      = EndTo;   
    
    this.TimeStep   = timestep;
    this.TimeCounter = 0;
    
    this.tweenHeight = [];    
    this.tweenFrame = 0;
    this.tweenDone = 0;
 
};

RJCTK.Utils.Tween.prototype.refresh = function()
{
    this.TimeCounter++;
    if (this.TimeCounter==this.TimeStep)
    {
        this.tweenFrame++;
        this.TimeCounter=0;    
        if (this.tweenFrame==RJCTK.Utils.an_tweenStepW.length)
        {   
            this.tweenFrame = 0;
            this.tweenDone = 1;
        }else 
        {    
            this.element.style.height =this.tweenHeight[this.tweenFrame] +"px";
            if (this.tweenHeight[this.tweenFrame]==0)
                   this.element.style.display="none";
                 
        };
    };
};

RJCTK.Utils.Tween.prototype.createTween = function()
{
    var tmpH    = this.StartFrom;
    var hDiff   = this.EndTo - this.StartFrom;
    
    for (var i=0; i<RJCTK.Utils.an_tweenStepW.length; i++) {
        tmpH += hDiff*RJCTK.Utils.an_tweenStepW[i]*0.01;
        this.tweenHeight[i] = tmpH;      
    };
    var j=RJCTK.Utils.an_tweenStepW.length-1;
      this.tweenHeight[j] = this.EndTo;

    
};
RJCTK.Utils.AnimateCallback=function()
{
    //while (RJCTK.Utils.an_CallbackSemaphore);
    RJCTK.Utils.an_CallbackSemaphore=true;
    RJCTK.Utils.an_HasAnims=false;
   
           RJCTK.Utils.an_AnimElement.refresh();
           if (RJCTK.Utils.an_AnimElement.tweenDone == 1)
                {   
                RJCTK.Utils.an_AnimElement.element.style.height="";
                  //  alert(RJCTK.Utils.an_AnimElements[i].tweenHeight);
                // RJCTK.Utils.an_AnimElements.splice(i,1);
                RJCTK.Utils.an_AnimElement=null;
                
                }
           else 
                    RJCTK.Utils.an_HasAnims=true;

    if (RJCTK.Utils.an_HasAnims)
        setTimeout("RJCTK.Utils.AnimateCallback()",1);
    RJCTK.Utils.an_CallbackSemaphore=false;
};

RJCTK.Utils.StartTweenHeight = function (element,StartFrom,EndTo,timestep)
{
   // while (RJCTK.Utils.an_CallbackSemaphore);

   if (RJCTK.Utils.an_AnimElement!=null) return false;

  
     RJCTK.Utils.an_AnimElement= new RJCTK.Utils.Tween(element,StartFrom,EndTo,timestep);
     RJCTK.Utils.an_AnimElement.createTween();
    if (RJCTK.Utils.an_HasAnims==false)
    { RJCTK.Utils.an_HasAnims=true;
      setTimeout("RJCTK.Utils.AnimateCallback()",1);
    };
  return true;
};

// Menu events and calls ************************************************************************************************
RJCTK.Utils.HideMenu = function(elementid,cssclass)
{
 var element = document.getElementById(elementid);
 if (element.className == cssclass)
 {
    element.className= cssclass + "hide";
    setTimeout('document.getElementById("'+elementid+'").className="hide";',125);
    return "hide";
 } else 
 {
    element.className= cssclass + "hide";
    setTimeout('document.getElementById("'+elementid+'").className="'+cssclass+'";',125);
    return "show";
 };

};
RJCTK.Utils.OnHideMenuClick = function()
{
 RJCTK.Utils.HideMenu('mainmenu','menutable');
 
 RJCTK.Utils.writeCookie('menustatus', RJCTK.Utils.HideMenu('toolbar','toolbartable'),15);
 RJCTK.Utils.HideMenu('toolbarver','toolbartable');
 RJCTK.Utils.HideMenu('tool_top','toolbartable');
 
 return false;
};

RJCTK.Utils.OnAutoPollClick = function()
{

    RJCTK.Utils.SendAHAH('ClientCom.aspx?action=setpoll',
            function (response)
            {
                    var element = document.getElementById('autopoll'); //shoudn't this turn the polling on off too ? we are still running polls you know
                    var elementv = document.getElementById('autopollv');
                    if (response == "Pause:On")
                    {
                            element.src ="skin/nopoll.gif";
                            elementv.src ="skin/nopoll.gif";
                            element = document.getElementById('autoanswer'); //shoudn't this turn the polling on off too ? we are still running polls you know
                            elementv = document.getElementById('autoanswerv');
                            element.src ="skin/autoanswoff.gif";              
                            elementv.src ="skin/autoanswoff.gif";
                    }
                     else 
                     {
                            element.src ="skin/pollon.gif";              
                            elementv.src ="skin/pollon.gif";
                     }
            }
   );
return false;
};

RJCTK.Utils.OnAutoAnswerClick = function()
{
 RJCTK.Utils.SendAHAH('ClientCom.aspx?action=autoanswer',
            function (response)
            {
                  var element = document.getElementById('autoanswer'); //shoudn't this turn the polling on off too ? we are still running polls you know
                    var elementv = document.getElementById('autoanswerv');
                    if (response == "AutoAnswer:On")
                    {
                            element.src ="skin/autoanswer.gif";
                            elementv.src ="skin/autoanswer.gif";
                    }
                     else 
                     {
                            element.src ="skin/autoanswoff.gif";              
                            elementv.src ="skin/autoanswoff.gif";
                     }         
            }
   );
return false;
}

//************************************************************************************************
// Page Timer Section************************************************************************************************

var TimerStart;
var TimerReferenceTime;
var TimerElement;
var TimerStartFromSeconds;
RJCTK.Utils.StartTimer = function(element,startFromSeconds)
{
TimerReferenceTime=new Date();
TimerStart=true;
TimerElement=element;
TimerStartFromSeconds = startFromSeconds;
setTimeout("RJCTK.Utils.UpdateTimer()",1000);


};
RJCTK.Utils.UpdateTimer= function()
{
var TimeNow= new Date();
var TimeDiference = (TimeNow.getTime()- TimerReferenceTime.getTime() )/1000 + TimerStartFromSeconds;
var Minutes = Math.floor(TimeDiference/60);
var Seconds = Math.floor(TimeDiference- Minutes * 60);
TimerElement.innerHTML = Minutes + ":"+Seconds;
if (TimerStart)
    setTimeout("RJCTK.Utils.UpdateTimer()",1000);   
};
RJCTK.Utils.StopTimer= function()
{
TimerStart=false;
};
 
 
 RJCTK.Utils.GetDOMParser = function (text)
 {
     if (window.ActiveXObject)
    {
        var doc=new ActiveXObject("Microsoft.XMLDOM");
        doc.async="false";
        doc.loadXML(text);
      }
    // code for Mozilla, Firefox, Opera, etc.
    else
    {
        var parser=new DOMParser();
        var doc=parser.parseFromString(text,"text/xml");
    };
    return doc.documentElement;

 };
 
//************************************************************************************************
//Maintain hidden info in postback

RJCTK.Utils.setPostbackValue = function (name,value)
{
var element = document.getElementById(name);
if (element != undefined)
    element.value = value;

};
RJCTK.Utils.getPostbackValue = function (name)
{
var element = document.getElementById(name);
if (element != undefined)
{
    return  element.value;
 };
    
return null;
};

//************************************************************************************************
// Tabs Section************************************************************************************************

RJCTK.Utils.Test=function()
{
           var objDiv = document.getElementById("scheduler");
           objDiv.scrollTop = 50;
           alert(objDiv.scrollHeight);
           alert("aaaaaa");
};

var panes = new Array();

RJCTK.Utils.setupPanes=function(containerId, defaultTabId) {
  // go through the DOM, find each tab-container
  // set up the panes array with named panes
  // find the max height, set tab-panes to that height  
  panes[containerId] = new Array();
  var maxHeight = 0; var maxWidth = 0;
  var container = document.getElementById(containerId);
  var paneContainer = container.getElementsByTagName("div")[0];
  var paneList = paneContainer.childNodes;
  for (var i=0; i < paneList.length; i++ ) {
    var pane = paneList[i];
    if (pane.nodeType != 1) continue;
    if (pane.offsetHeight > maxHeight) maxHeight = pane.offsetHeight;
    if (pane.offsetWidth  > maxWidth ) maxWidth  = pane.offsetWidth;
    panes[containerId][pane.id] = pane;
    pane.style.display = "none";
  }; 
   
    paneContainer.style.height ="100%";
   
    var cookieTab = RJCTK.Utils.getPostbackValue(containerId+"_hv");
    if(( cookieTab ==null )||(cookieTab.length==0)||cookieTab == undefined)
        document.getElementById(defaultTabId).onclick();
    else 
        document.getElementById(cookieTab).onclick();
};

RJCTK.Utils.showPane=function(paneId, activeTab) {
  // make tab active class
  // hide other panes (siblings)
  // make pane visible
  
    for (var con in panes) {
    activeTab.blur();
    activeTab.className = "selected";
    if (panes[con][paneId] != null) { // tab and pane are members of this container
      var pane = document.getElementById(paneId);
      pane.style.display = "block";
      var container = document.getElementById(con);
      var tabs = container.getElementsByTagName("ul")[0];
      var tabList = tabs.getElementsByTagName("a");
      for (var i=0; i<tabList.length; i++ ) {
        var tab = tabList[i];
        if (tab != activeTab) tab.className = "";
      };
      RJCTK.Utils.setPostbackValue(con+"_hv",activeTab.id);            
      for (var i in panes[con]) {
        var pane = panes[con][i];
        if (pane == undefined) continue;
        if (pane.id == paneId) continue;
        pane.style.display = "none";
      };
    };
  };
  return false;    
};
//go to a specific tab based on wether elementID has any content text or not
RJCTK.Utils.showPaneFromTextboxValue =function (paneID,elementID,tabOnContent,tabOnEmpty,activeTab)
{
    var element = document.getElementById(elementID);
    if ((element)&& (element.value.length>0))
        RJCTK.Utils.showPane(paneID + tabOnContent,activeTab);
    else            
        RJCTK.Utils.showPane(paneID + tabOnEmpty,activeTab);
};

RJCTK.Utils.showPaneFromCheckboxValue =function (paneID,elementID,tabOnContent,tabOnEmpty,activeTab)
{
    var element = document.getElementById(elementID);
    if ((element)&& (element.checked == true))
        RJCTK.Utils.showPane(paneID + tabOnContent,activeTab);
    else            
        RJCTK.Utils.showPane(paneID + tabOnEmpty,activeTab);
};

RJCTK.Utils.showPaneFromListValue =function (paneID,elementID,valuesList,activeTab)
{    
    var element = document.getElementById(elementID);
    
     for ( var prop in valuesList)
     {
         if (element.value == prop)
         {
            RJCTK.Utils.showPane(paneID + valuesList[prop],activeTab);
            return;
          };
     };
        
     RJCTK.Utils.showPane(paneID + valuesList[0],activeTab);
};
// Web Form fill values from postback at client... kinda ugly, but it's very fast************************************************************************************************
RJCTK.Utils.SetCntValues= function (PostBackFormValues,PostBackControlTypes)
{
var i;
 var element; 
for (i=0;i<PostBackFormValues.length;i++)    
    {
     switch (PostBackControlTypes[i])
     {    
            case 5: //empty
                    break;
            case 1://text box
                element = document.getElementById('WebFormCnt'+(i+1));
                //alert('WebFormCnt'+i);
                element.value=PostBackFormValues[i];
                break;
            case 2://Drop down
                element = document.getElementById('WebFormCnt'+(i+1));
                element.value=PostBackFormValues[i];
                break;
            case 3://checkbox
                element = document.getElementById('WebFormCnt'+(i+1));
                if (PostBackFormValues[i]==1)
                    element.checked=true;   
                 else 
                    element.checked=false;   
                break;
            case 4: //options list
                element = document.getElementById('WebFormCnt'+(i+1));
                element.value=PostBackFormValues[i];
                
                //RJCTK.Utils.SetCntBindOptionList('WebFormCnt'+(i+1));
                break;
     }; //end switch
    };//end for 
};
//init the option list
RJCTK.Utils.SetCntBindOptionList = function(elementID)
{

var elementHidden; 
var element;
var i=0;
elementHidden = document.getElementById(elementID);
element =document.getElementById(elementID+"$cb$"+i);
//alert(elementHidden.value);
while (element !=null)
{    
    
    if (elementHidden.value.indexOf(element.value)>=0)
            element.checked=true;   
    else 
            element.checked=false;   
   // element.onClick = function(){ RJCTK.Utils.SetCntBindBackOptionList(elementID);};
    i++;
    element =document.getElementById(elementID+"$cb$"+i);
};
elementHidden.value = "";
};

//populate the main control from the individual checkboxes
RJCTK.Utils.SetCntBindBackOptionList = function(elementID)
{
var elementHidden; 
var element;
var result;
alert('bind back');
elementHidden = document.getElementById(elementID);
var i=0;
element = document.getElementById(elementID+"$cb$"+i);
while (element !=null)
{
if (element.checked)
{
    if (result.length>0)
        result = result +";";
    result = result + element.value;    
};
i=i+1;
element = document.getElementById(elementID+"$cb$"+i);
};
elementHidden.value = result;
};
// ************************************** Build the help window**********************************************************************************************************************************************************
var HelpElement= null;
RJCTK.Utils.BuildHelpWindow = function (HelpHTML)
{    
   if (HelpElement != null) return;
   HelpElement =  RJCTK.Utils.createElement("div",document.body);         
   HelpElement.id = "HelpWin";    
   RJCTK.Utils.addClass(HelpElement,"HelpWin");   
   
   var HelpTitle =  RJCTK.Utils.createElement("div",HelpElement); 
   RJCTK.Utils.addClass(HelpTitle,"HelpWinTitle");
   RJCTK.Utils.addEvent(HelpTitle,"mousedown",RJCTK.Utils.MoveHelpWindow);      
   var HelpCloseLink = RJCTK.Utils.createElement("a",HelpTitle); 
   HelpCloseLink.href="";
   RJCTK.Utils.addEvent(HelpCloseLink,"click",function(){RJCTK.Utils.CloseHelpWindow();return false;});   
   var HelpCloseImg = RJCTK.Utils.createElement("img",HelpCloseLink); 
   HelpCloseImg.src = "skin/help.png";
   RJCTK.Utils.addClass(HelpCloseImg,"HelpWinImg");
   var HelpTitleText= RJCTK.Utils.createElement("span",HelpTitle); 
   HelpTitleText.innerHTML="Help";
   var HelpContent = RJCTK.Utils.createElement("div",HelpElement); 
   RJCTK.Utils.addClass(HelpContent,"HelpWinContent");
   HelpContent.innerHTML = HelpHTML;      
   
};
RJCTK.Utils.CloseHelpWindow = function ()
{
    HelpElement.style.display='none';
    HelpElement.innerHTML="";
    HelpElement= null;
};
RJCTK.Utils.MoveHelpWindow = function (ev)
{      
//if (HelpElement!=null)
  //RJCTK.DragDrop.DragDrop(ev,HelpElement);
        
};
//region infobar **************************************************************************************************
RJCTK.Utils.ShowInfoBar = function(type,msg,timeout)
{
var infob=document.getElementById('infobar');
if (!infob) return;
infob.className = "";
RJCTK.Utils.addClass(infob,type);       
//RJCTK.Utils.addClass(infob,"infobar_ok");       
infob.style.display="block";    
infob.innerHTML = msg;      
if (type!="infobar_ok")
{
    document.getElementById("soundeffect").loop="1";
    document.getElementById("soundeffect").src=""; //reset first in case of problems
    document.getElementById("soundeffect").src="skin/infobar.wav";
    
};
setTimeout("RJCTK.Utils.HideInfoBar()",timeout);
};

RJCTK.Utils.HideInfoBar = function(type,msg)
{

    var infob=document.getElementById('infobar');
    if (infob)
    {    
        infob.style.display="none";
    };
};
RJCTK.Utils.PlayRingtone = function()
{
    document.getElementById("soundeffect").loop="-1";
    document.getElementById("soundeffect").src=""; //reset first in case of problems
    document.getElementById("soundeffect").src="skin/ring.wav";
};
RJCTK.Utils.StopRingtone = function()
{
    document.getElementById("soundeffect").src=""; //reset first in case of problems    
};
// Browser sniffing************************************************************************************************

/// detect Opera browser
RJCTK.is_opera = /opera/i.test(navigator.userAgent);

/// detect a special case of "web browser"
RJCTK.is_ie = ( /msie/i.test(navigator.userAgent) && !RJCTK.is_opera );

/// detect IE5.0/Win
RJCTK.is_ie5 = ( RJCTK.is_ie && /msie 5\.0/i.test(navigator.userAgent) );

/// detect IE for Macintosh
RJCTK.is_mac_ie = ( /msie.*mac/i.test(navigator.userAgent) && !RJCTK.is_opera );

/// detect KHTML-based browsers
RJCTK.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

/// detect Konqueror
RJCTK.is_konqueror = /Konqueror/i.test(navigator.userAgent);

/// detect Gecko
RJCTK.is_gecko = /Gecko/i.test(navigator.userAgent);


