
if (!this.JSON) { this.JSON = {};}

(function () { 

    function f(n) { return n < 10 ? '0' + n : n;}
	
    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf()) ?
                   this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z' : null;
        };

        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }
	
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(szString)
    {
        escapable.lastIndex = 0;
        return escapable.test(szString) ? '"' + szString.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' : '"' + szString + '"';
    }
	
    function str(key, holder)
    {
        var i,
            k, 
            v,
            length,
            partial,
            value = holder[key];

        if (value && typeof value === 'object' && typeof value.toJSON === 'function')
            value = value.toJSON(key);
        
        switch (typeof value)
        {
        case 'string':
            return quote(value);
        case 'number':
            return isFinite(value) ? String(value) : 'null';
        case 'boolean':
        case 'null':
            return String(value);
        case 'object':
            if (!value)
                return 'null';
            
            partial = [];

            if (Object.prototype.toString.apply(value) === '[object Array]')
            {
                length = value.length;
                for (i = 0; i < length; i += 1)
                {
                    partial[i] = str(i, value) || 'null';
                }
                v = partial.length === 0 ? '[]' : '[' + partial.join(',') + ']';
                return v;
            }

            for (k in value)
            {
                if (Object.hasOwnProperty.call(value, k))
                {
                    v = str(k, value);
                    if (v)
                    	partial.push(quote(k) + ':' + v);
                }
            }
            
            v = partial.length === 0 ? '{}' : '{' + partial.join(',') + '}';
            return v;
        }
    }

    if (typeof JSON.stringify !== 'function')
    {
        JSON.stringify = function (jJSON) 
        {
			return str('', {'': jJSON});
        };
    }
	
    if (typeof JSON.parse !== 'function')
    {
        JSON.parse = function (szJSON)
        {
            var jJSON;

            cx.lastIndex = 0;
            if (cx.test(szJSON))
            {
                szJSON = szJSON.replace(cx, function (a)
                {
                    return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

            if (/^[\],:{}\s]*$/.test(szJSON.
            		replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
					replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
					replace(/(?:^|:|,)(?:\s*\[)+/g, '')))
			{
                jJSON = eval('(' + szJSON + ')');
                return jJSON;
            }
            throw new SyntaxError('JSON.parse');
        };
    }
}());



function $(szSelector,oParent)
{
	if (oParent === undefined ) oParent = document;
	
	// ------------------------------------------------------------------------------------------------
	// Id
	if(/^#/.test(szSelector) && !/\s/.test(szSelector) && !/\./.test(szSelector)) // Id
	{
		return oParent.getElementById(szSelector.replace(/#/,''));
	}
	// ------------------------------------------------------------------------------------------------
	// Form
	else if(/^\[/.test(szSelector) && !/\s/.test(szSelector))
	{
		if (/\./.test(szSelector))
		{
			// ----------------------------------------------------------------------------------------
			// Get the context form
			var oForm 	= $(szSelector.split(/\./)[0],oParent);
			if (oForm === undefined || oForm == document) return [];
			
			// ----------------------------------------------------------------------------------------
			// Look into the form for the right item
			var tElements 	= [], szItem = szSelector.split(/\./)[1], oElement = null;
			for (var i=0,n=oForm.elements.length;i<n;i++)
			if (oForm.elements[i].name == szItem)
			{
				tElements.push(oForm.elements[i]);
			}
			if (tElements.length == 0)	return [];
			return tElements;
		}
		else
		{
			
			
			// ----------------------------------------------------------------------------------------
			// Find the form
			var szItem 	= szSelector.replace('[','').replace(']',''), oElement = undefined;
			for (var i=0,n=oParent.forms.length;i<n;i++)
			if (oParent.forms[i].name == szItem)
			{
				oElement = oParent.forms[i];
				break;
			}
			return oElement;
		}
	}
	// ------------------------------------------------------------------------------------------------
	// Tag or class, if there is a sub selection then go deeper
	else if (/\s/.test(szSelector))
	{
		// --------------------------------------------------------------------------------------------
		// Browse parents
		var tElements	 	= [];
		var tSelector		= szSelector.split(/\s/);
		var szSubSelector 	= szSelector.substr(tSelector[0].length + 1);
		var tParents	 	= $(tSelector[0],oParent);
		if (!Object.isArray(tParents))
			tParents = [tParents];
		
		for(var i=0,n=tParents.length;i<n;i++)
		{
			var tRes = $(szSubSelector,tParents[i]);
			if (tRes != undefined)
			for(j=0,nn=tRes.length;j<nn;j++)
				tElements.push(tRes[j]);
		}
		if (tElements.length == 0)	return [];
		return tElements;
	}
	// ------------------------------------------------------------------------------------------------
	// Class
	else if(/\./.test(szSelector))
	{
		var szTagName 	= (/^\./.test(szSelector))? "*" : szSelector.split(/\./)[0]; 
		var szClasses	= (/^\./.test(szSelector))? szSelector.replace(/\./,'') : szSelector.substr(szTagName.length +1);
		var tClasses	= szClasses.split(/\./);
		
		// --------------------------------------------------------------------------------------------
		// Browse all tags
		var tElements = [], tTags = oParent.getElementsByTagName(szTagName), oReturn = null;
		for (i=0,n=tTags.length;i<n; i++)
		{
			// Verify each classes
			bFound = false;
			for(j=0,nn=tClasses.length; j<nn; j++)
			{
				bFound = true;
				if(!RegExp("(^|\\s|\\.)" + tClasses[j] + "(\\s|\\.|$)","i").test(tTags[i].className))
				{
					bFound = false;
					break;
				}
			}
			if (bFound)
				tElements.push(tTags[i]);	
		}
		if (tElements.length == 0)	return [];
		return tElements;
	}
	// ------------------------------------------------------------------------------------------------
	// Tag
	else
	{
		// --------------------------------------------------------------------------------------------
		// Browse all tags
		var tElements = [], tTags = oParent.getElementsByTagName(szSelector), oReturn = null;
		for (i=0,n=tTags.length;i<n; i++)
		{
			tElements.push(tTags[i]);
		}
		if (tElements.length == 0)	return [];
		return tElements;
	}
}



var ct = {
	version: '2.0',
	
	browser: (function()
	{
		var ua 			= navigator.userAgent;
		var isOpera 	= Object.prototype.toString.call(window.opera) == '[object Opera]';
		var isWebKit	= /WebKit/.test(ua);
		var isIE		= !isWebKit && !isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName);
		
		return {
			WebKit:			(isWebKit),
			OldWebKit: 		(isWebKit && !window.getSelection().getRangeAt),
			IE: 			(!isWebKit && !isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(navigator.appName)),
			IE6: 			(isIE && /MSIE [56]/.test(ua)),
			Gecko: 			(!isWebKit && /Gecko/.test(ua)),
			Mac: 			(ua.indexOf('Mac') != -1),
			MobileSafari:   (/Apple.*Mobile.*Safari/.test(ua))
		}
	})(),
	
	preload : (function()
	{
		// Object
		var _toString = Object.prototype.toString;
		function extend(destination, source)
		{
			for (var property in source)
				destination[property] = source[property];
			return destination;
		}
		
		
		function getFirstChildByTagName(object,szTagName)
		{
			for(var i=0,n=object.childNodes.length;i<n;i++)
			if (object.childNodes[i].tagName == szTagName)
				return object.childNodes[i];
			return undefined;
		}
		
		function getChildsByTagName(object,szTagName)
		{
			var tRes = Array();
			for(var i=0,n=object.childNodes.length;i<n;i++)
			if (object.childNodes[i].tagName == szTagName)
				tRes.push(object.childNodes[i]);
			return tRes;
		}
		
		function isElement(object)	{return !!(object && object.nodeType == 1);}
		function isArray(object)	{return _toString.call(object) == "[object Array]";}
		function isFunction(object) {return typeof object === "function";}
		function isString(object) 	{return _toString.call(object) == "[object String]";}
		function isNumber(object) 	{return (_toString.call(object) == "[object Number]" && object.toString() != 'NaN');}
		function isUndefined(object){return typeof object === "undefined";}
		function isEmpty(object)	{return (typeof object === "undefined" || object == "");}
		
		// CLEAN OBJECT FROM MEMORY
		function clean(object)
		{
			if (!object) return;
			
			// TINYMCE : Textarea
			if (typeof(tinyMCE) != "undefined")
			if (object.tagName == 'DIV')
			{
				var tTextarea = object.getElementsByTagName('textarea');
				if (tTextarea.length > 0)
				{
					for(i=0;i<tTextarea.length;i++)
					if (tTextarea[i].getAttribute('x-type') == 'wysiwyg')
					{
						tinyMCE.execCommand('mceRemoveControl', false, tTextarea[i].getAttribute('id'));
						Object.clean(tTextarea[i]);
					}
				}
			}
			// Clean attributes
		    var a = object.attributes, i, l, n;
		    if (a)
		    {
		    	l = a.length;
		        for (i = 0; i < l; i += 1)
		        {
		        	try
					{
		            	n = a[i].name;
		            	if (typeof object[n] === 'function')
		               		object[n] = null;
		            
		            }catch(e){}
		        }
		    }
		    
		    // Clean child nodes
		    a = object.childNodes;
		    if (a)
		    {
		    	while (object.childNodes.length > 0)
		        {
		            Object.clean(object.childNodes[0]);
		            object.removeChild(object.childNodes[0]);
		        }
		    }
		}
		function clone(object)		{return extend({ }, object);}
		/*
		function ct_object_Clone(o)
		{
			if(typeof(o) != 'object') return o;
			if(o == null)
				return o;
			var newO = new Object();
			for(var i in o) newO[i] = ct_object_Clone(o[i]);
				return newO;
		}*/


		function forEach(tArray,fnDelegate,ownpropertiesonly)
		{
			if (typeof(fnDelegate) == "function")
			{
				if (this instanceof Array && typeof(ownpropertiesonly) == "undefined")
					ownpropertiesonly = true;
				
				for (key in tArray)
				{
					var ok = (!ownpropertiesonly);
					if (!ok)
					{
						try{ok = tArray.hasOwnProperty(key);}catch(ex){}
					}
					
					if (ok)
					{
						try{ fnDelegate(tArray[key],key,tArray);}catch(ex){}
					}
				}
			}
		}
		
		
		function map(tArray,fnIterator)
		{
			var tResult = [];
			if (typeof fnIterator != "function")
				throw new TypeError();
			
			for(var i=0,n=tArray.length;i<n;i++)
				tResult[i] = fnIterator.call(arguments[1], tArray[i],i,tArray)
			return tResult;
		}
			
		extend(Object, {
			extend:        extend,
			getChildsByTagName: getChildsByTagName,
			getFirstChildByTagName: getFirstChildByTagName,
			clone:         clone,
			clean:         clean,
			isElement:     isElement,
			isArray:       isArray,
			isFunction:    isFunction,
			isString:      isString,
			isNumber:      isNumber,
			isUndefined:   isUndefined,
			isEmpty:       isEmpty,
			forEach:       forEach,
			map:           map
		});
		
		// Functions
		Object.extend(Function.prototype, (function()
		{
			var _slice = Array.prototype.slice;
			
			function update(array, args)
			{
				var arrayLength = array.length, length = args.length;
				while (length--) array[arrayLength + length] = args[length];
				return array;
			}
			
			function merge(array, args)
			{
				array = _slice.call(array, 0);
				return update(array, args);
			}
			
			function bind(context)
			{
				if (Object.isUndefined(arguments[0])) return this;
				var _fnMethod = this; //, _tArgs = _slice.call(arguments, 1);
				
				return function()
				{
					//var a = merge(_tArgs, arguments);
      				//return _fnMethod.apply(context, a);
      				return _fnMethod.apply(context, arguments);
				}
			}
			
			return {
				bind:bind
			}
		})());
		
		// String
		Object.extend(String.prototype,(function()
		{
			function extractTags(tag)
			{
			    var matchAll = new RegExp('(?:<' + tag + '.*?>)((\n|\r|.)*?)(?:<\/' + tag + '>)','img');
			    var matchOne = new RegExp('(?:<' + tag + '.*?>)((\n|\r|.)*?)(?:<\/' + tag + '>)','im');
			    var tMatched = (this.match(matchAll) || []);
			    return Object.map(tMatched,function(scriptTag){	return (scriptTag.match(matchOne) || ['', ''])[1];});
			}
			
			function urlencode()
			{
				var szStr = escape(this);
				return szStr.replace(/[*+\/@&,=\s]/g,function (s)
				{
					switch (s)
					{
						case " ": s = "%20"; break;
						case "*": s = "%2A"; break;
						case "+": s = "%2B"; break;
						case ",": s = "%2C"; break;
						case "/": s = "%2F"; break;
						case "=": s = "%3D"; break;
						case "@": s = "%40"; break;
						case "&": s = "%26"; break;
					}
					return s;
				});
			}
			
			return {
				extractTags:	extractTags,
				urlencode:		urlencode
			}
		})());
		return true;
	})(),
	
	/*log: 
	{
		enable : true,
		log 	: function(szText)	{if (this._console && this.enable) this._console.log(szText);},
		info 	: function(szText)	{if (this._console && this.enable) this._console.info(szText);},
		error 	: function(szText)	{if (this._console && this.enable) this._console.error(szText);},
		warn 	: function(szText)	{if (this._console && this.enable) this._console.warn(szText);},
		_console : (console ? console : (window.console ? window.console : null))
	},*/
	
	window : 
	{
		size : 
		{
			Get : function()
			{
				var iWinW = 630, iWinH = 460;
				if (parseInt(navigator.appVersion)>3)
				{
					if (navigator.appName=="Netscape")
					{
						iWinW = window.innerWidth -16;
						iWinH = window.innerHeight -16;
					}
					if (navigator.appName.indexOf("Microsoft")!=-1)
					{
						var hDoc = $('#document');
						if (hDoc)
						{
							iWinW = hDoc.offsetWidth;
							iWinH = hDoc.offsetHeight;
						}else{
							iWinW = document.body.offsetWidth;
							iWinH = document.body.offsetHeight;
						}
					}
				}
				return {"Screen":{"Width":screen.availWidth, "Height":screen.availHeight},"Window": {"X":0, "Y":0, "Width":iWinW, "Height":iWinH}};
			},
			
			Set : function(iX,iY,iWidth,iHeight)
			{
				//if (iX != undefined)
				//	;
				window.resizeTo(iWidth,iHeight);
			}
		}

	},
	
	keyboard:
	{
		GetCharCode : function(iKeyCode)
		{
			var iAsciiCode = iKeyCode * -1;
			if (iAsciiCode > 95 && iAsciiCode < 106)
				iAsciiCode -= 48;
			return String.fromCharCode(iAsciiCode);
		},
		
		GetEvent : function(oEvent,hWindow)
		{
			var jResult = {"keyCode":0,"shift":0,"ctrl":0,"alt":0};
			if (hWindow == undefined) 	hWindow = window;
			if (!oEvent) 				oEvent = hWindow.event;
				jResult.keyCode = (oEvent.which ? oEvent.which : oEvent.keyCode);
			
			jResult.shift 	= (oEvent.shiftKey ? 1 : 0);
			jResult.ctrl	= (oEvent.ctrlKey ? 1 : 0);
			jResult.alt		= (oEvent.altKey ? 1 : 0);
			
			return jResult;
		}
	},
	
	mouse : 
	{
		GetEvent : function(oEvent,hWindow)
		{
			// --------------------------------------------------------------------------------------------
			// Variables
			var iPosX = 0,iPosY = 0, oTarget = null, oResult, iButton;
			if (!hWindow) hWindow = window;
			if (!oEvent) oEvent = hWindow.event;
			
			// --------------------------------------------------------------------------------------------
			// Get data from event data if this is a fake dispatch
			if (typeof oEvent.event_data != "undefined")
			{
				iPosX 	 = oEvent.event_data.X;
				iPosY 	 = oEvent.event_data.Y;
				iButton	 = oEvent.event_data.Button;
				oTarget	 = oEvent.event_data.Target;
			}
			else
			// --------------------------------------------------------------------------------------------
			// Compute position and get objects
			{
				// Get button
				iButton = (oEvent.which ? (oEvent.which == 3 ? 2:1): (oEvent.button== 2 ? 2:1));
				
        		// iPad / iPhone Multi-Touch
        		if (ct.browser.MobileSafari && oEvent.type.substr(0,5) == "touch")
        		{
        			if (oEvent.touches.length < 1)
        			{
        				return { 	"X":	0,
									"Y":	0,
									"Target":undefined,
									"Event": oEvent.type,
									"Button":iButton};
        			}
        			
        			var oTouch 		= oEvent.touches[0];
        			oTarget 		= oTouch.target;
        			iPosX = oTouch.pageX;
					iPosY = oTouch.pageY;
        		}
				// Get pos X and Y
				else if (oEvent.pageX || oEvent.pageY)
				{
					iPosX = oEvent.pageX;
					iPosY = oEvent.pageY;
				}
				// IE
				else if (oEvent.clientX || oEvent.clientY)
				{
					var jScroll = ct.style.GetScroll(null,hWindow);
					iPosX = oEvent.clientX + jScroll.X;
					iPosY = oEvent.clientY + jScroll.Y;
				}
				
				// Clicked
				if (!oTarget)
				if (oEvent.target)
					oTarget=oEvent.target;
				else if (oEvent.srcElement)
					oTarget=oEvent.srcElement;
				
				if (oTarget.nodeType==3) // Defeat Safari bug
					oTarget = oTarget.parentNode;
			}
			
			// --------------------------------------------------------------------------------------------
			// Result
			oResult = { "X":	iPosX,
						"Y":	iPosY,
						"Target":oTarget,
						"Event": oEvent.type,
						"Button":iButton};
			return oResult;
		}
	},
	
	event : 
	{
		Fire : function(oElem, szEvType, tParams, hWindow)
		{
			// Variables
			var oEvt;
			if (!hWindow) hWindow = window;
			
			// IE
			if (hWindow.document.createEventObject)
			{
				oEvt = hWindow.document.createEventObject();				
			}
			// W3C
			else
			{
				 switch (szEvType)
				 {
					 case "abort":
					 case "blur":
					 case "change":
					 case "error":
					 case "focus":
					 case "load":
					 case "reset":
					 case "resize":
					 case "scroll":
					 case "select":
					 case "submit":
					 case "unload":
						oEvt = document.createEvent('HTMLEvents');
						oEvt.initEvent(szEvType, true, true);
					 	break;
					 case "click":
					 case "mousedown":
					 case "mousemove":
					 case "mouseout":
					 case "mouseover":
					 case "mouseup":
					 	oEvt = document.createEvent('MouseEvents');
						oEvt.initMouseEvent(szEvType, true, true,  hWindow, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
						break;
					case "keydown":
					case "keyup":
					case "keypress":
						
						oEvt= document.createEvent("KeyboardEvent");
      					oEvt.initKeyEvent(szEvType, true, true, hWindow, false, false, false, false, 27, 0);
      					break;
				}
			}
			
			// Event data
			oEvt.event_data = tParams;
			
			if ( document.createEvent )
	            return oElem.dispatchEvent( oEvt );
	        else
	            return oElem.fireEvent("on" + szEvType, oEvt );
		},
		
		Bind : function(oElem, sEvType, parFnCallback)
		{
			var fnOldCB = oElem['on' + sEvType] = parFnCallback;
			
			if (typeof(oElem['on' + sEvType]) != "function")
				oElem['on' + sEvType] = parCallBack;
			else
			{
				oElem['on' + sEvType] = function()
				{
					var bRes = parFnCallback();
					if (!bRes) return false;
					
					return fnOldCB();
				}
			}
		},
		
		Add : function(oElem, sEvType, parFnCallback, bCapture)
		{
			if (Object.isArray(oElem))
			{
				for(var i=0;i<oElem.length;i++)
					ct.event.Add(oElem[i],sEvType,parFnCallback,bCapture);
			}
			else
			{
				return 	oElem.addEventListener? oElem.addEventListener(sEvType, parFnCallback, bCapture):
		      			oElem.attachEvent? oElem.attachEvent('on' + sEvType, parFnCallback):oElem['on' + sEvType] = parFnCallback;
		    }
		},
		
		Remove : function(oElem, sEvType, parFnCallback, bCapture)
		{
			if (Object.isArray(oElem))
			{
				for(var i=0;i<oElem.length;i++)
					ct.event.Remove(oElem[i],sEvType,parFnCallback,bCapture);
			}
			else
			{
				return 	oElem.removeEventListener? oElem.removeEventListener(sEvType, parFnCallback, bCapture):
						oElem.detachEvent? oElem.detachEvent('on' + sEvType, parFnCallback):oElem['on' + sEvType] = "";
			}
		},
		
		PreventDefault : function(oEvent)
		{
			if (oEvent.preventDefault)
				oEvent.preventDefault();
			return false;
		}

	},
	
	
	geolocation :
	{
		isEnable : function()
		{
			return (navigator.geolocation ? true:false);
		},
		
		_fnCallBackFuncOK : undefined,
		_fnCallBackFuncERR : undefined,
		_fnCallBackParams : undefined,
		
		Locate : function(fnCallBackFuncOK,fnCallBackFuncERR,fnCallBackParams)
		{
			if (!this.isEnable())
			{
				if (fnCallBackFuncERR)
					fnCallBackFuncERR('Browser functionality not supported',fnCallBackParams);
				return false;
			}
			
			ct.geolocation._fnCallBackFuncOK 	= fnCallBackFuncOK;
			ct.geolocation._fnCallBackFuncERR = fnCallBackFuncERR;
			ct.geolocation._fnCallBackParams	= fnCallBackParams;
			
			// Locate me
			navigator.geolocation.getCurrentPosition(	ct.geolocation._LocateOK,
														ct.geolocation._LocateERR);
			
			
		},
		
		_LocateERR : function(szError)
		{
			if (ct.geolocation._fnCallBackFuncERR != undefined)
			{
				ct.geolocation._fnCallBackFuncERR(szError,ct.geolocation._fnCallBackParams);
			}
		},
		
		_LocateOK : function(oPosition)
		{
			var jResponse = {
								"latitude"				:oPosition.coords.latitude,
								"longitude"				:oPosition.coords.longitude,
								"altitude"				:oPosition.coords.altitude,
								"accuracy"				:oPosition.coords.accuracy,
								"altitude-accuracy"		:oPosition.coords.altitudeAccuracy,
								"heading"				:oPosition.coords.heading,
								"speed"					:oPosition.coords.speed
							};
			
			if (ct.geolocation._fnCallBackFuncOK != undefined)
				ct.geolocation._fnCallBackFuncOK(jResponse,ct.geolocation._fnCallBackParams);
			
		}
	},
	
	flash : 
	{
		Load : function(oTarget,szId,szMovie,iWidth,iHeight,tParameters)
		{
			// Get the div target
			var szName,szValue,oFlash,oParam;
			if (!tParameters) tParameters = [];
			
			// Clean the target
			Object.clean(oTarget);
			
			// Target
			szSource = "\
<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0\" width=\"" + iWidth + "\" height=\"" + iHeight + "\">\
<param name=\"movie\" value=\"" + szMovie + "\">";
			
			// Set parameters
			for(var i=0,n=tParameters.length;i<n;i++)
			{
				szName 	= tParameters[i].name;
				szValue = tParameters[i].value;
				
				szSource += "<param name=\"" + szName + "\" value=\"" + szValue + "\">\n";
			}
			
			szSource += "\
<embed wmode=\"transparent\" quality=\"high\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" src=\"" + szMovie + "\" width=\"" + iWidth + "\" height=\"" + iHeight + "\"";
			
			// Set parameters
			for(var i=0,n=tParameters.length;i<n;i++)
			{
				szName 	= tParameters[i].name;
				szValue = tParameters[i].value;
				
				szSource += szName + "=\"" + szValue + "\" ";
			}
			szSource += "></embed>\
</object>";
			
			oTarget.innerHTML = szSource;
			
			
			/*
			// Create flash object
			oFlash 	= document.createElement((ct.browser.IE || ct.browser.Gecko || 1 ? "embed" : "object"));
			
			// Add the flash into the target
			oTarget.appendChild(oFlash);
			
			if (!ct.browser.IE && !ct.browser.Gecko || 1)
			{
				oFlash.setAttribute("codebase"	,"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0");
				oFlash.setAttribute("classid"	,"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000");
			}
			
			// Set default values
			oFlash.setAttribute("name"		,szId);
			oFlash.setAttribute("width"		,iWidth);
			oFlash.setAttribute("height"	,iHeight);
			oFlash.setAttribute("type"		,"application/x-shockwave-flash");
			
			// Add movie into the Parameters
			tParameters.unshift({"name":"movie","value":szMovie});
			
			// Apply values
			for(var i=0,n=tParameters.length;i<n;i++)
			{
				szName 	= tParameters[i].name;
				szValue = tParameters[i].value;
				
				if (szName == "movie") szName = "src";
				oFlash.setAttribute(szName,szValue);
				
				// EMBED
				if ((ct.browser.IE || ct.browser.Gecko) && 0)
				{
					if (szName == "movie") szName = "src";
					
					oFlash.setAttribute(szName,szValue);
				}
				// OBJECT
				else
				{
					oParam	= document.createElement("param");
					oParam.setAttribute("name",szName);
					oParam.setAttribute("value",szValue);
					oFlash.appendChild(oParam);
				}
			}
			*/
		}
	},
	
	menu : 
	{
		_menu : {
				"Button":null,
			 	"Parent":null,
			 	"Menu":null,
			 	"Perimeter":{"X1":0,"Y1":0,"X2":0,"Y2":0,"X3":0,"Y3":0}
			 },
		
		Show : function(oEvent, oMenu,bAnimate,hWindow)
		{
			// -----------------------------------------------------------------------------------------
			if (bAnimate == undefined)	bAnimate= true;
			if (hWindow == undefined) 	hWindow = window;
			jMouseEvent = ct.mouse.GetEvent(oEvent,hWindow);
			
			if (jMouseEvent.Target.tagName == "A")
				jMouseEvent.Target = jMouseEvent.Target.firstChild;
			
			this.ShowXY(jMouseEvent.Target,{"X":0,"Y":0},oMenu,bAnimate, hWindow);
		},
		
		ShowXY : function(oTarget,jOffset, oMenu,bAnimate, hWindow)
		{
			
			// -----------------------------------------------------------------------------------------
			var iX,iY;
			if (bAnimate == undefined)	bAnimate= true;
			if (hWindow == undefined) 	hWindow = window;
			var hDocument 		= hWindow.document;
			var oWindowMenu 	= $('div.ct_menu')[0];
			
			if (this._menu.Menu == oMenu) return;
			if (!oMenu) return;
			
			// -----------------------------------------------------------------------------------------
			// Get window scroll and offset
			var jWindowSize 	= ct.window.size.Get();
			var jWindowOffset 	= {"X":0,"Y":0};
			var jWindowScroll 	= {"X":0,"Y":0};
			if (hWindow != window)
			{
				tIFrames = $('IFRAME');
				for(i=0;i<tIFrames.length;i++)
				{
					if (tIFrames[i].contentWindow == hWindow)
					{
						//jWindowScroll = ct.style.GetScroll(undefined,hWindow);
						jWindowOffset = ct.style.GetOffset(tIFrames[i],hWindow);
						break;
					}
				}
			}
			
			// -----------------------------------------------------------------------------------------
			// Get scroll, offset and dimension
			jScroll = ct.style.GetScroll(undefined,hWindow);
			if (oTarget)
			{
				jOffset 	= ct.style.GetOffset(oTarget,hWindow);
				jDimensions = ct.style.GetDimensions(oTarget,hWindow);
			}
			else
			{
				jDimensions	= {"width":50,"height":30};
			}
			
			// -----------------------------------------------------------------------------------------
			// Move child to the old parent
			if (oWindowMenu.childNodes.length > 0)
			{
				this._menu.Menu.style.display = "none";
				
				if (this._menu.Parent != null)
					this._menu.Parent.appendChild(oWindowMenu.removeChild(this._menu.Menu));
				else
					oWindowMenu.removeChild(this._menu.Menu);
			}
			
			// Save the current button and parent
			this._menu.Parent = oMenu.parentNode;
			
			// Remove hilight
			var oDiv 	= this._menu.Parent.parentNode;
			var tLIs	= $('ul li',oDiv);
			ct.style.klass.Remove(tLIs,'hilight');
			
			// Menu LI
			var oMenuLI = $('ul li.i' + oMenu.getAttribute("x-index"),oMenu.parentNode.parentNode)[0];
			ct.style.klass.Add(oMenuLI,'hilight');
			
			// Add the menu to the window
			oMenu = oWindowMenu.appendChild(oMenu);
			oMenu.style.display 		= "block";
			oWindowMenu.style.height	= "0px";
			oWindowMenu.style.display 	= "block";
			oWindowMenu.style.zIndex 	= 140;
			
			// -----------------------------------------------------------------------------------------
			// Save the new menu object
			this._menu.Menu = oMenu;
			
			// -----------------------------------------------------------------------------------------
			// Keep the menu into the screen
			iTargetX 		= jWindowOffset.X - jWindowScroll.X + jOffset.X - jScroll.X;
			iTargetY 		= jWindowOffset.Y - jWindowScroll.Y + jOffset.Y - jScroll.Y;
			iTargetWidth 	= (oTarget ? jDimensions.width : 50);
			iTargetHeight	= (oTarget ? jDimensions.height : 30);
			
			iX = (iTargetX <= 0 ? 0: 
								(iTargetX + oMenu.offsetWidth  >= jWindowSize.Window.Width  ?  
								jWindowSize.Window.Width  - oMenu.offsetWidth : 
								iTargetX));
			
			iY = (iTargetY <= - iTargetHeight ? - iTargetHeight:
								(iTargetY + oMenu.offsetHeight >= jWindowSize.Window.Height ?  
								jWindowSize.Window.Height - oMenu.offsetHeight: 
								iTargetY));
			
			// -----------------------------------------------------------------------------------------
			// Set position
			oWindowMenu.style.left = (iX) + "px";
			oWindowMenu.style.top  = (iY + iTargetHeight) + "px";
			
			// -----------------------------------------------------------------------------------------
			// Compute the perimeters
			this._menu.Perimeter.X1 = iTargetX;
			this._menu.Perimeter.Y1 = iTargetY;
			this._menu.Perimeter.X2 = iTargetX + iTargetWidth; 		// Target width
			this._menu.Perimeter.Y2 = iTargetY + iTargetHeight;	 	// Target height
			
			this._menu.Perimeter.X3 = iX;
			this._menu.Perimeter.Y3 = iY + iTargetHeight; 			// Target height
			this._menu.Perimeter.X4 = iX + oMenu.offsetWidth;
			this._menu.Perimeter.Y4 = iY + oMenu.offsetHeight + iTargetHeight;
			
			// -----------------------------------------------------------------------------------------
			// Create animation to display the menu
			var jMenuDimensions = ct.style.GetDimensions(oMenu,hWindow);
			if (bAnimate == true && jMenuDimensions.height > 40)
			{
				ct.animations.Create('blast',0,jMenuDimensions.height,function()
				{
					var oWindowMenu 	= $('div.ct_menu')[0];
					oWindowMenu.style.height = 0 + 'px';
					return true;
				},
				function(iValue)
				{
					var oWindowMenu 	= $('div.ct_menu')[0];
					oWindowMenu.style.height = parseInt(iValue) + 'px';	
					return true;
				},
				function()
				{
					var oWindowMenu 	= $('div.ct_menu')[0];
					oWindowMenu.style.height = "auto";
					return true;
				});
				
				// Start animation
				ct.animations.Start();
			}
			else
			{
				oWindowMenu.style.height = "auto";
			}
			
		},
		
		Hide : function()
		{
			var oWindowMenu = $('div.ct_menu')[0];
			
			// If the menu is not shown
			if (this._menu.Menu == null)
				return;
			
			// Remove hilight
			var oDiv 	= this._menu.Parent.parentNode;
			var tLIs	= $('ul li',oDiv);
			ct.style.klass.Remove(tLIs,'hilight');
			
			// Hide the menu
			oWindowMenu.style.display 		= "none";
			this._menu.Menu.style.display 	= "none";
			this._menu.Parent.appendChild(this._menu.Menu);
			this._menu.Menu 				= null;
			this._menu.Parent 				= null;
		},
		
		_MouseMove : function(oEvent,hWindow)
		{
			// -----------------------------------------------------------------------------------------
			// Get mouse event
			if (!hWindow) hWindow = window;
			var jMouseEvent = ct.mouse.GetEvent(oEvent,hWindow);
			var hDocument 	= hWindow.document;
			var oTarget		= jMouseEvent.Target;
			
			// -----------------------------------------------------------------------------------------
			// If the menu is not shown
			if (this._menu.Menu == null)
				return;
			
			// -----------------------------------------------------------------------------------------
			// Get offset
			jWindowOffset = {"X":0,"Y":0};
			jWindowScroll = {"X":0,"Y":0};
			if (hWindow != window)
			{
				tIFrames = $('IFRAME');
				for(i=0;i<tIFrames.length;i++)
				{
					if (tIFrames[i].contentWindow == hWindow)
					{
						//jWindowScroll = ct.style.GetScroll(tIFrames[i],hWindow);
						jWindowOffset = ct.style.GetOffset(tIFrames[i],hWindow);
						break;
					}
				}
			}
			jScroll = ct.style.GetScroll(undefined,hWindow);
			
			// -----------------------------------------------------------------------------------------
			// Verify if the mouse is in the perimeter
			if ((
					jWindowOffset.X - jWindowScroll.X + jMouseEvent.X - jScroll.X >= this._menu.Perimeter.X1 && 
					jWindowOffset.X - jWindowScroll.X + jMouseEvent.X - jScroll.X <= this._menu.Perimeter.X2 &&
					jWindowOffset.Y - jWindowScroll.Y + jMouseEvent.Y - jScroll.Y >= this._menu.Perimeter.Y1 && 
					jWindowOffset.Y - jWindowScroll.Y + jMouseEvent.Y - jScroll.Y <= this._menu.Perimeter.Y2
				)||(	
					jWindowOffset.X - jWindowScroll.X + jMouseEvent.X - jScroll.X >= this._menu.Perimeter.X3 && 
					jWindowOffset.X - jWindowScroll.X + jMouseEvent.X - jScroll.X <= this._menu.Perimeter.X4 &&
					jWindowOffset.Y - jWindowScroll.Y + jMouseEvent.Y - jScroll.Y >= this._menu.Perimeter.Y3 && 
					jWindowOffset.Y - jWindowScroll.Y + jMouseEvent.Y - jScroll.Y <= this._menu.Perimeter.Y4
				))
			{
				// On the button or on the menu
			}else{
				// Hide the menu
				this.Hide();
			}
		}
	},
	
	tooltip : 
	{
			
		_Tooltip : null,
		_MouseMove : function(oEvent,hWindow)
		{
			// -----------------------------------------------------------------------------------------
			// Get mouse event
			if (!hWindow) hWindow = window;
			var jMouseEvent = ct.mouse.GetEvent(oEvent,hWindow);
			var hDocument 	= hWindow.document;
			var oTarget 	= jMouseEvent.Target;
			
			// ---------------------------------------------------------------------------------------------
			// Tooltip management
			if (oTarget.alt != undefined && oTarget.alt != "")
			{
				if (oTarget.getAttribute("x-alt-display") == "none")
					return;
				
				// -----------------------------------------------------------------------------------------
				// Get offset
				var jWindowSize = ct.window.size.Get();
				var jWindowOffset = {"X":0,"Y":0};
				var jWindowScroll = {"X":0,"Y":0};
				if (hWindow != window)
				{
					tIFrames = $('IFRAME');
					for(i=0;i<tIFrames.length;i++)
					{
						if (tIFrames[i].contentWindow == hWindow)
						{
							jWindowOffset = ct.style.GetOffset(tIFrames[i],hWindow);
							//jWindowScroll = ct.style.GetScroll(tIFrames[i],hWindow);
							break;
						}
					}
				}
				
				if (oTarget)
				{
					jScroll 	= ct.style.GetScroll(oTarget,hWindow);
					jOffset 	= ct.style.GetOffset(oTarget,hWindow);
					jDimensions = ct.style.GetDimensions(oTarget,hWindow);
				}
				else
				{
					jScroll 	= ct.style.GetScroll(undefined,hWindow);
					jOffset		= {"X":0,"Y":0};
					jDimensions	= {"width":50,"height":30};
				}
				oTooltip = $('div.ct_tooltip')[0];
				
				// -----------------------------------------------------------------------------------------
				// Show the tooltip
				if (this._Tooltip != oTarget)
				{
					this._Tooltip 			= oTarget;
					oTooltip.style.zIndex 	= -1;
					oTooltip.style.display 	= "block";
					oTooltip.innerHTML 		= oTarget.alt;
					oTooltip.style.zIndex 	= 60;
				}
				
				// -----------------------------------------------------------------------------------------
				// Keep the menu into the screen
				iTargetX 		= jWindowOffset.X - jWindowScroll.X + jOffset.X - jScroll.X;
				iTargetY 		= jWindowOffset.Y - jWindowScroll.Y + jOffset.Y - jScroll.Y;
				iTargetWidth 	= (oTarget ? jDimensions.width : 50);
				iTargetHeight	= (oTarget ? jDimensions.height : 30);
				
				iX = (iTargetX <= 0 ? 0: 
													(iTargetX + oTooltip.offsetWidth  >= jWindowSize.Window.Width  ?  
													jWindowSize.Window.Width  - oTooltip.offsetWidth : 
													iTargetX));
				
				iY = (iTargetY <= - iTargetHeight ? - iTargetHeight:
													(iTargetY + oTooltip.offsetHeight >= jWindowSize.Window.Height ?  
													jWindowSize.Window.Height - oTooltip.offsetHeight: 
													iTargetY));
				
				// Set position
				switch(oTarget.getAttribute("x-alt-positionning"))
				{
					case "top":
						oTooltip.style.left = (iX + Math.round(jDimensions.width / 2) - Math.round(oTooltip.offsetWidth / 2) + 2) + "px";
						oTooltip.style.top  = (iY - oTooltip.offsetHeight) + "px";
						break;
					case "left":
						oTooltip.style.left = (iX - oTooltip.offsetWidth) + "px";
						oTooltip.style.top  = (iY + Math.round(jDimensions.height / 2) - Math.round(oTooltip.offsetHeight / 2) + 2) + "px";
						break;
					case "right":
						oTooltip.style.left = (iX + jDimensions.width) + "px";
						oTooltip.style.top  = (iY + Math.round(jDimensions.height / 2) - Math.round(oTooltip.offsetHeight / 2) + 2) + "px";
						break;
					default:
					case "bottom":
						oTooltip.style.left = (iX + Math.round(jDimensions.width / 2) - Math.round(oTooltip.offsetWidth / 2) + 2) + "px";
						oTooltip.style.top  = (iY + jDimensions.height + 5) + "px";
						break;
				}
				oTooltip.style.zIndex = 60;
			}
			else if (this._Tooltip != null)
			{
				oTooltip = $('div.ct_tooltip')[0];
				oTooltip.style.display = "none";
				oTooltip.style.zIndex = -1;
				oTooltip.style.left = "0px";
				oTooltip.style.top  = "0px";
				this._Tooltip = null;
			}
		}
	},	
	
	text :
	{

		selectionReset : function(oSel,hWindow){ return (!ct.browser.IE ? hWindow.getSelection().removeAllRanges() : hWindow.document.selection.empty()); },
		selectionGet : function(hWindow){ return (!ct.browser.IE ? hWindow.getSelection() : hWindow.document.selection);},
		selectionGetType : function(oSel,hWindow){return (oSel.type == "None" || oSel.type == "Caret" ? "CARET":"RANGE");},
		rangeGet : function(oSel,hWindow){return (!ct.browser.IE && oSel.rangeCount > 0 ? oSel.getRangeAt(oSel.rangeCount - 1) : oSel.createRange());},
		rangeSelect : function(oRng,hWindow){ if (!ct.browser.IE) this.selectionGet(hWindow).addRange(oRng); else oRng.select(); },
		
		rangeCvToCT: function (oInRange,hWindow)
		{
			function adoptBoundary(oOutRange, oInRange, bStart)
			{
				var oCursorNode = hWindow.document.createElement('a'), oParent = oInRange.parentElement(), oInRangeStored = oInRange.duplicate();
				
				// -------------------------------------------------------------------------------------------
				// Browse
				oInRangeStored.collapse(bStart);
				do
				{
					// If the parent is null (first time)
					if (oCursorNode.parentNode == null)				oParent.appendChild(oCursorNode);
					else if (!oCursorNode.previousSibling && oCursorNode.parentNode == oParent)		break;
					else if (!oCursorNode.previousSibling)			oCursorNode.parentNode.parentNode.insertBefore(oCursorNode, oCursorNode.parentNode);
					else if (oCursorNode.previousSibling && oCursorNode.previousSibling.childNodes.length > 0)	oCursorNode.previousSibling.appendChild(oCursorNode);
					else if (oCursorNode.previousSibling)			oCursorNode.parentNode.insertBefore(oCursorNode, oCursorNode.previousSibling);
					
					// Move to element
					oInRangeStored.moveToElementText(oCursorNode);
				}
				while (oInRangeStored.compareEndPoints(bStart ? 'StartToStart' : 'StartToEnd', oInRange) > 0 || !oCursorNode.nextSibling);
				
				// -------------------------------------------------------------------------------------------
				// If the node has not been found
				if (oInRangeStored.compareEndPoints(bStart ? 'StartToStart' : 'StartToEnd', oInRange) == -1)
					oInRangeStored.setEndPoint(bStart ? 'EndToStart' : 'EndToEnd', oInRange);
				
				oOutRange[bStart ? 'oStartNode':'oEndNode'] = (oCursorNode.nextSibling.firstChild ? oCursorNode.nextSibling.firstChild : oCursorNode.nextSibling);
				oOutRange[bStart ? 'iStartOffset':'iEndOffset'] = oInRangeStored.text.length;
				
				//alert("NEXT :" + bStart + " - " + oCursorNode.nextSibling.tagName + ':' + oInRangeStored.text.length + '\n\n' + hWindow.document.body.innerHTML);
				
				// -------------------------------------------------------------------------------------------
				// Delete the cursor node
				oCursorNode.parentNode.removeChild(oCursorNode);
			}
			
			// -----------------------------------------------------------------------------------------------
			// Return range
			var oOutRange = new Object();
			if (ct.browser.IE)
			{
				oOutRange.oStartNode	= null;
				oOutRange.iStartOffset 	= 0;
				oOutRange.oEndNode 		= null;
				oOutRange.iEndOffset 	= 0;
				adoptBoundary(oOutRange, oInRange, true);
				adoptBoundary(oOutRange, oInRange, false);
			}
			else
			{
				oOutRange.oStartNode	= oInRange.startContainer;
				oOutRange.iStartOffset 	= oInRange.startOffset;
				oOutRange.oEndNode 		= oInRange.endContainer;
				oOutRange.iEndOffset 	= oInRange.endOffset;
			}
			return oOutRange;
		},
		
		rangeCvFromCT: function (oInRange,hWindow)
		{
			function adoptEndPoint(oOutRange, oInRange, bStart)
			{
				// Find anchor node and iOffset
				var oContainer 		= oInRange[bStart ? 'oStartNode' : 'oEndNode'];
				var iOffset 		= oInRange[bStart ? 'iStartOffset' : 'iEndOffset'];
				
				var oAnchorNode 	= (oContainer && oContainer.nodeValue !== null && oContainer.data !== null  ? oContainer : null);
				var oAnchorParent	= (oContainer && oContainer.nodeValue !== null && oContainer.data !== null  ? oContainer.parentNode : oContainer);
				var iTextOffset 	= (oContainer.nodeType == 3 || oContainer.nodeType == 4 ? iOffset : 0);
				
				var oCursorNode		= hWindow.document.createElement('a');
				var oIETempRange 	= hWindow.document.body.createTextRange();
				
				if (!oAnchorNode)
					oAnchorParent.appendChild(oCursorNode);
				else
					oAnchorParent.insertBefore(oCursorNode, oAnchorNode);
				
				oIETempRange.moveToElementText(oCursorNode);
				oCursorNode.parentNode.removeChild(oCursorNode);
				
				// Move range
				oOutRange.setEndPoint(bStart ? 'StartToStart' : 'EndToStart', oIETempRange);
				oOutRange[bStart ? 'moveStart' : 'moveEnd']('character', iTextOffset);
			}
			
			// -----------------------------------------------------------------------------------------------
			// Return range
			var oOutRange;
			if (ct.browser.IE)
			{
				oOutRange = hWindow.document.body.createTextRange();
				adoptEndPoint(oOutRange, oInRange, true);
				adoptEndPoint(oOutRange, oInRange, false);
			}
			else
			{
				oOutRange = hWindow.document.createRange();
				oOutRange.setStart(oInRange.oStartNode, oInRange.iStartOffset);
				oOutRange.setEnd(oInRange.oEndNode, oInRange.iEndOffset);
			}
			return oOutRange;
		},
		
		
		
		rangeCTGet : function(hWindow)
		{
			var oSel, oRng, jStartStack, jEndStack;
			
			// -----------------------------------------------------------------------------------------------
			// Focus then get selection and range		
			hWindow.focus();
			oSel = ct.text.selectionGet(hWindow);
			oRng = ct.text.rangeCvToCT(ct.text.rangeGet(oSel,hWindow),hWindow);
			ct.text.selectionReset(oSel,hWindow);
			
			// -----------------------------------------------------------------------------------------------
			// If there is no selection exit
			if (oRng == null)// || (oRng.oStartNode == oRng.oEndNode && oRng.iStartOffset == oRng.iEndOffset))
				return null;
			
			// -----------------------------------------------------------------------------------------------
			// Get root start and end
			jStartStack = ct.text.getAncestorsStack(oRng.oStartNode);
			jEndStack   = ct.text.getAncestorsStack(oRng.oEndNode);
			
			// -----------------------------------------------------------------------------------------------
			// JSON Result structure
			return {oStartRootNode : jStartStack[0].node, oStartNode : oRng.oStartNode	, iStartOffset : oRng.iStartOffset, 
					oEndRootNode : jEndStack[0].node	, oEndNode : oRng.oEndNode		, iEndOffset : oRng.iEndOffset};
		},
		
		
		rangeCTSet : function(oCTRange,hWindow)
		{
			var oSel, oRng;
			
			// -----------------------------------------------------------------------------------------------
			// If there is no selection exit
			if (oCTRange == null || (oCTRange.iStartNode == oCTRange.iEndNode && oCTRange.iStartOffset == oCTRange.iEndOffset))
				return null;
			
			//alert("SET RANGE:" + oCTRange.oStartNode.nodeValue + "-" + oCTRange.iStartOffset + " E:" + oCTRange.oEndNode.nodeValue + "-" + oCTRange.iEndOffset);
			
			// -----------------------------------------------------------------------------------------------
			// Focus, reset selection, get range		
			hWindow.focus();
			
			oSel = ct.text.selectionGet(hWindow);
			ct.text.selectionReset(oSel,hWindow);
			
			oRng = ct.text.rangeCvFromCT(oCTRange,hWindow);
			ct.text.rangeSelect(oRng,hWindow);
		},
		
		
		caretCTGet : function(hWindow)
		{
			var oSel, oRng, jEndStack;
			
			// -----------------------------------------------------------------------------------------------
			// Focus then get selection and range		
			hWindow.focus();
			oSel = ct.text.selectionGet(hWindow);
			oRng = ct.text.rangeCvToCT(ct.text.rangeGet(oSel,hWindow),hWindow);
			
			// -----------------------------------------------------------------------------------------------
			// Get root start and end
			jEndStack   = ct.text.getAncestorsStack(oRng.oEndNode);
			
			// -----------------------------------------------------------------------------------------------
			// JSON Result structure
			return {oRootNode : jEndStack[0].node	, oNode : oRng.oEndNode		, iOffset : oRng.iEndOffset};
		
		},
		
		caretCTSet : function(oCTCaret, hWindow)
		{
			var oSel, oRng, oCTRange;
			
			// -----------------------------------------------------------------------------------------------
			// If there is no selection exit
			if (oCTCaret == null || oCTCaret.oNode == null)
				return null;
			
			// -----------------------------------------------------------------------------------------------
			// Focus, reset selection, set range		
			hWindow.focus();
			oSel = ct.text.selectionGet(hWindow);
			ct.text.selectionReset(oSel,hWindow);
			
			oCTRange = new Object();
			oCTRange.oStartNode 	= oCTCaret.oNode;
			oCTRange.oStartOffset 	= oCTCaret.iOffset;
			oCTRange.oEndNode 		= oCTCaret.oNode;
			oCTRange.oEndOffset 	= oCTCaret.iOffset;
			
			oRng = ct.text.rangeCvFromCT(oCTRange,hWindow);
			ct.text.rangeSelect(oRng,hWindow);
		},
		
		getAncestorsStack : function(oElem)
		{
			var tStack = [];
			while (oElem.tagName != "BODY")
			{
				tStack.unshift({"tag":(oElem.nodeType == 3 ? "" : oElem.nodeName),"node":oElem});
				oElem = oElem.parentNode;
			}
			return tStack;
		}
		
	},
	
	style :
	{
		Get : function(oElem)
		{
			return ((typeof oElem.getAttribute("style") == "object" ? oElem.style.cssText : oElem.getAttribute("style")).toLowerCase() || "");
		},
		
		Set : function(oElem,szStyle)
		{
			if (typeof oElem.getAttribute("style") == "object")
				oElem.style.cssText = szStyle;
			else
				oElem.setAttribute("style",szStyle);
		},
		
		GetSheet : function(oElem)
		{
			if(document.defaultView && document.defaultView.getComputedStyle)
				return document.defaultView.getComputedStyle(oElem,"");
			else if(oElem.currentStyle)
				return oElem.currentStyle;
		},
		
		GetStyle : function(oElem,szStyle)
		{
			var oStyleSheet = this.GetSheet(oElem);
			return oStyleSheet[szStyle];
		},
		
		GetOffset : function(oObject,hWindow)
		{
			var jOffset = {"X":0,"Y":0}, oCur = oObject;
			if (hWindow == undefined) hWindow = window;
			while( oCur != null )
			{
				jOffset.X += oCur.offsetLeft;
				jOffset.Y += oCur.offsetTop;
				oCur = oCur.offsetParent;
			}
			return jOffset;
		},
		
		GetScroll : function(oObject,hWindow)
		{
			var jScroll = {"X":0,"Y":0}, oCur = oObject;
			if (hWindow == undefined) hWindow = window;
			
			// Add object scroll
			if (oCur != undefined)
			{	
				while( oCur != null && oCur != hWindow.document)
				{
					jScroll.Y += oCur.scrollTop;
					jScroll.X += oCur.scrollLeft;
					oCur = oCur.offsetParent;
				}
			}
			else
			{
				if( typeof( hWindow.pageYOffset ) == 'number' )
				{
					//Netscape compliant
					jScroll.Y = hWindow.pageYOffset;
					jScroll.X = hWindow.pageXOffset;
				}
				else if( hWindow.document.body && ( hWindow.document.body.scrollLeft || hWindow.document.body.scrollTop ) )
				{
					//DOM compliant
					jScroll.Y = hWindow.document.body.scrollTop;
					jScroll.X = hWindow.document.body.scrollLeft;
				}
				else if( hWindow.document.documentElement && ( hWindow.document.documentElement.scrollLeft || hWindow.document.documentElement.scrollTop ) )
				{
					//IE6 standards compliant mode
					jScroll.Y = hWindow.document.documentElement.scrollTop;
					jScroll.X = hWindow.document.documentElement.scrollLeft;
				}
			}
			
			return jScroll;
		},
				
		GetDimensions : function (oElem)
		{
			var oElemStyle 			= this.GetSheet(oElem);
			if (oElemStyle == null)
			{
				return  {
				    		"width"			:0,
				    		"height"		:0,
				    		"paddingLeft"	:0,
				    		"paddingTop"	:0,
				    		"paddingRight"	:0,
				    		"paddingBottom"	:0
		    			};
		    }
		    
			// Compute if necessary to display before get values
		    var bShowBeforeCompute 	= !(oElemStyle.display != 'none');
		    if (bShowBeforeCompute)
		    {
			    var szOrigVisibility 	= oElemStyle.visibility;
			    var szOrigPosition 		= oElemStyle.position;
			    var szOrigDisplay 		= oElemStyle.display;
			    
			    // Display block but hidden
			    oElemStyle.visibility 	= 'hidden';
			    oElemStyle.position 	= 'absolute';
			    oElemStyle.display 		= 'block';
		    }
		    
		    // Save values
		    var iWidth 				= oElem.clientWidth; // oElem.offsetWidth
		    var iHeight 			= oElem.clientHeight; // oElem.offsetHeight
		    var iPaddingLeft		= parseInt(oElemStyle.paddingLeft 	|| 0);
		    var iPaddingTop			= parseInt(oElemStyle.paddingTop 	|| 0);
		    var iPaddingRight		= parseInt(oElemStyle.paddingRight 	|| 0);
		    var iPaddingBottom		= parseInt(oElemStyle.paddingBottom || 0);
		    
		    // Restore original values
		    if (bShowBeforeCompute)
		    {
			    oElemStyle.display 		= szOrigDisplay;
			    oElemStyle.position 	= szOrigPosition;
			    oElemStyle.visibility 	= szOrigVisibility;
		    }
		    return {
			    		"width"			:iWidth,
			    		"height"		:iHeight,
			    		"paddingLeft"	:iPaddingLeft,
			    		"paddingTop"	:iPaddingTop,
			    		"paddingRight"	:iPaddingRight,
			    		"paddingBottom"	:iPaddingBottom
		    		};
		},
		
		klass: {
			Add : function(oElem,szStyle)
			{
				if (oElem == null || oElem == undefined || typeof(oElem) != "object") return false;
				
				if (Object.isArray(oElem))
				{
					for(var i=0,n=oElem.length;i<n;i++)
					{
						if (!this.Has(oElem[i],szStyle))
							oElem[i].className += " " + szStyle;
					}
				}
				else 
				{
					if (!this.Has(oElem,szStyle))
						oElem.className += " " + szStyle;					
				}
				return true;
			},
			Remove : function(oElem,szStyle)
			{
				if (oElem == null || oElem == undefined || typeof(oElem) != "object") return false;
				if (Object.isArray(oElem))
				{
					for(var i=0,n=oElem.length;i<n;i++)
					{
						if (oElem[i].className != "")
							oElem[i].className = oElem[i].className.replace(new RegExp('(\\s|^)'+szStyle+'(\\s|$)'),' ');
					}
				}
				else
				{
					if (oElem.className != "")
						oElem.className = oElem.className.replace(new RegExp('(\\s|^)'+szStyle+'(\\s|$)'),' ');
				}
				return true;
			},
			Has : function(oElem,szStyle)
			{
				if (oElem == null || oElem == undefined || typeof(oElem) != "object") return "";
				return (oElem.className.match(new RegExp('(\\s|^)'+szStyle+'(\\s|$)')) != null);
			}
		}
	},
	
	json : {
		Parse : function(szJSON)
		{
			var jSON;
			if (szJSON == "") return {};
			try{
				jSON = JSON.parse(szJSON);
			}catch(e){
				return undefined;
			}
			return jSON;
		},
		
		Stringify : function(jJSON)
		{
			var szJSON;
			try{
				szJSON = JSON.stringify(jJSON);
			}catch(e){
				return undefined;
			}
			return szJSON;
		},
		
		_oXMLParser : null,
		ParseXML : function(szText)
		{
			var oXML;
			
			if (window.ActiveXObject)
			{
				if (!ct.json._oXMLParser)
					ct.json._oXMLParser = new ActiveXObject('Microsoft.XMLDOM');
				ct.json._oXMLParser.async='false';
				ct.json._oXMLParser.loadXML(szText);
				oXML = ct.json._oXMLParser;
			}
			else
			{
				if (!ct.json._oXMLParser)
					ct.json._oXMLParser = new DOMParser();
				oXML = ct.json._oXMLParser.parseFromString(szText,'text/xml');
			}
			
			return ct.json.FromXML(oXML);
		},
		
		FromXML : function(xml)
		{
			// Create the return object
			var obj = {};
			
			// Get attributes
			if (xml.nodeType == 1)
			{
				if (xml.attributes.length > 0)
				{
					obj["@attributes"] = {};
					for (var j = 0; j < xml.attributes.length; j++)
					{
						var attribute = xml.attributes.item(j);
						
						obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
					}
				}
			}
			// Terminal node
			else if (xml.nodeType == 3)
			{
				//obj = xml.nodeValue;
				return xml.nodeValue;
			}
			
			// do children
			if (xml.hasChildNodes())
			{
				for(var i = 0,n=xml.childNodes.length; i < n; i++)
				{
					var item 		= xml.childNodes.item(i);
					var nodeName 	= item.nodeName;
					
					// For single text child
					if(n == 1 && item.nodeType == 3)
					{
						return item.nodeValue;
					}
					else
					{
						if (typeof(obj[nodeName]) == "undefined")
						{
							obj[nodeName] = ct.json.FromXML(item);
						}
						else
						{
							if (typeof(obj[nodeName].length) == "undefined")
							{
								var old = obj[nodeName];
								obj[nodeName] = [];
								obj[nodeName].push(old);
							}
							
							obj[nodeName].push(ct.json.FromXML(item));
						}
					}
				}
			}
			return obj;
		},
		
		Equal : function(oJSON1,oJSON2)
		{
			if(!oJSON1 && !oJSON2)	return true;
			if(!oJSON1 || !oJSON2)	return false;
			
			for (szKey in oJSON1)
			if(typeof oJSON1[szKey] == 'object')
			{
				if(!this.Equal(oJSON1[szKey],oJSON2[szKey]))
					return false;
			}
			else if(oJSON1[szKey] != oJSON2[szKey])
			{
				return false;
			}
			return true;
		}	
	},
	
	
	animations : 
	{
		_tAnimations 	: [],
		_tAnimationsTypes : {
			'default'	: [1,2,3,4,5,6,7,8,9,10,9,8,7,6,5,4,3,2,1],
			'blast'		: [12,12,11,10,10,9,8,7,6,5,4,3,2,1],
			'linear'	: [10,10,10,10,10,10,10,10,10,10]
		},
		_bActive 		: false,
		_iTickInterval	: 20,
		_oTickTimer		: null,
		
		Create : function(szType,iStart,iEnd,fnOnBegin,fnOnFrame,fnOnComplete,vUserParams)
		{
			//ctl.log.Debug('ctl.animator.Create()');
			szType 		= szType || 'default';
			
			// Add to the animation queue
			var oObject 		= new Object();
			oObject.onBegin 	= (fnOnBegin 	? fnOnBegin : null);
			oObject.onFrame 	= (fnOnFrame 	? fnOnFrame : null);
			oObject.onComplete 	= (fnOnComplete ? fnOnComplete : null);
			oObject.vUserParams	= (vUserParams ? vUserParams : null);
			oObject.bActive 	= true;
			oObject.iFrameCount = this._tAnimationsTypes[szType].length;
			oObject.iFrame = 0;
			
			// Crate motion tween
			var tTween 	= [iStart];
			var iTmp 	= iStart;
			var iDiff 	= iEnd - iStart;
			for (var i=0 ; i < oObject.iFrameCount; i++)
			{
				iTmp += iDiff * this._tAnimationsTypes[szType][i] * 0.01;
				tTween[i] 		= {};
				tTween[i].data 	= iTmp;
				tTween[i].event = null;
			}
			oObject.tTween = tTween;
			
			// Push new animation into the array
			this._tAnimations.push(oObject);
		},
		
		Start : function()
		{
			// Verify if the motion engine is already started
			if (this._oTickTimer || this._bActive)
				return false;
			
			// Start the motion engine
			this._bActive = true;
			this._oTickTimer  = setInterval(this._onTick.bind(this),this._iTickInterval);
		},
		
		Stop : function()
		{
			// Verify if the motion engine is already stopped
			if (!this._oTickTimer || !this._bActive)
				return false;
			
			clearInterval(this._oTickTimer);
			this._oTickTimer 	= null;
			this._bActive 		= false;
			this._tAnimations  	= [];
		},
		
		_onFrame  : function(iIndex)
		{
			// Get current animation
			var oAnim = this._tAnimations[iIndex];
			if (!oAnim.bActive)
				return false;
			
			// On begin
			if (oAnim.iFrame == 0)
			{
				if (oAnim.onBegin)
					oAnim.onBegin(oAnim.vUserParams);
			}
			
			// Call the tween callback
			if (oAnim.onFrame && oAnim.tTween[oAnim.iFrame])
				oAnim.onFrame(oAnim.tTween[oAnim.iFrame].data,oAnim.vUserParams);
			
			// On complete
			if (oAnim.iFrame++ >= oAnim.iFrameCount - 1)
			{
				oAnim.bActive = false;
				oAnim.iFrame = 0;
				if (oAnim.onComplete)
					oAnim.onComplete(oAnim.vUserParams);
				return false;
			}
			return true;
		},
		
		_onTick : function()
		{
			var iActive = 0;
			for (var i=0; i< this._tAnimations.length; i++)
			{
				if (this._tAnimations[i].bActive)
				{
					if (!this._onFrame(i))
					{
						this._tAnimations.splice(i,1);
						i--;
					}
					else
					{
						iActive++;
					}
				}
			}
			
			if (iActive == 0 && this._oTickTimer)
				this.Stop();
		}
	},
	
	webservices : 
	{
		_bFree : true,
		_szTechnology : "",
		_szUrl : "",
		_tCookies : [],
		_tTriggers : [],
		
		Connect : function(szTechnology,szUrl,bUseLocalCookie)
		{
			if (!this._bFree)
			{
				ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,'<b>WebService</b><br/>Already connected!');
				return;
			}
			
			this._bFree		 	= false;
			this._szUrl		 	= szUrl;
			this._szTechnology 	= szTechnology;
			this._tCookies 		= [];
			
			// Get current cookies
			/*var tCookies = document.cookie.split(';');
			if (bUseLocalCookie)
			for(var i=0;i<tCookies.length;i++)
			{
				tCookie = tCookies[i].split('=');
				this._tCookies.push({"name":tCookie[0],"value":tCookie[1]});
			}*/
		},
		
		SetTrigger : function(szTrigger,parCallBackFn,parCallBackParams)
		{
			this._tTriggers[szTrigger] = { "CallBackFn":parCallBackFn, "CallBackParams":parCallBackParams};
		},
		
		Disconnect : function()
		{
			this._bFree 		= true;
			this._szUrl 		= "";
			this._szTechnology 	= "REST";
			this._tCookies 		= [];
			this._tTriggers		= [];
		},
		
		Call : function(parMethod,parOperation,parParams, parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			if (this._szTechnology == "REST")
			{
				ct.ajax.JSONPost(this._szUrl + "/" + parOperation,parParams,
								this._CallBack.bind(this),
								{"fnCallBackFn":parCallBackFn,"tCallBackParams":parCallBackParams},
								parErrorsHandler);
			}
			else if (this._szTechnology == "REST-XML")
			{
				ct.ajax.XMLPost(this._szUrl + "/" + parOperation,parParams,
								this._CallBack.bind(this),
								{"fnCallBackFn":parCallBackFn,"tCallBackParams":parCallBackParams},
								parErrorsHandler);
			}
		},
		
		_CallBack : function(parWSResponse,parCallBacks)
		{
			// Call the callback
			if (parCallBacks && parCallBacks.fnCallBackFn)
				parCallBacks.fnCallBackFn(parWSResponse,parCallBacks.tCallBackParams);
			
			// Check if the response if a JSON or not
			if (typeof parWSResponse == "object")
			{
				// Check each triggers
				for (szTrigger in this._tTriggers)
	            {
	            	if (!parWSResponse[szTrigger])
	            		continue;
					if (parWSResponse[szTrigger] == "")
						continue;
					
					// Trigger
					this._tTriggers[szTrigger].CallBackFn(parWSResponse,this._tTriggers[szTrigger].CallBackParams);
	            }
			}
		}
	},
	
	ajax : 
	{
		// System attributes
		_tQueue : [],
		_bRunning : false,
		_jAjaxRequest : null,
		_fnReadyStateChanged : null,
		_oTimeOut : null,
		_fnWatchDog : null,
		
		_oXMLHttp : (function()
		{
			try { return new XMLHttpRequest();} // Mozilla / Safari 
			catch (e)
			{
				// IE
				var tXMLHttp = ['MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
				for (var i=0;i < tXMLHttp.length; i++)
				{
					try{ return new ActiveXObject(tXMLHttp[i]);}
					catch (e){}
				}
				ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,'<b>Ajax</b><br/>Unable to create XMLHttpRequest!');
				return null;
			}
		})(),
		
		// Public methods
		Get : function(parUrl,parData,parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			var tHeader = [	{"name":"Content-Type","value":"application/x-www-form-urlencoded"},
							{"name":"Cache-Control","value":"no-cache"}];
			this.Request('GET',parUrl,parData,tHeader,parCallBackFn,parCallBackParams,parErrorsHandler);
			return false;
		},
		
		Post : function(parUrl,parData,parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			var tHeader = [	{"name":"Content-Type","value":"application/x-www-form-urlencoded"},
							{"name":"Cache-Control","value":"no-cache"}];
			this.Request('POST',parUrl,parData,tHeader,parCallBackFn,parCallBackParams,parErrorsHandler);
			return false;
		},
		
		JSONGet : function(parUrl,parJSONData,parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			if (parJSONData == "" || parJSONData == undefined)	parJSONData = {};
			var tHeader = [	{"name":"Content-Type","value":"application/json"},
							{"name":"Cache-Control","value":"no-cache"}];
			this.Request('JSON_GET',parUrl,ct.json.Stringify(parJSONData),tHeader,parCallBackFn,parCallBackParams,parErrorsHandler);
			return false;
		},
		
		JSONPost : function(parUrl,parJSONData,parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			if (parJSONData == "" || parJSONData == undefined)	parJSONData = {};
			var tHeader = [	{"name":"Content-Type","value":"application/json"},
							{"name":"Cache-Control","value":"no-cache"}];
			this.Request('JSON_POST',parUrl,ct.json.Stringify(parJSONData),tHeader,parCallBackFn,parCallBackParams,parErrorsHandler);
			return false;
		},
		
		XMLPost : function(parUrl,parJSONData,parCallBackFn,parCallBackParams,parErrorsHandler)
		{
			if (parJSONData == "" || parJSONData == undefined)	parJSONData = {};
			var tHeader = [	{"name":"Content-Type","value":"text/xml"},
							{"name":"Cache-Control","value":"no-cache"}];
			
			var szRequestParams = "<\?xml version=\"1.0\"?><request>";
			
			for(jParam in parJSONData)
				szRequestParams += "<" + jParam + ">" + parJSONData[jParam] + "</" + jParam + ">";
			
			szRequestParams		+= "</request>";
			this.Request('XML_POST',parUrl,szRequestParams,tHeader,parCallBackFn,parCallBackParams,parErrorsHandler);
			return false;
		},
		
		Abort : function()
		{			
			// Clear the watchdog
			clearTimeout(this._oTimeOut);
			this._oTimeOut = null;
			
			// Abort
			this._oXMLHttp.abort();
				
			// Clean the request
			delete this._jAjaxRequest;
			this._jAjaxRequest = null;
			
			// Retry
			this._bRunning = false;
			this._Request();
		},
		
		Request: function(parMethod,parUrl,parParams,parHeader,parCallBackFn,parCallBackParam,parErrorsHandler)
		{
			if (this._tQueue.length > 10)
			{
				if (typeof(parErrorsHandler) == "function")
					parErrorsHandler("timeout",parCallBackParam);
				else
					ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Ajax error</b><br/><br/>The message queue is full!");
				
				return;
			}
			
			this._tQueue.push({
				"Method":parMethod,
				"Url":parUrl,
				"Params":parParams,
				"Header":parHeader,
				"CallBackFn":parCallBackFn,
				"CallBackParam":parCallBackParam,
				"ErrorsHandler":parErrorsHandler,
				"Response":""
			});
			
			this._Request();
		},
		
		
		// Private methods
		_Request : function()
		{
			// Init the callback the first time
			if (this._fnOnReadyStateChanged == null)
			{
				this._fnReadyStateChanged = this._RequestOnReadyStateChanged.bind(this);
				this._oXMLHttp.onreadystatechange = this._fnReadyStateChanged;
				this._fnWatchDog = this._WatchDog.bind(this);
			}
			
			// Verify is the ajax component is running and if the queue is not empty
			if (this._tQueue.length <= 0)	return;
			if (this._bRunning == true)		return;
			this._bRunning = true;
			
			// Get the next item in the queue
			this._jAjaxRequest = this._tQueue.shift();
			if (this._jAjaxRequest.Params == undefined)	this._jAjaxRequest.Params = "";
			
			// Start the watchdog 8 sec
			this._oTimeOut = setTimeout(this._fnWatchDog.bind(this),8000);
			
			// Try to connect to the page
			try
			{
				// Connection to the specified URL
				if (/POST/.test(this._jAjaxRequest.Method))
					this._oXMLHttp.open("POST",this._jAjaxRequest.Url,true);
				else
					this._oXMLHttp.open("GET", this._jAjaxRequest.Url + (this._jAjaxRequest.Params != "" ? "?" + this._jAjaxRequest.Params:""),true);
				
				// Header
				for(var i=0;i<this._jAjaxRequest.Header.length;i++)
					this._oXMLHttp.setRequestHeader(this._jAjaxRequest.Header[i].name,this._jAjaxRequest.Header[i].value);
					
				// POST or GET
				if (/POST/.test(this._jAjaxRequest.Method))
					this._oXMLHttp.send(this._jAjaxRequest.Params);
				else
					this._oXMLHttp.send("");
				
				// Clean the params
				this._jAjaxRequest.Params = "";
			}
			catch(e)
			{
				
				if (this._jAjaxRequest == null)
				{
					this.Abort();
					return;
				}
				
				// User errors handler
				if (typeof(this._jAjaxRequest.ErrorsHandler) == "function")
					this._jAjaxRequest.ErrorsHandler(e.name,this._jAjaxRequest.CallBackParam);
				else
					ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Ajax error</b><br/>" + e.name + "<br/>" + e.message);
				
				this.Abort();
				return;
			}
		},
		
		_WatchDog : function()
		{
			// User errors handler
			if (typeof(this._jAjaxRequest.ErrorsHandler) == "function")
				this._jAjaxRequest.ErrorsHandler("timeout",this._jAjaxRequest.CallBackParam);
			else
				ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Ajax timeout</b><br/>");
			
			this.Abort();
		},
		
		_RequestOnReadyStateChanged: function()
		{
			// Ready state management
			switch(this._oXMLHttp.readyState)
			{
				case 0:return;	// Not initalize
	      		case 1:return;	// Loading
	      		case 2:return;	// Loaded
	      		case 3:return;	// Interacting
	      		case 4:break;	// Finished
	      		default:
	      			ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error</b><br/><br/>State " + this._oXMLHttp.readyState + "<br/>Http bad state<br/>Method:" + this._jAjaxRequest.Method + "<br/>Url:" + this._jAjaxRequest.Url);
					this.Abort();
					return;
      		}
			
			// The request has been performed
			if (this._oXMLHttp.status == 200)// || this._oXMLHttp.status == 0)
			{
				// Verify if an error exists
				if (/MKO STDIO ERROR/.test(this._oXMLHttp.responseText) ||
						/<b>Warning<\/b>/.test(this._oXMLHttp.responseText) ||
						/<b>Fatal error<\/b>/.test(this._oXMLHttp.responseText))
				{
					alert(this._jAjaxRequest.Url + "\n" + this._oXMLHttp.responseText);
				}
				else if (this._jAjaxRequest.CallBackFn != undefined && this._jAjaxRequest.CallBackFn != "")
				{
					
					var vResponse 	= this._oXMLHttp.responseText;
					
					//alert(vResponse);
					
					var szContentType=this._oXMLHttp.getResponseHeader("content-type");
					if (/json/.test(szContentType))		vResponse = ct.json.Parse(vResponse);
					if (/xml/.test(szContentType))		vResponse = ct.json.ParseXML(vResponse);
					
					// Clear the watchdog
					clearTimeout(this._oTimeOut);
					this._oTimeOut = null;
					
					// Abort
					this._oXMLHttp.abort();
					
					// Call callback
					this._jAjaxRequest.CallBackFn(vResponse,this._jAjaxRequest.CallBackParam);
				}
				
				this.Abort();
				return;
			}
			
			// User errors handler
			if (this._jAjaxRequest.ErrorsHandler != undefined && this._jAjaxRequest.ErrorsHandler != "")
			{
				this._jAjaxRequest.ErrorsHandler(this._oXMLHttp.status,this._jAjaxRequest.CallBackParam);
			}
			// Default errors handler
			else switch(this._oXMLHttp.status)
			{
				case 0:break;
				case 301:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 301</b><br/><br/>This page has been moved!<br/>" + this._jAjaxRequest.Url);	break;
				case 400:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 400</b><br/><br/>Bad request!<br/>" + this._jAjaxRequest.Url);	break;
				case 401:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 401</b><br/><br/>Not authorized!<br/>" + this._jAjaxRequest.Url);break;
				case 403:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 403</b><br/><br/>Forbidden!<br/>" + this._jAjaxRequest.Url);break;
				case 404:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 404</b><br/><br/>This page doesn't exists!<br/>" + this._jAjaxRequest.Url);break;
				case 500:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 500</b><br/><br/>Internal error!<br/>" + this._jAjaxRequest.Url);break;
				case 501:ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error 501</b><br/><br/>Not implemented!<br/>" + this._jAjaxRequest.Url);break;
				default: ct.msgbox.Show(ct.msgbox.TYPE.ERROR,0,"<b>Internal ajax error " + this._oXMLHttp.status + "</b><br/><br/>Bad response: " +
							 															   this._oXMLHttp.statusText + "<br/>" + this._jAjaxRequest.Url); break;
			}
			
			this.Abort();
			return;
		}
		
	},
	
	msgbox : 
	{
		TYPE : 		{ERROR : 1,	WARNING : 2,QUESTION : 3, INFORMATION : 4},
		QUESTION :  {OK : 0, YES_NO : 1, YES_CANCEL : 2, VALID_CANCEL : 3},
		_tQueue : [],
		_bRunning : false,
		_bMutex : false,
		
		Show : function(parMessageType, parQuestionType,parMsg,parCallBackBtn1,parCallBackBtn2,parCallBackParam)
		{
			// Add to the msgbox Queue
			if (this._tQueue.push({
				"MessageType":parMessageType,
				"QuestionType":parQuestionType,
				"Message":parMsg,
				"CallBackBtn1":parCallBackBtn1,
				"CallBackBtn2":parCallBackBtn2,
				"CallBackParam":parCallBackParam
			}) > 0)
			{
				// Try to display the dialog box
				this._Show();
			}
		},
		
		_Show : function()
		{
			var jMsgBox, fnCallBackButton1 = 0, fnCallBackButton2 = 0;
			
			// If the msgbox is already visible then leave
			if (this._Running == true)		return;
			if (this._tQueue.length == 0)	return;
			
			// Mutex
			while(this._bMutex);
			this._bMutex = true;
			
			// Display the msgbox
			this._bRunning = true;
			jMsgBox = this._tQueue.shift();
			
			// Set the popup message
			if (!$('#ct_popup_msg'))
			{
				this._bRunning = false;
				alert(jMsgBox.Message);
				return;
			}
			$('#ct_popup_msg').innerHTML = jMsgBox.Message;
			
			// If the callback btn1
			fnCallBackButton1 = function(){
				ct.dlg.Hide("ct_popup");
				if (jMsgBox.CallBackBtn1 != undefined)
					jMsgBox.CallBackBtn1(jMsgBox.CallBackParam);
				this._bRunning = false;
				this._Show();
				return false;
			};
			
			// If the callback btn2
			fnCallBackButton2 = function(){
				ct.dlg.Hide("ct_popup");
				if (jMsgBox.CallBackBtn2 != undefined)
					jMsgBox.CallBackBtn2(jMsgBox.CallBackParam);
				this._bRunning = false;
				this._Show();
				return false;
			};
		
			// Display the right popup
			switch(jMsgBox.MessageType)
			{
				default:
				case this.TYPE.INFORMATION:	$('#ct_popup_img').className = 'png ct_popup_information';	break;
				case this.TYPE.ERROR:		$('#ct_popup_img').className = 'png ct_popup_error';		break;
				case this.TYPE.WARNING:		$('#ct_popup_img').className = 'png ct_popup_warning';		break;
				case this.TYPE.QUESTION:	$('#ct_popup_img').className = 'png ct_popup_question';		break;
			}
			
			//
			switch(jMsgBox.QuestionType)
			{
				case this.QUESTION.YES_NO:
					$('#ct_popup_button1').style.display = 'block';
					$('#ct_popup_button1').className = 'png btn btn_yes btn_1';
					$('#ct_popup_button1').onclick = fnCallBackButton1.bind(this);
					$('#ct_popup_button2').style.display = 'block';
					$('#ct_popup_button2').className = 'png btn btn_no btn_2';
					$('#ct_popup_button2').onclick = fnCallBackButton2.bind(this);
					$('#ct_popup_button3').style.display = 'none';
					break;
					
				case this.QUESTION.YES_CANCEL:
					$('#ct_popup_button1').style.display = 'block';
					$('#ct_popup_button1').className = 'png btn btn_yes btn_1';
					$('#ct_popup_button1').onclick = fnCallBackButton1.bind(this);
					$('#ct_popup_button2').style.display = 'block';
					$('#ct_popup_button2').className = 'png btn btn_cancel btn_2';
					$('#ct_popup_button2').onclick = fnCallBackButton2.bind(this);
					$('#ct_popup_button3').style.display = 'none';
					break;
					
				case this.QUESTION.VALID_CANCEL:
					$('#ct_popup_button1').style.display = 'block';
					$('#ct_popup_button1').className = 'png btn btn_valid btn_1';
					$('#ct_popup_button1').onclick = fnCallBackButton1.bind(this);
					$('#ct_popup_button2').style.display = 'block';
					$('#ct_popup_button2').className = 'png btn btn_cancel btn_2';
					$('#ct_popup_button2').onclick = fnCallBackButton2.bind(this);
					$('#ct_popup_button3').style.display = 'none';
					break;
				default:
					$('#ct_popup_button1').style.display = 'none';
					$('#ct_popup_button2').style.display = 'none';
					$('#ct_popup_button3').style.display = 'block';
					$('#ct_popup_button3').className = 'png btn btn_ok btn_3';
					$('#ct_popup_button3').onclick = fnCallBackButton1.bind(this);
			}		
			
			/* Show the popup */
			ct.dlg.Show("ct_popup");
			
			/* Set the focus */
			if ($('#ct_popup_button3').style.display != 'none')
				$('#ct_popup_button3').focus();
			else
				$('#ct_popup_button1').focus();
				
			// Mutex
			this._bMutex = false;
		}	
	},
	
	dlg : 
	{
		_tDlg : [],
		
		Show : function(parId,parShow)
		{
			var oObject = $('#' + parId);
			if (oObject.style.display == "block")
				return;
			
			// Push into the dlg stack
			this._tDlg.push(parId);
			
			// Display the backlayer
			if (this._tDlg.length == 1)
				this.backlayer.Show(parId);
			
			// Display and the dlg
			oObject.style.display = "block";
			
			// Ajust the backlayer zindex
			//this.backlayer.AjustZIndex($('#' + parId).style.zIndex - 1);
		},
		Hide : function(parId,parShow)
		{
			var oObject = $('#' + parId);
			if (oObject.style.display != "block")
				return;
			
			// Pop the dlg stack
			this._tDlg.pop();
			
			// Hide the dlg
			oObject.style.display = "none";	
			
			// Ajust the backlayer zindex
			if (this._tDlg.length > 0)
				;//this.backlayer.AjustZIndex($('#' + this._tDlg[this._tDlg.length - 1]).style.zIndex);
			else
				this.backlayer.Hide();	
		},
		
		backlayer :
		{
			AjustZIndex : function(parZIndex)
			{
				$('#ct_backlayer').style.zIndex = parZIndex;
			},
			
			Show : function()
			{
				var oObject = $('#ct_backlayer');
				
				oObject.style.display = "block";
				oObject.style.opacity = ".0";
				oObject.style.filter = "alpha(opacity=0)";
				for(var i=1;i<20;i++)
				{
					setTimeout("$('#ct_backlayer').style.opacity = '." + ((i * 0.025) + "").substring(2) + "';", (i * 20));
					setTimeout("$('#ct_backlayer').style.filter = 'alpha(opacity=" + (i * 2.5) + ")';", (i * 20));
				}
			},
			
			Hide : function()
			{
				$('#ct_backlayer').style.display = 'none';
			}
		},
		
		splash : 
		{
			_jData : {
					"Url":"",
					"Params":"",
					"CallBackFn1":undefined,
					"CallBackFn2":undefined,
					"CallBackParam":undefined,
					"ErrorHandler":undefined
				},
			
			Show : function(parUrl,parJSONData,parCb1,parCb2,parUserData,parErrorHandler)
			{
				// Save data
				this._jData.Url 			= parUrl;
				this._jData.Params 			= parJSONData;
				this._jData.CallBackFn1 	= parCb1;
				this._jData.CallBackFn2 	= parCb2;
				this._jData.CallBackParam 	= parUserData;
				this._jData.ErrorHandler	= parErrorHandler;
				
				// Load the form
				ct.ajax.JSONPost(
								this._jData.Url,
								this._jData.Params,
								(function(parFormSource)
								{
									// Display the page into the div
									_ct_div_DisplayPage($("#ct_splash_content"),parFormSource);
									
									// Show the splash
									ct.dlg.Show("ct_splash");
								}).bind(this),
								"",
								parErrorHandler);
			},
			
			_Unload : function(parCallBack1_or_2,parJSONData)
			{
				var oCallBackFn, oCallBackParam, oDiv;
				
				// Hide the form
				ct.dlg.Hide("ct_splash");
				
				// Free this div
				oDiv = $("#ct_splash_content");
				Object.clean(oDiv);
				
				// Get all information required
				oCallBackFn 	= (parCallBack1_or_2 == 1 ? this._jData.CallBackFn1:this._jData.CallBackFn2);
				oCallBackParam 	= this._jData.CallBackParam;
				
				// Clean
				this._jData.Url 			= "";
				this._jData.Params 			= "";
				this._jData.CallBackFn1 	= undefined;
				this._jData.CallBackFn2 	= undefined;
				this._jData.CallBackParam 	= undefined;
				
				// Call the ok callback
				if (oCallBackFn != undefined && oCallBackFn != "")
					oCallBackFn(parJSONData,oCallBackParam);
			},
			PostResCb1 : function(parJSONData){ct.dlg.splash._Unload(1,parJSONData);},
			PostResCb2 : function(parJSONData){ct.dlg.splash._Unload(2,parJSONData);},
			
			Resize : function(parWidth,parHeight)
			{
				var oSplash,oDiv,jWindowSize = ct.window.size.Get();
				oSplash = $('#ct_splash');
				oDiv  = $('#ct_splash_content');
				
				if (/%/.test(parWidth))	parWidth  = Math.round(jWindowSize.Window.Width * parseInt(parWidth.substr(0,parWidth.length -1)) / 100);
				if (/%/.test(parHeight))parHeight = Math.round(jWindowSize.Window.Height * parseInt(parHeight.substr(0,parHeight.length -1)) / 100);
				parWidth = parseInt(parWidth);
				parHeight = parseInt(parHeight);
				
				// Resize workspace
				oSplash.style.width 		= (parWidth + 60) + "px";
				oSplash.style.height 		= (parHeight + 60)  + "px";
				oSplash.style.marginLeft 	= -((parWidth + 60) / 2) + "px";
				oSplash.style.marginTop 	= -((parHeight + 60) / 2) + "px";
				
				// Resize workspace content
				oDiv.style.width 		= parWidth + "px";
				oDiv.style.height 		= parHeight + "px";
				
				// Resize workspace borders
				$('#ct_splash img.ct_borders_tc')[0].style.width 	= parWidth + "px";
				$('#ct_splash img.ct_borders_ml')[0].style.height 	= parHeight + "px";
				$('#ct_splash img.ct_borders_mr')[0].style.height 	= parHeight + "px";
				$('#ct_splash img.ct_borders_bc')[0].style.width 	= parWidth + "px";
			}
			
		},
		
		form :
		{
			Get : function(parFormName,hWindow)
			{
				
				if (!hWindow) hWindow = window;
				
				// Variable declaration
				var i,szPostBlock = "",szName,szValue;
				
				// Get the select
				var tInputs = $('[' + parFormName + '] select',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined || tInputs[i].name == "")
						continue;
					
					//alert(tInputs[i].type + ':' + tInputs[i].name + '=' + tInputs[i].value);
					szName = tInputs[i].name;
					szValue = tInputs[i].value;
					//szPostBlock += '"' + szName + '":"' + szValue.replace(/\\/g,'').replace(/"/g,'\\"').replace(/\n/g,'\\n').replace(/\r/g,'\\r').replace(/\t/g,'\\t') + '",';
					szPostBlock += '"' + szName + '":"' + szValue.replace(/\|/g,'').replace(/\\/g,'').replace(/"/g,'').replace(/\n/g,'').replace(/\r/g,'').replace(/\t/g,'') + '",';
				}
				
				// Get the textarea
				tInputs = $('[' + parFormName + '] textarea',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined || tInputs[i].name == "")
						continue;
					
					// Save
					if (tInputs[i].getAttribute('x-type') == 'wysiwyg' && hWindow.tinyMCE)
					{
						szName 				= tInputs[i].name;
						szValue 			= hWindow.tinyMCE.get(tInputs[i].name).getContent().replace(/\r?\n/g,'');
						tInputs[i].value 	= szValue;
					}
					else if (tInputs[i].getAttribute('x-type') == 'source')
					{
						szName = tInputs[i].name;
						szValue = tInputs[i].value;
					}
					else
					{
						//alert(tInputs[i].type + ':' + tInputs[i].name + '=' + tInputs[i].value);
						szName = tInputs[i].name;
						szValue = tInputs[i].value.replace(/\r?\n/g,'<br/>').replace(/"/g,'');
					}
					
					//alert(szValue);
					
					//szPostBlock += '"' + szName + '":"' + szValue.replace(/\\/g,'').replace(/"/g,'\\"').replace(/\n/g,'\\n').replace(/\r/g,'\\r').replace(/\t/g,'\\t') + '",';
					szPostBlock += '"' + szName + '":"' + szValue.replace(/\|/g,'').replace(/\\/g,'').replace(/"/g,'\\"') + '",';
				}
					
				// Get the inputs and create the post block
				tInputs = $('[' + parFormName + '] input',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined || tInputs[i].name == "")
						continue;
					
					szName = ""
					szValue = "";
					
					if (/checkbox/.test(tInputs[i].type))
					{
						szName = tInputs[i].name;
						szValue = (tInputs[i].checked == true ? "true":"false");
					}
					else if (/radio/.test(tInputs[i].type))
					{
						if (tInputs[i].checked == true)
						{
							szName = tInputs[i].name;
							szValue = tInputs[i].value;
						}
					}
					else
					{
						szName = tInputs[i].name;
						szValue = tInputs[i].value;
					}
					//szPostBlock += '"' + szName + '":"' + szValue.replace(/\\/g,'').replace(/"/g,'\\"').replace(/\n/g,'\\n').replace(/\r/g,'\\r').replace(/\t/g,'\\t') + '",';
					szPostBlock += '"' + szName + '":"' + szValue.replace(/\|/g,'').replace(/\\/g,'').replace(/"/g,'').replace(/\n/g,'').replace(/\r/g,'').replace(/\t/g,'') + '",';
				}
				szPostBlock = "{" + szPostBlock.substr(0,szPostBlock.length -  1)  + "}";
				
				return ct.json.Parse(szPostBlock);
			},
			
			Set : function(parFormName,jForm,hWindow)
			{
				
				if (!hWindow) hWindow = window;
				
				// Variable declaration
				var i,szPostBlock = "",szName,szValue;
				
				// Get the select
				var tInputs = $('[' + parFormName + '] select',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined)	continue;
					if (!jForm[tInputs[i].name]) 		continue;
					
					tInputs[i].value = jForm[tInputs[i].name];
				}
				
				// Get the textarea
				tInputs = $('[' + parFormName + '] textarea',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined)	continue;
					if (!jForm[tInputs[i].name]) 		continue;
					
					// Save
					if (tInputs[i].getAttribute('x-type') == 'wysiwyg' && hWindow.tinyMCE)
					{
						//szName 				= tInputs[i].name;
						//szValue 			= hWindow.tinyMCE.get(tInputs[i].name).getContent();
						//tInputs[i].value 	= szValue;
						
						tInputs[i].value = jForm[tInputs[i].name];
					}
					else
					{
						tInputs[i].value = jForm[tInputs[i].name];
					}
					
					
				}
					
				// Get the inputs and set values
				tInputs = $('[' + parFormName + '] input',hWindow.document);
				for(i=0;i<tInputs.length;i++)
				{
					if (tInputs[i].name == undefined)	continue;
					if (!jForm[tInputs[i].name]) 		continue;
					
					if (/checkbox/.test(tInputs[i].type) || /radio/.test(tInputs[i].type))
					{
						tInputs[i].checked = (jForm[tInputs[i].name] == "true" || jForm[tInputs[i].name] == true ? true:false);
					}
					else
					{
						tInputs[i].value = jForm[tInputs[i].name];
					}
					
				}
				return '';
			},
			
			Post : function(parFormName,parUrl,parCallBackFn,parCallBackParam)
			{
				ct.ajax.JSONPost(parUrl,this.Get(parFormName),parCallBackFn,parCallBackParam);
			},
			
			_tStack : [],
			_iCurrent : -1,
			_bMutex : false,
			Show : function(parFormUrl,parJSONData,parCb1,parCb2,parUserData,parErrorHandler)
			{
				if (this._bMutex)
					return;
				
				// Push into to the stack
				if (this._tStack.push({
					"Url"			:parFormUrl,
					"Params"		:parJSONData,
					"CallBackFn1"	:parCb1,
					"CallBackFn2"	:parCb2,
					"CallBackParam"	:parUserData,
					"ErrorHandler"	:parErrorHandler,
					"Window":{
						"Size"		:{"Width":0,"Height":0}
					}
				}) > 0)
				{
					this._Load();
				}
			},
			
			_Load : function()
			{
				var oDiv,szWidth,szHeight;
				
				// Mutex
				while(this._bMutex);
				this._bMutex = true;
				
				// Save the current context and hide the current form
				if (this._tStack.length > 1)
				{
					// Save the size
					szWidth  = $('#ct_form img.ct_borders_bc')[0].style.width;
					szheight = $('#ct_form img.ct_borders_mr')[0].style.height;
					this._tStack[this._iCurrent].Window.Size.Width  = parseInt(szWidth.substr(0,szWidth.length - 2));
					this._tStack[this._iCurrent].Window.Size.Height = parseInt(szheight.substr(0,szheight.length - 2));
					
					// Hide the current content
					$("#ct_form_content_" + this._iCurrent).style.display = "none";
				}
				
				// Load the new context
				this._iCurrent = this._tStack.length - 1;
				
				// Clean the div
				oDiv = $('#ct_form_content_' + this._iCurrent);
				Object.clean(oDiv);
				
				// Load the form
				ct.ajax.JSONPost(	this._tStack[this._iCurrent].Url,
									this._tStack[this._iCurrent].Params,
									(function(parFormSource)
									{
										// Display the page into the div
										var oDiv = $("#ct_form_content_" + this._iCurrent);
										_ct_div_DisplayPage(oDiv,parFormSource);
										oDiv.style.display = "block";
										
										// Mutex
										this._bMutex = false;
										
										// Show the form
										ct.dlg.Show("ct_form");
										
									}).bind(this),
									"",
									(function(szErrorNumber)
									{
										var fnErrorHandler = this._tStack[this._iCurrent].ErrorHandler;
										
										// Mutex
										this._bMutex = false;
										
										// Unload
										this._Unload(0);
										
										// Error handler
										if (fnErrorHandler)
											fnErrorHandler(szErrorNumber);
									}).bind(this));
				
			},
			
			_Unload : function(parCallBack1_or_2,parJSONData)
			{
				var oCallBackFn, oCallBackParam, oDiv;
				
				if (this._tStack.length == 0)	return;
				
				// Mutex
				while(this._bMutex);
				this._bMutex = true;
				
				// Free this div
				oDiv 				= $("#ct_form_content_" + this._iCurrent);
				oDiv.style.display 	= "none";
				oDiv.style.width	= "";
				oDiv.style.height	= "";
				Object.clean(oDiv);
				
				// Get all information required
				oCallBackFn			= undefined;
				if (parCallBack1_or_2 == 1)	oCallBackFn	= this._tStack[this._iCurrent].CallBackFn1;
				if (parCallBack1_or_2 == 2)	oCallBackFn	= this._tStack[this._iCurrent].CallBackFn2;
				oCallBackParam 		= this._tStack[this._iCurrent].CallBackParam;
				
				// Pop the div
				this._tStack.splice(this._iCurrent,1);
				this._iCurrent 	= this._tStack.length - 1;
				
				// Show the next form
				if (this._tStack.length == 0)
				{		
					// Hide the form
					ct.dlg.Hide("ct_form");
				}
				else
				{
					// Stack the next one
					this.Resize(this._tStack[this._iCurrent].Window.Size.Width,this._tStack[this._iCurrent].Window.Size.Height);
					$("#ct_form_content_" + this._iCurrent).style.display = "block";
				}
				
				// Mutex
				this._bMutex = false;
				
				// Call the ok callback
				if (oCallBackFn != undefined && oCallBackFn != "")
					oCallBackFn(parJSONData,oCallBackParam);
			},
			PostResCb1 : function(parJSONData){ct.dlg.form._Unload(1,parJSONData);},
			PostResCb2 : function(parJSONData){ct.dlg.form._Unload(2,parJSONData);},
			
			Resize : function(parWidth,parHeight)
			{
				var oForm,oDiv, jWindowSize = ct.window.size.Get();
				oForm = $('#ct_form');
				oDiv  = $('#ct_form_content_' + this._iCurrent);
				
				if (/%/.test(parWidth))	parWidth  = Math.round(jWindowSize.Window.Width * parseInt(parWidth.substr(0,parWidth.length -1)) / 100);
				if (/%/.test(parHeight))parHeight = Math.round(jWindowSize.Window.Height * parseInt(parHeight.substr(0,parHeight.length -1)) / 100);
				parWidth = parseInt(parWidth);
				parHeight = parseInt(parHeight);
				
				// Resize workspace
				oForm.style.width 		= (parWidth + 40) + "px";
				oForm.style.height 		= (parHeight + 20)  + "px";
				oForm.style.marginLeft 	= -((parWidth + 40) / 2) + "px";
				
				// Resize workspace content
				oDiv.style.width 		= parWidth + "px";
				oDiv.style.height 		= parHeight + "px";
				
				// Resize workspace borders
				$('#ct_form img.ct_borders_ml')[0].style.height = parHeight + "px";
				$('#ct_form img.ct_borders_mr')[0].style.height = parHeight + "px";
				$('#ct_form img.ct_borders_bc')[0].style.width 	= parWidth + "px";
			}
		}
	}
	

};

// Automatically register handlers
ct.event.Add(document,"mousemove",	ct.menu._MouseMove.bind(ct.menu)		,false);
ct.event.Add(document,"mousemove",	ct.tooltip._MouseMove.bind(ct.tooltip)	,false);


_ct_div_DisplayPage = function(oTarget,parContent,hWindow)
{
	if (!hWindow)
	{
		hWindow 	= window;
		hDocument 	= document;
	}
	else
	{
		hWindow 	= hWindow;
		hDocument	= hWindow.document;
	}
	
	// Clean target
	Object.clean(oTarget);
	oTarget.innerHTML = parContent;
	oTarget.style.display = "block";
	
	//Find all scripts and concat them
	szFullScript = "";
	szFullStyle = "";
	Object.forEach(parContent.extractTags("script"),function(szScript){szFullScript += szScript;});
	Object.forEach(parContent.extractTags("style"),function(szStyle){szFullStyle += szStyle;});
	
	// First load the CSS
	var oStyle = hDocument.createElement('STYLE');
	oStyle.setAttribute("type","text/css");
	oTarget.appendChild(oStyle);
	if(oStyle.styleSheet) // IE
	{
		oStyle.styleSheet.cssText = szFullStyle;
	}
	else // w3c
	{
		var cssText = hDocument.createTextNode(szFullStyle);
		oStyle.appendChild(cssText);
	}
	
    // Finaly load the script
    var oScript = hDocument.createElement('SCRIPT');
    oScript.setAttribute("type","text/javascript");
	oScript.text = szFullScript;
	oTarget.appendChild(oScript);
}

ct_div_LoadPage = function(oTarget,parUrl,parJSONData,parCallBackFn,parCallBackParams,parErrorsHandler,hWindow)
{
	// Call the ajax get to load the div
	ct.ajax.JSONPost(	parUrl,
						parJSONData,
						ct_div_LoadPage_1,
						{"Target":oTarget,"Window":hWindow,"CallBackFn":parCallBackFn,"CallBackParams":parCallBackParams},
						parErrorsHandler);
}

ct_div_LoadPage_1 		= function(parResponse,parUserData)
{
	// Display page
    _ct_div_DisplayPage(parUserData.Target,parResponse,parUserData.hWindow);
    
    // Call callback
    if (parUserData.CallBackFn != undefined)
    {
    	parUserData.CallBackFn(parResponse,parUserData.CallBackParams);
   	}
}

