﻿/*________________________________________________________________
 *                                                                
 * s@rdalya - s@rm@l Dynamic Framework                            
 *                                                                
 * Author      :                                                  
 *     Volkan Ozcelik (volkan@sarmal.com)                         
 *                                                                
 * Copyright   :                                                  
 *     2003 © sarmal.com                                          
 *                                                                
 * About       :                                                  
 *     s@rdalya, is a cross-browser compatible system which is    
 *     designed to work in all DOM-supporting browsers.           
 *     s@rdalya has been tested with internet explorer 6,         
 *     netscape navigator 6-7-8beta, Firefox 1.5.x.x-Mozilla 1.x.x
 *     Opera 7.0-7.2-8Beta-9 and more.                            
 *                                                                
 *     At the beginning, s@rdalya started his life as a small API,
 *     mostly driven by the dynamic html programming and scripting
 *     needs of author's projects.                                
 *                                                                
 *     Nevertheless, today, it can stand on its own feet and may  
 *     be useful to others. So here it goes.                      
 *                                                                
 *     Version  : see Sardalya.version below                      
 *     Platform : linux, windows, freebsd, osx, sun               
 *     Size     : 38Kb (compressed production release)            
 *     Price    : Free for uncommercial use -                     
 *                almost free for commercial use --               
 *                see http://www.sarmal.com/sardalya/ for         
 *                licensing details                               
 *                                                                
 * Terms of use:                                                  
 *     This file (s@rdalya API) is distributed under CC license.  
 *                                                                
 *     See http://www.sarmal.com/sardalya/Terms.aspx              
 *     for terms of use.                                          
 *________________________________________________________________
 *                                                                
 * Do you have bug reports, feature requests, wishlists?          
 * Or do you simply want to collaborate?                          
 * Then join us at s@rdalya wiki:                                 
 *                                                                
 *             http://sardalya.pbwiki.com/                        
 *                                                                
 * Do you want to see recent buzzes about s@rdalya?               
 * Then have a look at s@rdalya blog:                             
 *                                                                
 *             http://www.sarmal.com/sardalya/blog/               
 *                                                                
 * Do not forget to visit http://www.sarmal.com/sardalya/ for the 
 * most up-to-date version of the API.                            
 * _______________________________________________________________
 *                                                                
 * Please do not remove this informative header.                  
 * If you find s@rdalya useful, why not help others?              
 * _______________________________________________________________
 */

/*
 * define external objects for JSLint verification
 * (see http://www.jslint.com/ for details)
 *
 * Thank you Douglas Crockford, a billion times.
 * JSLint has saved hours of debugging and it has revealed
 * tiny little bugs that were around for years but I was not
 * aware of.
 *
 */

/*extern ActiveXObject, Image, XMLHttpRequest */

var _this=null;

/** Sardalya ------------------------------------------------------ **/

var Sardalya=
{
	name:"Sardalya",
	version:"2.2.4",
	build:"20060718",
	archive:"s@rdalya-s2,2,4@2006,07,18.zip"
};

/** shortcuts ----------------------------------------------------- **/

var _=
{
	/* AJAX related */
	ajax:function()
	{
		return this.xhr();
	},
	xhr:function()
	{
		return new XHRequest();
	},

	/* DOM related */
	o:function(e)
	{
		return new CBObject(e).getObject();
	},
	id:function(e)
	{
		return new CBObject(e).getID();
	},
	gcn:function(s)
	{
		return DOMManager.getElementsByClassName(s);
	},
	gid:function(s)
	{
		return document.getElementById(s);
	},
	gtn:function(s)
	{
		return document.getElementsByTagName(s);
	},
	elm:function(x)
	{
		return document.createElement(x);
	},
	sweep:function(e)
	{
		return DOMManager.sweep(e);
	},
	load:function(d)
	{
		DOMManager.quickLoad(d);
	},

	/* DOM query */
	child:function(o,p)
	{
		return DOMManager.isChild(o,p);
	},

	/* DOM CSS */
	getclass:function(e)
	{
		return StyleManager.getClass(e);
	},
	setclass:function(e,c)
	{
		StyleManager.setClass(e,c);
	},
	getstyle:function(o,s)
	{
		return StyleManager.getStyle(o,s);
	},
	setstyle:function(o,s,v)
	{
		return StyleManager.setStyle(o,s,v);
	},
	addclass:function(o,a)
	{
		StyleManager.addClass(o,a);
	},
	remclass:function(o,a)
	{
		StyleManager.removeClass(o,a);
	},
	hasclass:function(o,s)
	{
		return StyleManager.hasClassName(o,s);
	},

	/* Custom DOM Objects */
	l:function(x)
	{
		return new LayerObject(x);
	},
	dl:function(e,c1,c2,b)
	{
		return new DraggableLayer(e,c1,c2,b);
	},
	dyl:function(e)
	{
		return new DynamicLayer(e);
	},
	tip:function(e,i1,i2,l,t)
	{
		return new ToolTip(e,i1,i2,l,t);
	},
	ib:function(e,s1,s2,i)
	{
		return new ImageButton(e,s1,s2,i);
	},
	ir:function(e,s1,s2)
	{
		return new ImageRollover(e,s1,s2);
	},
	wo:function()
	{
		return WindowObject;
	},

	/* Validators */
	ajaxdom:function()
	{
		return Validator.isDOMEnabled()&&Validator.isAjaxEnabled();
	},
	integer:function(o)
	{
		return Validator.isInteger(o);
	},
	numeric:function(o)
	{
		return Validator.isNumeric(o);
	},
	positive:function(o)
	{
		return Validator.isPositive(o);
	},
	whitespace:function(o)
	{
		return Validator.isWhiteSpace(o);
	},
	string:function(o)
	{
		return Validator.isString(o);
	},
	defined:function(o)
	{
		return Validator.isDefined(o);
	},
	formelm:function(o)
	{
		return FormManager.isFormElement(o);
	},
	email:function(o)
	{
		return Validator.isEmail(o);
	},
	url:function(o)
	{
		return Validator.isValidURL(o);
	},

	/* Format text */
	safehtml:function(v)
	{
		return TextFormatter.safeHTML(v);
	},
	safews:function(v)
	{
		return TextFormatter.safeWhiteSpace(v);
	},
	qry:function(s)
	{
		return TextFormatter.splitQueryString(s);
	},

	/* All I want is cookies */
	scook:function(t,v,i)
	{
		return CookieManager.set(t,v,i);
	},
	gcook:function(s)
	{
		return CookieManager.get(s);
	},

	/* Event management */
	evto:function(e)
	{
		return new EventObject(e);
	},
	oevt:function(e)
	{
		return ((e&&e.getObject)?e.getObject():
			new EventObject(e).getObject());
	},
	stop:function(e)
	{
		return ((e&&e.cancelDefaultAction)?e.cancelDefaultAction():
			new EventObject(e).cancelDefaultAction());
	},
	src:function(e,_b)
	{
		return ((e&&e.getSource)?e.getSource(_b):
			new EventObject(e).getSource(_b));
	},
	chain:function(a,b,c,d)
	{
		EventHandler.addEventListener(a,b,c,d);
	},
	unchain:function(a,b,c,d)
	{
		EventHandler.removeEventListener(a,b,c,d);
	},

	/* Form related */
	preparefields:function()
	{
		FormManager.prepareFormField();
	},
	field:function(e,s1,s2,s3)
	{
		return new FormField(e,s1,s2,s3);
	},

	/* Dimensional */
	dim:function(x,y)
	{
		return new Dimension(x,y);
	},
	cns:function(x,y,z,t)
	{
		return new Constraint(x,y,z,t);
	},
	coord:function()
	{
		return CursorTracker.getCursorPosition();
	},

	/* Dummy */
	nill:function()
	{
		return Constant.NULL;
	},

	/*private*/
	_processParam:function(o,objParam)
	{
		if(objParam)
		{
			if(objParam.href)
			{
				o.href=objParam.href;
			}
			
			if(objParam.className)
			{
				o.className=objParam.className;
			}
		}
	},
	
	/*private*/
	_processArDOM:function(o,arDOM)
	{
		if(typeof(arDOM)!="object")
		{
			arDOM=[arDOM];
		}
		var len=arDOM.length,
			obj=null;
		for(var i=0;i<len;i++)
		{
			obj=arDOM[i];
			
			o.appendChild(
				typeof(obj)=="string"?document.createTextNode(obj):
				obj);
		}
	},

	/*private*/
	_process:function(o,arDOM,objParam)
	{
		this._processParam(o,objParam);
		this._processArDOM(o,arDOM);
		return o;
	},

	/* DOM node creation */
	GLUE:function()
	{
		var objParent=_.o(arguments[0]),
			obj=null,
			len=arguments.length;
		
		for(var i=1;i<len;i++)
		{
			obj=arguments[i];
	
			if(typeof(obj)=="string")
			{
				obj=document.createTextNode(obj);
			}
			
			objParent.appendChild(obj);
		}
	},
	e:function(strElem,arDOM,objParam)
	{
		if(strElem=="br")
		{
			return document.createElement("br");
		}
		
		if(strElem=="hr")
		{
			return document.createElement("hr");
		}

		return this._process(document.createElement(strElem),
			arDOM,objParam);
	}
};

/** Constant ------------------------------------------------------ **/

var Constant=
{
	Format:
	{
		NUMERIC:1,
		INTEGER:2,
		MOBILE:3,
		EMAIL:4
	},
	Mouse:
	{
		DRAG:0,
		RESIZE:1,
		DOWN:3
	},
	Key:
	{
		ENTER:13,
		BACKSPACE:8,
		TAB:9,
		ESCAPE:27,
		DELETE:46,
		UP:38,
		RIGHT:39,
		DOWN:40,
		LEFT:37,
		ANYKEY:-2,
		CTRL:17,
		ALT:18
	},
	NodeType:
	{
		TEXT:3
	},
	Orientation:
	{
		HORIZONTAL:1,
		VERTICAL:2,
		BOTH:3
	},
	NOT_INITED:-1,
	NULL:function()
	{
	}
};

/** AjaxController ------------------------------------------------ **/

function _AjaxController()
{
	this._intRequestCount=0;
}

_this=_AjaxController.prototype;

_this.incrementCount=function()
{
	this._intRequestCount++;
};

_this.decrementCount=function()
{
	this._intRequestCount--;
};

_this.getActiveThreadCount=function()
{
	return this._intRequestCount;
};

var AjaxController=new _AjaxController();

/** TextFormatter ------------------------------------------------- **/

function _TextFormatter()
{
}

_this=_TextFormatter.prototype;

_this.escape=function(strText)
{
	return encodeURIComponent(strText);
};

_this.safeHTML=function(strSource)
{
	var div = document.createElement('div');
	div.appendChild(document.createTextNode(strSource));
	return div.innerHTML;
};

_this.safeWhiteSpace=function(strSource)
{
	return strSource.trim();
};

_this.splitQueryString=function(strURL)
{
	var strQuery=strURL.match(/^\??(.*)$/)[1],
		tokens=strQuery.split("&"),
		len=tokens.length,
		i=0,
		parts=null,
		result=[];

	for(i=0;i<len;i++)
	{
		parts=tokens[i].split("=");
		result[parts[0]]=parts[1];
	}

	return result;
};

var TextFormatter=new _TextFormatter();

/** XHRequest ----------------------------------------------------- **/

function XHRequest()
{
	this._fields=[];
	this._values=[];
	this._initialized=false;
	this.init();
	this._incremented=false;/* to prevent a race condition while 
	                           incrementing counter.*/
}

_this=XHRequest.prototype;

_this.removeAllFields=function()
{
	this._fields.length=0;
	this._values.length=0;
};

_this.addField=function(strField,strValue)
{
	this._fields.push(strField);
	this._values.push(TextFormatter.escape(strValue));
};

_this.post=function(strURL,_blnSync)
{
	if(!this._xhr)
	{
		return;
	}

	if(!_blnSync)
	{
		_blnSync=false;
	}

	var uq=this._generateURL(strURL);

	this._xhr.open("POST",uq.url,!_blnSync);
	this._setRequestHeaders();
	this._xhr.setRequestHeader("Content-Type",
		"application/x-www-form-urlencoded");
	this._xhr.send(""+uq.query/*null -- Opera does not like null.*/);

	this._postProcess(_blnSync);
};

_this.postSynchronized=function(strURL)
{
	this.post(strURL,true);
};

_this.get=function(strURL,_blnSync)
{
	if(!this._xhr)
	{
		return null;
	}

	if(!_blnSync)
	{
		_blnSync=false;
	}

	var uq=this._generateURL(strURL);

	this._xhr.open("GET",uq.url+"&"+uq.query,!_blnSync);

	this._setRequestHeaders();
	this._xhr.send("");

	this._postProcess(_blnSync);
};

_this._postProcess=function(blnSync)
{
	if(blnSync)
	{
		/*
		 * note that 99.99% of the time you'll make async requests
		 * so this method will not be executed at all.
		 */
		this._processAsyncRequest();
	}
	else
	{
		if(!this._incremented)
		{
			/*
			 * Theoretically if two threads enter here at the same time
			 * (with millisecond precision) there will be a race condition.
			 * However JavaScript is not Java. And there is no way to 
			 * prevent this. 
			 * On the other hand this chance is so small that we can
			 * neglect it for all practical purposes.
			 */
			this._incremented=true;
			AjaxController.incrementCount();
		}
	}
};

_this._processAsyncRequest=function()
{
	var obj=this._xhr;

	if(obj.status==200||obj.status==304)
	{
		this.oncomplete(obj.responseText,obj.responseXML);
	}
	else
	{
		this.onerror(obj.status,obj.statusText);
	}

	this._cleanup();
};

_this.getSynchronized=function(strURL)
{
	this.get(strURL,true);
};

_this.getObject=function()
{
	var request=null,
		arProgID=null;

	if(this._xhr)
	{
		request=this._xhr;
	}
	else if(window.XMLHttpRequest)
	{
		request=new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		try
		{
			request=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(othermicrosoft)
		{
			try
			{
				request=new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (failed)
			{
				arProgID=[
					"Msxml2.XMLHTTP.7.0",
					"Msxml2.XMLHTTP.6.0",
					"Msxml2.XMLHTTP.5.0",
					"Msxml2.XMLHTTP.4.0",
					"MSXML2.XMLHTTP.3.0"];

				for(var i=0;i<arProgID.length;i++)
				{
					try
					{
						request=new ActiveXObject(arProgID[i]);
						break;
					}
					catch(ignore)
					{
					}
				}
			}
		}
	}

	return request;
};

_this.finalize=function()
{
	if(!this._xhr)
	{
		return;
	}

	/* free the object from circular references. */
	this._cleanup();

	/* 
	 * Note that the line below does not erase
	 * the XmlHttpRequest object from the memory.
	 * It only marks the reference, which 
	 * the member variance _xhr points to, to null.
	 * Since object references are passed by value
	 * the class only loses its handle to the 
	 * formerly-created XmlHttpRequest object.
	 * (google: pass byval, pass byref for details)
	 */
	this._xhr=null;
};

_this.init=function()
{
	var sourceElement=this,
		cleanme=null;

	/* 
	 * Create a brand new XHR instance.
	 */
	this._xhr=this.getObject();

	if(!this._xhr)
	{
		return;
	}

	/* 
	 * abort former request, if any. 
	 * This is necessary to re-use the object
	 * because IE6 and below are not that 
	 * clever to understand that a 
	 * new request is initiating.
	 */
	this.abort();

	if(!this._initialized)
	{
		/*
		 * We cannot add onreadystatechange event
		 * to the EventRegistry using EventHandler.addEventListener.
		 * Thus we need a special cleanup process to take care
		 * of circular references.
		 * If for some reason this._xhr still remains in the memory
		 * it will cause a slight leak. 
		 * This method takes care of it.
		 */
		cleanme=function(evt)
		{
			/* finalize the sourceelement */
			sourceElement.finalize();
			
			/* detach cleanup event. */
			_.unchain(window,"unload",cleanme);

			/* Remove the final remaining references */

			/* defensive coding. */
			cleanme=null;
			sourceElement=null;
		};
		
		_.chain(window,"unload",cleanme,true);
	}

	this._xhr.onreadystatechange=function()
	{
		var obj=sourceElement.getObject();

		if(obj.readyState==4)
		{		
			/*now that the request is completed*/
			if(sourceElement._incremented)
			{
				AjaxController.decrementCount();
				/* +1 -> 0           */
				/* post() -> still 0 */

				/*
				 * don't increment activeThreadCount
				 * before the above decrement operation.
				 * see wiki documentation for details.
				 */
				sourceElement._incremented=false;
			}

			/*
			 * 404: file not found.
			 * 200: OK.
			 * 304: reading from cache.
			 */
			if(obj.status==200||obj.status==304)
			{
				sourceElement.oncomplete(obj.responseText,obj.responseXML);
			}
			else
			{
				sourceElement.onerror(obj.status,obj.statusText);
			}

			/*to prevent IE memory leak due to circular COM referencing.*/
			sourceElement._cleanup();
		}
	};
	
	this._initialized=true;
};

_this._setRequestHeaders=function()
{
	this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
	this._xhr.setRequestHeader("X-Sardalya-Version",Sardalya.version);
	this._xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
	this._xhr.setRequestHeader("Accept",
		"text/javascript, text/html, application/xml, text/xml, */*");
};

_this.abort=function()
{
	if(this._xhr)
	{
		/*
		 * If the request is in progress.
		 * decrement the active thread count.
		 */
		if(this._xhr.readyState!=0 && this._xhr.readyState!=4 && 
			this._incremented)
		{
			AjaxController.decrementCount();
			this._incremented=false;
		}

		/* 
		 * Clear the readystatechange event handler before calling abort.
		 * IE and mozilla fires onreadystatechange when abort is called.
		 * If not handled, this may cause weird consequences.
		 */
		this._cleanup();

		/* 
		 * Theoretically there is no need to abort the request 
		 * if it's not in progress. However IE6 and below 
		 * will not trigger a new request if we do not call abort().
		 */
		this._xhr.abort();
	}
};

_this.oncomplete=function(strResponseText,objResponseXML)
{
	alert("Completed everything.");
};

_this.onerror=function(intStatus,strStatusText)
{
	alert("An error occured but my owner is too lazy to handle it.");
};

_this._cleanup=function()
{
	/* release circular reference to solve the memory leak proble in IE. */
	this._xhr.onreadystatechange=_.nill();
};

_this._generateURL=function(strURL)
{
	var len=this._fields.length,
		i=0,
		append="";
	
	if(len>0)
	{
		for(i=0;i<len;i++)
		{
			append+="&"+this._fields[i]+"="+this._values[i];
		}
	}

	if(append==="")
	{
		append="&";
	}

	return {url:(strURL+"?rnd="+Math.random()),query:append.substring(1)};
};

/** RGBObject ----------------------------------------------------- **/

function RGBObject(strHex)
{
	var regRGB=/rgb\((\d*),\s*(\d*),\s*(\d*)\s*\)/;

	this._hexValue=strHex.remove("#");

	if(this._hexValue.match(regRGB))
	{
		this._r=parseInt(strHex.match(regRGB)[1],10);
		this._g=parseInt(strHex.match(regRGB)[2],10);
		this._b=parseInt(strHex.match(regRGB)[3],10);
	}
	else
	{
		this._r=this._toR(this._hexValue);
		this._g=this._toG(this._hexValue);
		this._b=this._toB(this._hexValue);
	}
}

_this=RGBObject.prototype;

_this._toR=function(strHex)
{
	return parseInt(strHex.substring(0,2),16);
};

_this._toG=function(strHex)
{
	return parseInt(strHex.substring(2,4),16);
};

_this._toB=function(strHex)
{
	return parseInt(strHex.substring(4,6),16);
};

_this.R=function()
{
	return this._r;
};

_this.G=function()
{
	return this._g;
};

_this.B=function()
{
	return this._b;
};

_this.toString=function()
{
	return "rgb("+this._r+","+this._g+","+this._b+")";
};

_this.toArray=function()
{
	return [
		this.R(),
		this.G(),
		this.B()
	];
};

/** Dimension ----------------------------------------------------- **/

function Dimension(x,y)
{
	this._x=x;

	this._y=y;
}

_this=Dimension.prototype;

_this.getX=function()
{
	return this._x;
};

_this.setX=function(x)
{
	this._x=x;
};

_this.getY=function()
{
	return this._y;
};

_this.setY=function(y)
{
	this._y=y;
};

_this.setAll=function(objDimension)
{
	this.setX(objDimension.getX());
	this.setY(objDimension.getY());
};

_this.equals=function(anotherDimension)
{
	return this.getX()==anotherDimension.getX()&&
		this.getY()==anotherDimension.getY();
};

_this.toString=function()
{
	return "("+this.getX()+","+this.getY()+")";
};

/** Constraint ---------------------------------------------------- **/

function Constraint(intMinLower,intMinUpper,intMaxLower,intMaxUpper)
{
	this._lowerBound=_.dim(intMinLower,intMinUpper);
	this._upperBound=_.dim(intMaxLower,intMaxUpper);
}

_this=Constraint.prototype;

_this.getUpperBound=function()
{
	return this._upperBound;
};

_this.getLowerBound=function()
{
	return this._lowerBound;
};

/** Validator ----------------------------------------------------- **/

function _Validator()
{
}

_this=_Validator.prototype;

_this.isDefined=function(x)
{
	return typeof(x)!="undefined";
};

_this.isNull=function(x)
{
	return !this.isDefined(x)?false:null;
};

_this.isEmpty=function(x)
{
	return (!this.isDefined(x)||this.isNumeric(x))?false:(x==="");
};

_this.isEmail=function(x)
{
	return this.isDefined(x)?
		(/^[A-Za-z0-9]+([_\.-][A-Za-z0-9]+)*@[A-Za-z0-9]+([_\.-][A-Za-z0-9]+)*\.([A-Za-z]){2,4}$/i).test(x):
		false;
};

_this.isValidURL=function(x)
{
	return this.isDefined(x)?
		(/^(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]$/i).test(x):
		false;
};

_this.isWhiteSpace=function(x)
{
	return this.isDefined(x)?(/^\s*$/).test(x):false;
};

_this.isInteger=function(x)
{
	if(!this.isDefined(x))
	{
		return false;
	}

	x=(""+x).replace(/\.0*$/g,"");

	var intNumber=parseInt(x,10);

	if(!isNaN(intNumber)&&(x=x.remove(/^0*/))==="")
	{
		x=0;
	}

	intNumber=parseInt(x,10);

	if((!isNaN(intNumber))&&((""+intNumber)==x))
	{
		return true;
	}

	return false;
};

_this.isFloat=function(x)
{
	if(!this.isDefined(x))
	{
		return false;
	}

	x=(""+x).replace(/,/g,".");

	return x!==""&&!isNaN(x);
};

_this.isNumeric=function(x)
{
	return this.isFloat(x);
};

_this.isString=function(x)
{
	if(!this.isDefined(x))
	{
		return false;
	}

	return typeof(x)=="string";
};

_this.isDate=function(intYear,intMonth,intDay)
{
	var arMonth=[31,28,31,30,31,30,31,31,30,31,30,31];
	var intMaxDay=0;

	if(!this.isDefined(intYear)||!this.isDefined(intMonth)||
		!this.isDefined(intDay)||this.isEmpty(intYear)||
		this.isEmpty(intMonth)||this.isEmpty(intDay))
	{
		return false;
	}

	arMonth[1]=((parseInt(intYear,10)%4===0&&
		parseInt(intYear,10)%100!==0)||parseInt(intYear,10)%400===0)?29:28;

	intMaxDay=arMonth[parseInt(intMonth,10)-1];

	if(parseInt(intDay,10)>intMaxDay)
	{
		return false;
	}

	return true;
};

_this.isPositive=function(x)
{
	if(!this.isNumeric(x))
	{
		return false;
	}

	return parseFloat(x)>=0;
};

_this.isPositiveStrict=function(x)
{
	if(!this.isNumeric(x))
	{
		return false;
	}

	return parseFloat(x)>0;
};

_this.isNegative=function(x)
{
	if(!this.isNumeric(x))
	{
		return false;
	}

	return parseFloat(x)<=0;
};

_this.isNegativeStrict=function(x)
{
	if(!this.isNumeric(x))
	{
		return false;
	}

	return parseFloat(x)<0;
};

_this.validateMarkup=function(strLocation)
{
	if(!strLocation)
	{
		strLocation=window.location.href;
	}

	window.open("http://validator.w3.org/check?uri="+
		TextFormatter.escape(strLocation));
};

_this.validateCSS=function(strLocation)
{
	if(!strLocation)
	{
		strLocation=window.location.href;
	}

	window.open("http://jigsaw.w3.org/css-validator/validator?uri="+
		TextFormatter.escape(strLocation));
};

_this.isDOMEnabled=function()
{
	if(document.getElementById&&document.getElementsByTagName)
	{
		return true;
	}

	return false;
};

_this.isAjaxEnabled=function()
{
	var ajax=_.ajax();

	if(ajax.getObject())
	{
		ajax.abort();
		return true;
	}

	return false;
};

var Validator=new _Validator();

/** Array --------------------------------------------------------- **/

_this=Array.prototype;

_this.indexOf=function(elm)
{
	for(var i=0;i<this.length;i++)
	{
		if(elm==this[i])
		{
			return i;
		}
	}

	return -1;
};

_this.contains=function(elm)
{
	return this.indexOf(elm)!=-1;
};

_this.copy=function()
{
	var theCopy = [],
		index=this.length;

	while(index--)
	{
		theCopy[index]=(_.defined(this[index].copy))?
			this[index].copy():
			this[index];
	}

	return theCopy;
};

_this.clear=function()
{
	this.length=0;
	return this;
};

_this.first=function()
{
	return this[0];
};

_this.last=function()
{
	return this[this.length - 1];
};

_this.compact=function()
{
	var result=[],
		len=this.length,
		i=0,
		obj=null;

	for(i=0;i<len;i++)
	{
		obj=this[i];

		if(obj!==null&&typeof(obj)!="undefined")
		{
			if(obj.compact)
			{
				obj.compact();
			}

			result.push(obj);
		}
	}

	this.clear();

	len=result.length;

	for(i=0;i<len;i++)
	{
		this.push(result[i]);
	}
};

/** SortHelper ---------------------------------------------------- **/

function _SortHelper()
{
}

_this=_SortHelper.prototype;

_this.genericSort=function(a,b)
{
	if(isNaN(a)&&isNaN(b))
	{
		if(a<b)
		{
			return -1;
		}
		else if(a>b)
		{
			return 1;
		}

		return 0;
	}

	return (isNaN(a)?Number.POSITIVE_INFINITY:a)-(isNaN(b)?
		Number.POSITIVE_INFINITY:b);
};

_this.genericSortDesc=function(a,b)
{
	if(isNaN(a)&&isNaN(b))
	{
		if(a<b)
		{
			return 1;
		}
		else if(a>b)
		{
			return -1;
		}

		return 0;
	}

	return (isNaN(b)?Number.NEGATIVE_INFINITY:b)-(isNaN(a)?
		Number.NEGATIVE_INFINITY:a);
};

var SortHelper=new _SortHelper();

/** String -------------------------------------------------------- **/

_this=String.prototype;

_this.trim=function(blnIgnoreCarriage,blnIgnoreInnerWhiteSpace)
{
	var temp=this.replace(/^\s*/,"");
	temp=temp.replace(/\s*$/,"");

	blnIgnoreCarriage=blnIgnoreCarriage?true:false;
	blnIgnoreInnerWhiteSpace=blnIgnoreInnerWhiteSpace?true:false;

	if(blnIgnoreCarriage&&!blnIgnoreInnerWhiteSpace)
	{
		temp=temp.replace(/\t+/g," ");
		temp=temp.replace(/ +/g," ");
	}
	else if(!blnIgnoreCarriage&&blnIgnoreInnerWhiteSpace)
	{
		/* Consider unix formats as well */
		temp=temp.replace(/(\r\n|\n\r|\n|\r)+/g,"");
	}
	else if(!blnIgnoreCarriage&&!blnIgnoreInnerWhiteSpace)
	{
		temp=temp.replace(/\s+/g," ");
	}

	/* if only one single whitespace left remove it. */
	if(temp==" ")
	{
		temp="";
	}

	return temp;
};

_this.removeExcess=function(intLen,strPostFix)
{
	if(!_.defined(intLen)||!intLen)
	{
		intLen=50;
	}

	if(!_.defined(strPostFix)||!strPostFix)
	{
		strPostFix="...";
	}

	if(this.length>=intLen)
	{
		return this.substring(0,intLen)+strPostFix;
	}

	return this;
};

_this.remove=function(varRegExp,strOption)
{
	return this.replace(
		_.string(varRegExp)?
		new RegExp(varRegExp,strOption?strOption:"g"):
		varRegExp,
	"");
};

_this.removeTags=function()
{
	return this.replace(/<[\/]?([a-zA-Z0-9]+)[^>^<]*>/ig,"");
};

_this.toCamelCase=function()
{
	var arList = this.split("-"),
		strResult="",
		len=0,
		i=0;

	if(arList.length==1)
	{
		return arList[0];
	}

	if(this.indexOf("-")===0)
	{
		strResult=arList[0].charAt(0).toUpperCase()+arList[0].substring(1);
	}
	else
	{
		strResult=arList[0];
	}

	len=arList.length;

	for (i=1;i<len;i++)
	{
		strResult+=arList[i].charAt(0).toUpperCase()+arList[i].substring(1);
	}

	return strResult;
};

/** DataFormatter ------------------------------------------------- **/

function _DataFormatter()
{
}

_this=_DataFormatter.prototype;

_this.format=function(strValue,enumFormat)
{
	switch(enumFormat)
	{
		case Constant.Format.NUMERIC:
			return strValue.remove("[^0-9\\.,-]");
		case Constant.Format.INTEGER:
			return strValue.remove("[^0-9-]");
		case Constant.Format.MOBILE:
			return strValue.remove("[^0-9]");
		case Constant.Format.EMAIL:
			return strValue.remove("[^A-Za-z0-9_\\.-@]").toLowerCase();
		default:
			alert("Format Error at DataFormatter.format @"+enumFormat);
			return strValue;			
	}
};

var DataFormatter=new _DataFormatter();

/** CBObject ------------------------------------------------------ **/

function CBObject(elmID)
{
	this._obj=this._getObject(elmID);
}

_this=CBObject.prototype;

_this.exists=function()
{
	return this.getObject()!==null;
};

_this.getObject=function()
{
	return this._obj;
};

_this.getID=function()
{
	return this.exists()?this.getObject().id:null;
};

_this._getObject=function(elmID)
{
	return _.string(elmID)?_.gid(elmID):elmID;
};

/** Try      ------------------------------------------------------ **/

function _Try()
{
}

_this = _Try.prototype;

_this.all=function()
{
	var i=0,
		len=arguments.length;
	
	for(i=0;i<len;i++)
	{
		try
		{
			arguments[i]();
		}
		catch(ignore)
		{
		}	  
	}
};

_this.these=function()
{
	var i=0,
		len=arguments.length;
	
	for(i=0;i<len;i++)
	{
		try
		{
			arguments[i]();
			return;
		}
		catch(ignore)
		{
		}	  
	}
	
};

var Try = new _Try();

/** DOMLoadController --------------------------------------------- **/

var DOMLoadController=
{
	index:0,
	sanityLimit:50,
	interval:-1,
	retryMilli:256
};

/** DOMManager ---------------------------------------------------- **/

function _DOMManager()
{
}

_this=_DOMManager.prototype;

_this.getOffset=function(elm)
{
	var ol=0,
		ot=0;

	if(!(elm=_.o(elm)))
	{
		return _.dim(-1,-1);
	}

	while(true)
	{
		ol+=elm.offsetLeft;
		ot+=elm.offsetTop;
		elm=elm.offsetParent;
		if(!elm)
		{
			break;
		}
	}

	return _.dim(ol,ot);
};

_this.isChild=function(elmTestNode,elmParentNode)
{
	var objTestNode=_.o(elmTestNode),
		objParentNode=_.o(elmParentNode),
		theNode=objTestNode;

	if(objTestNode==objParentNode)
	{
		return false;
	}

	while(theNode.nodeName.toLowerCase()!="body")
	{
		if(theNode==objParentNode)
		{
			return true;
		}

		if(theNode.parentNode)
		{
			theNode=theNode.parentNode;
		}
		else
		{
			return false;
		}
	}

	return false;
};

_this.sweep=function(obj)
{
	obj=(!obj)?document:_.o(obj);

	var children=obj.childNodes,
		arRemove=[],
		len=children.length,
		i=0;

	for(i=0;i<len;i++)
	{
		if(children[i].nodeType==Constant.NodeType.TEXT&&
			_.whitespace(children[i].nodeValue))
		{
			arRemove.push(children[i]);
		}
	}

	len=arRemove.length;

	for(i=0;i<len;i++)
	{
		arRemove[i].parentNode.removeChild(arRemove[i]);
	}

	len=children.length;

	for(i=0;i<len;i++)
	{
		this.sweep(children[i]);
	}
};

_this.getElementsByClassName=function(strClassName,elmParentNode) 
{
	var children=null,
		i=0;
		result=[];

	
	elmParentNode=(elmParentNode)?_.o(elmParentNode):document.body;

	children=elmParentNode.getElementsByTagName("*");

	for(i=0;i<children.length;i++)
	{
		if(children[i].className.match(new RegExp("(^|\\s)"+
			strClassName+"(\\s|$)")))
		{
			result.push(children[i]);
		}
	}

	return result;
};

_this.removeNode=function(elm)
{
	elm=_.o(elm);
	elm.parentNode.removeChild(elm);
};

_this.registerExternalLink=function()
{
	var arLink=_.gtn("a");

	for(var i=0;i<arLink.length;i++)
	{
		if(arLink[i].className.indexOf("newwin")>-1)
		{
			_.chain(arLink[i],"click",this._ExternalLink_click,true);
		}
	}
};

_this.unregisterExternalLink=function()
{
	for(var i=0;i<arguments.length;i++)
	{
		_.unchain(_.o(arguments[i]),"click",this._ExternalLink_click);
	}
};

_this._ExternalLink_click=function(evt)
{
	var e=_.evto(evt),
		obj=_.src(e);

	if(obj.tagName.toLowerCase()=="img")
	{
		obj=obj.parentNode;
	}

	window.open(obj.href);

	return _.stop(e);
};

_this._executeWhenReady=function(fnDelegate,arID)
{
	DOMLoadController.index++;

	if(typeof document.getElementsByTagName != "undefined" &&
	   (document.getElementsByTagName('body')[0] !== null ||
		document.body !== null))
	{
		if(arID)
		{
			/*
				either a string or an object but not an array.
				TODO: write a Validator.isArray function
			*/
			if(typeof(arID)=="string"||
				arID.constructor.toString().indexOf("Array")==-1)
			{
				arID=[arID];
			}

			var len=arID.length;
			var hasError=false;
			
			for(var i=0;i<len;i++)
			{
				if(!_.o(arID[i]))
				{
					hasError=true;
				}
			}
			
			if(!hasError)
			{
				fnDelegate();
				clearInterval(DOMLoadController.interval);
			}
		}
		else
		{
			fnDelegate();
			clearInterval(DOMLoadController.interval);
		}
	}

	if(DOMLoadController.index >= DOMLoadController.sanityLimit)
	{
		clearInterval(DOMLoadController.interval);
		_.chain(window,"load",fnDelegate);
	}
};

_this.quickLoad=function(fnDelegate,arID)
{
	DOMLoadController.index=0;

	DOMLoadController.interval=setInterval(
		function()
		{
			DOMManager._executeWhenReady(fnDelegate,arID);
		}
	,DOMLoadController.retryMilli);
};

var DOMManager=new _DOMManager();

/** WindowObject -------------------------------------------------- **/

function _WindowObject()
{
}

_this=_WindowObject.prototype;

_this.getInnerDimension=function()
{
	var width=-1,
		height=-1;

	if (self.innerHeight)
	{/*all except ie*/
		width=self.innerWidth;
		height=self.innerHeight;
	}
	else if(document.documentElement&&document.documentElement.clientHeight)
	{/*ie strict*/
		width=document.documentElement.clientWidth;
		height=document.documentElement.clientHeight;
	}
	else if(document.body)
	{/*last trial*/
		width=document.body.clientWidth;
		height=document.body.clientHeight;
	}

	return _.dim(width,height);
};

_this.getScrollOffset=function()
{
	var leftOffset=0,
		topOffset=0;

	if(document.documentElement)
	{
		/*
		 * in some rarely exceptional cases document.body may happen
		 * to be null: ie6 win.
		 * to test; ctrl+r while moving the cursor.
		 * you should be using some combination of
		 * tooltip + draggablelayer etc.
		 */
		if((document.body)&&_.defined(document.body.scrollLeft))
		{
			leftOffset=Math.max(document.body.scrollLeft,
				document.documentElement.scrollLeft);
			topOffset=Math.max(document.body.scrollTop,
				document.documentElement.scrollTop);
		}
		else
		{
			leftOffset=document.documentElement.scrollLeft;
			topOffset=document.documentElement.scrollTop;
		}
	}
	else
	{/*ie quirksmode*/
		leftOffset=document.body.scrollLeft;
		topOffset=document.body.scrollTop;
	}

	return _.dim(leftOffset,topOffset);
};

_this.scrollTo=function(varX,varY)
{
	var dim=_.defined(varY)?_.dim(varX,varY):
		DOMManager.getOffset(_.o(varX));

	window.scrollTo(dim.getX(),dim.getY());
};

var WindowObject=new _WindowObject();

/** CookieManager ------------------------------------------------- **/

function _CookieManager()
{
}

_this=_CookieManager.prototype;

_this.set=function(strName,strValue,intDays)
{
	var strExpires="";
	var dtDate=new Date();

	if(!_.defined(document.cookie))
	{
		return;
	}

	if(intDays)
	{
		dtDate.setTime(dtDate.getTime()+(intDays*24*60*60*1000));
		strExpires="; expires="+dtDate.toGMTString();
	}
	else
	{
		strExpires="";
	}

	document.cookie=strName+"="+strValue+strExpires+"; path=/";
};

_this.get=function(strName)
{
	if(!document.cookie)
	{
		return null;
	}

	var strSeek=strName+"=",
		strCookie="",
		i=0,
		arCookie=document.cookie.split(";");

	for(i=0;i<arCookie.length;i++)
	{
		strCookie=arCookie[i];

		while(strCookie.charAt(0)==" ")
		{
			strCookie=strCookie.substring(1,strCookie.length);
		}

		if(strCookie.indexOf(strSeek)===0)
		{
			return strCookie.substring(strSeek.length, strCookie.length);
		}
	}

	return null;
};

var CookieManager=new _CookieManager();

/** StyleManager -------------------------------------------------- **/

function _StyleManager()
{
}

_this=_StyleManager.prototype;

_this.getStyle=function(elmID,cssPropertyExtended)
{
	var obj=_.o(elmID),
		cssProperty=cssPropertyExtended.toCamelCase();

	if(!this.sanityCheck(obj,cssProperty))
	{
		return null;
	}
	else if(obj.currentStyle)
	{
		return obj.currentStyle[cssProperty];
	}
	else if(window.getComputedStyle)
	{
		return window.getComputedStyle(obj,"").getPropertyValue(
			cssPropertyExtended);
	}
	else if(_.defined(obj.style))
	{
		return obj.style[cssProperty];
	}

	return null;
};

_this.setStyle=function(elmID,cssProperty,value)
{
	var obj=_.o(elmID);

	cssProperty=cssProperty.toCamelCase();

	if(!this.sanityCheck(obj,cssProperty))
	{
		return;
	}

	obj.style[cssProperty]=value;
};

_this.setClass=function(elmID,cssClass)
{
	_.o(elmID).className=cssClass;
};

_this.getClass=function(elmID)
{
	return _.o(elmID).className;
};

_this.addClass=function(obj,arClassName)
{
	var strClassName="",
		i=0;
	
	obj=_.o(obj);

	for(i=0;i<arClassName.length;i++)
	{
		strClassName=arClassName[i];

		if(!this.hasClassName(obj,strClassName))
		{
			obj.className=(obj.className==="")?strClassName:
				(" "+strClassName);
		}
	}
};

_this.removeClass=function(obj,arClassName)
{
	var strClassName="",
		i=0,
		regClassName=null;
		
	obj=_.o(obj);

	for(i=0;i<arClassName.length;i++)
	{
		strClassName=arClassName[i];
		regClassName=new RegExp("(^|\\s)"+strClassName+"(\\s|$)");

		if(this.hasClassName(obj,strClassName))
		{
			obj.className=obj.className.replace(regClassName," ");
		}
	}
};

_this.hasClassName=function(obj,strClassName)
{
	return (new RegExp("(^|\\s)"+strClassName+"(\\s|$)")).test(
		_.o(obj).className);
};

_this.activateAlternateStyleSheet=function(strTitle)
{
	var objLink=null;

	for(var i=0;true;i++)
	{
		if(!_.gtn("link")[i])
		{
			break;
		}

		objLink=_.gtn("link")[i];

		if(objLink.getAttribute("rel").indexOf("style")!=-1&&
			objLink.getAttribute("title"))
		{
			objLink.disabled=true;
		}

		if(objLink.getAttribute("title")==strTitle)
		{
			objLink.disabled=false;
		}
	}
};

_this.remember=function(strTitle,intTimeout)
{
	if(!intTimeout)
	{
		intTimeout=14;
	}

	_.scook("alternateCSS",strTitle,intTimeout);
};

_this.recall=function()
{
	var strTitle=_.gcook("alternateCSS");
	if(strTitle)
	{
		this.activateAlternateStyleSheet(strTitle);
	}
};

_this.sanityCheck=function(obj,cssProperty)
{
	obj=_.o(obj);

	if(!obj)
	{
		return false;
	}

	return typeof(obj.style[cssProperty])!="undefined";
};

var StyleManager=new _StyleManager();

/** Incrementer --------------------------------------------------- **/

function Incrementer(intStart,intEnd,intTotalStep,expFactor)
{
	this._min=intStart;
	this._max=intEnd;
	this._steps=intTotalStep;
	this._currentStep=0;
	this._pow=expFactor;
}

_this=Incrementer.prototype;

_this.next=function()
{
	this._currentStep++;

	if(this._steps>this._currentStep)
	{
		return Math.ceil(this._min+((this._max-this._min)*Math.pow(
			this._currentStep*(1/this._steps),this._pow)));
	}

	return null;
};

/** Effect -------------------------------------------------------- **/

function _Effect()
{
	/*default values*/
	this._step=26;
	this._interval=63;
	this._exp=1.618;
}

_this=_Effect.prototype;

_this.dimensionClip=function(elm,arParams,fncNextEffect)
{
	this.dimensionChange(elm,arParams,fncNextEffect,true,"dimensionClip");
};

_this.dimensionChange=function(elm,arParams,fncNextEffect,
	_blnNoOverFlow,_strEffectName)
{
	var intTotalStep=this._step,
		intIntervalMilli=this._interval,
		expFactor=this._exp,
		dimBeginWH=arParams[0],
		dimEndWH=arParams[1],
		customParams=null,
		len=arParams.length,
		lyrElm=new DynamicLayer(elm),
		wIncrement=null,
		hIncrement=null;

	elm=_.o(elm);

	if(len>2)
	{
		customParams=arParams[2];
		intTotalStep=customParams.step?customParams.step:intTotalStep;
		intIntervalMilli=customParams.interval?
			customParams.interval:intIntervalMilli;
		expFactor=customParams.exp?customParams.exp:expFactor;
	}

	if(!elm.originalWH)
	{
		elm.originalWH=new Dimension(-1,-1);
	}

	if(elm.originalWH.getX()==-1)
	{
		elm.originalWH.setX(lyrElm.getWidth());
		elm.originalWH.setY(lyrElm.getHeight());
	}

	if(!dimEndWH)
	{
		dimBeginWH=new Dimension(-1,-1);
		dimBeginWH.setX(lyrElm.getWidth());
		dimBeginWH.setY(lyrElm.getHeight());
		dimEndWH=elm.originalWH;
	}
	else if(!dimBeginWH)
	{
		dimBeginWH=elm.originalWH;
	}

	wIncrement=new Incrementer(dimBeginWH.getX(),dimEndWH.getX(),
		intTotalStep,expFactor);
	hIncrement=new Incrementer(dimBeginWH.getY(),dimEndWH.getY(),
		intTotalStep,expFactor);

	if(elm._DimensionInterval)
	{
		clearInterval(elm._DimensionInterval);
	}

	if(_strEffectName)
	{
		elm[_strEffectName+"__OK"]=false;
	}
	else
	{
		elm.dimensionChange__OK=false;
	}

	if(_blnNoOverFlow)
	{
		_.setstyle(elm,"overflow","hidden");
	}

	elm._DimensionInterval=setInterval(
		function()
		{
			var w=wIncrement.next(),
				h=hIncrement.next(),
				lyr=new DynamicLayer(elm);

			if(w)
			{
				lyr.setWidth(w);
				lyr.setHeight(h);
			}
			else
			{
				w=dimEndWH.getX();
				h=dimEndWH.getY();

				lyr.setWidth(w);
				lyr.setHeight(h);

				clearInterval(elm._DimensionInterval);

				if(_strEffectName)
				{
					elm[_strEffectName+"__OK"]=true;
				}
				else
				{
					elm.dimensionChange__OK=true;
				}

				if(_.defined(fncNextEffect)&&fncNextEffect)
				{
					fncNextEffect();
				}
			}
		}
	,intIntervalMilli);

};

_this.positionChange=function(elm,arParams,fncNextEffect)
{
	var intTotalStep=this._step,
		intIntervalMilli=this._interval,
		expFactor=this._exp,
		dimBeginTL=arParams[0],
		dimEndTL=arParams[1],
		customParams=null,
		len=arParams.length,
		lyrElm=new DynamicLayer(elm),
		tIncrement=null,
		lIncrement=null;

	elm=_.o(elm);

	if(len>2)
	{
		customParams=arParams[2];
		intTotalStep=customParams.step?customParams.step:intTotalStep;
		intIntervalMilli=customParams.interval?
			customParams.interval:intIntervalMilli;
		expFactor=customParams.exp?customParams.exp:expFactor;
	}

	if(!elm.originalTL)
	{
		elm.originalTL=new Dimension(-1,-1);
	}

	if(elm.originalTL.getX()==-1)
	{
		elm.originalTL.setX(lyrElm.getTop());
		elm.originalTL.setY(lyrElm.getLeft());
	}

	if(!dimEndTL)
	{
		dimBeginTL=new Dimension(-1,-1);
		dimBeginTL.setX(lyrElm.getTop());
		dimBeginTL.setY(lyrElm.getLeft());
		dimEndTL=elm.originalTL;
	}
	else if(!dimBeginTL)
	{
		dimBeginTL=elm.originalTL;
	}
	tIncrement=new Incrementer(dimBeginTL.getX(),dimEndTL.getX(),
		intTotalStep,expFactor);
	lIncrement=new Incrementer(dimBeginTL.getY(),dimEndTL.getY(),
		intTotalStep,expFactor);

	if(elm._MoveInterval)
	{
		clearInterval(elm._MoveInterval);
	}

	elm.positionChange__OK=false;

	elm._MoveInterval=setInterval(
		function()
		{
			var t=tIncrement.next();
			var l=lIncrement.next();
			var lyr=new DynamicLayer(elm);

			if(t)
			{
				lyr.setTop(t);
				lyr.setLeft(l);
			}
			else
			{
				t=dimEndTL.getX();
				l=dimEndTL.getY();

				lyr.setTop(t);
				lyr.setLeft(l);

				clearInterval(elm._MoveInterval);

				elm.positionChange__OK=true;

				if(_.defined(fncNextEffect)&&fncNextEffect)
				{
					fncNextEffect();
				}
			}
		}
	,intIntervalMilli);
};

_this.fontZoom=function(elm,arParams,fncNextEffect)
{
	var intTotalStep=this._step,
		intIntervalMilli=this._interval,
		expFactor=this._exp,
		intBeginPercent=arParams[0],
		intEndPercent=arParams[1],
		customParams=null,
		len=arParams.length,
		pIncrement=null;

	elm=_.o(elm);

	if(len>2)
	{
		customParams=arParams[2];
		intTotalStep=customParams.step?customParams.step:intTotalStep;
		intIntervalMilli=customParams.interval?
			customParams.interval:intIntervalMilli;
		expFactor=customParams.exp?customParams.exp:expFactor;
	}

	if(!elm.originalPercent)
	{
		elm.originalPercent=100;
		elm.originalFontSize=_.getstyle(elm,"font-size");
	}

	if(!intEndPercent)
	{
		intBeginPercent=parseInt(
			100*(parseInt(
				_.getstyle(elm,"font-size"),10)/parseInt(
				elm.originalFontSize,10)),10);

		intEndPercent=100;
	}
	else if(!intBeginPercent)
	{
		intBeginPercent=elm.originalPercent;
	}

	pIncrement=new Incrementer(intBeginPercent,intEndPercent,
			intTotalStep,expFactor);


	if(elm._PercentInterval)
	{
		clearInterval(elm._PercentInterval);
	}

	elm.fontZoom__OK=false;

	elm._PercentInterval=setInterval(
		function()
		{
			var p=pIncrement.next();

			if(p)
			{
				_.setstyle(elm,"font-size",p+"%");
			}
			else
			{
				_.setstyle(elm,"font-size",intEndPercent+"%");

				clearInterval(elm._PercentInterval);

				elm.fontZoom__OK=true;

				if(_.defined(fncNextEffect)&&fncNextEffect)
				{
					fncNextEffect();
				}
			}
		}
	,intIntervalMilli);
};

_this.alphaFade=function(elm,arParams,fncNextEffect)
{
	var intTotalStep=this._step,
		intIntervalMilli=this._interval,
		expFactor=this._exp,
		dblBeginAlpha=arParams[0],
		dblEndAlpha=arParams[1],
		customParams=null,
		len=arParams.length;

	elm=_.o(elm);

	var lyrElm=new DynamicLayer(elm);

	if(len>2)
	{
		customParams=arParams[2];
		intTotalStep=customParams.step?customParams.step:intTotalStep;
		intIntervalMilli=customParams.interval?
			customParams.interval:intIntervalMilli;
		expFactor=customParams.exp?customParams.exp:expFactor;
	}

	if(!elm.originalAlpha)
	{
		elm.originalAlpha=lyrElm.getOpacity();
	}

	if(dblEndAlpha===null)
	{
		dblBeginAlpha=lyrElm.getOpacity();
		dblEndAlpha=elm.originalAlpha;
	}
	else if(dblBeginAlpha===null)
	{
		dblBeginAlpha=elm.originalAlpha;
	}

	var aIncrement=new Incrementer(parseInt(dblBeginAlpha*100,10),
		parseInt(dblEndAlpha*100,10),
		intTotalStep,expFactor);

	if(elm._AlphaInterval)
	{
		clearInterval(elm._AlphaInterval);
	}

	elm.alphaFade__OK=false;

	elm._AlphaInterval=setInterval(
		function()
		{
			var a=aIncrement.next();

			if(a!==null)
			{
				a/=100;
				lyrElm.setOpacity(a);
			}
			else
			{
				lyrElm.setOpacity(dblEndAlpha);
				clearInterval(elm._AlphaInterval);
				elm.alphaFade__OK=true;

				if(_.defined(fncNextEffect)&&fncNextEffect)
				{
					fncNextEffect();
				}
			}
		}
	,intIntervalMilli);
};

_this.colorFade=function(elm,strAttribute,arParams,fncNextEffect)
{
	var arBeginRGB=null,
		arEndRGB=null,
		intTotalStep=this._step,
		intIntervalMilli=this._interval,
		expFactor=this._exp,
		len=arParams.length,
		objBeginRGB=arParams[0],
		objEndRGB=arParams[1],
		customParams=null,
		rIncrement=null,
		gIncrement=null,
		bIncrement=null;

	elm=_.o(elm);

	if(len>2)
	{
		customParams=arParams[2];
		intTotalStep=customParams.step?customParams.step:intTotalStep;
		intIntervalMilli=customParams.interval?
			customParams.interval:intIntervalMilli;
		expFactor=customParams.exp?customParams.exp:expFactor;
	}

	if(typeof(objBeginRGB)=="string")
	{
		arBeginRGB=new RGBObject(objBeginRGB).toArray();
	}
	else
	{
		arBeginRGB=objBeginRGB;
	}

	if(typeof(objEndRGB)=="string")
	{
		arEndRGB=new RGBObject(objEndRGB).toArray();
	}
	else
	{
		arEndRGB=objEndRGB;
	}

	if(!elm.originalRGB)
	{
		elm.originalRGB=[];
	}

	if(typeof(elm.originalRGB[strAttribute])=="undefined")
	{
		elm.originalRGB[strAttribute]=new RGBObject(
				_.getstyle(elm,strAttribute)).toArray();
	}

	if(!arEndRGB)
	{
		arBeginRGB=new RGBObject(_.getstyle(elm,strAttribute)).toArray();
		arEndRGB=elm.originalRGB[strAttribute];
	}
	else if(!arBeginRGB)
	{
		arBeginRGB=elm.originalRGB[strAttribute];
	}

	rIncrement=new Incrementer(arBeginRGB[0],arEndRGB[0],
		intTotalStep,expFactor);
	gIncrement=new Incrementer(arBeginRGB[1],arEndRGB[1],
		intTotalStep,expFactor);
	bIncrement=new Incrementer(arBeginRGB[2],arEndRGB[2],
		intTotalStep,expFactor);

	if(elm[strAttribute+"_FadeInterval"])
	{
		clearInterval(elm[strAttribute+"_FadeInterval"]);
	}

	elm["colorFade_"+strAttribute+"_OK"]=false;

	elm[strAttribute+"_FadeInterval"]=setInterval(
		function()
		{
			var r=rIncrement.next();
			var g=gIncrement.next();
			var b=bIncrement.next();

			if(r)
			{
				_.setstyle(elm,strAttribute,"rgb("+r+","+g+","+b+")");
			}
			else
			{
				r=arEndRGB[0];g=arEndRGB[1];b=arEndRGB[2];

				_.setstyle(elm,strAttribute,"rgb("+r+","+g+","+b+")");

				elm["colorFade_"+strAttribute+"_OK"]=true;

				clearInterval(elm[strAttribute+"_FadeInterval"]);

				if(_.defined(fncNextEffect)&&fncNextEffect)
				{
					fncNextEffect();
				}
			}
		}
	,intIntervalMilli);
};

_this.isInProgress=function(elm,strEffectName,strAttribute)
{
	if(!strAttribute)
	{
		strAttribute="";
	}
	if(typeof(elm[strEffectName+"_"+strAttribute+"_OK"])=="undefined")
	{
		return false;
	}

	return !elm[strEffectName+"_"+strAttribute+"_OK"];
};

var Effect=new _Effect();

/** DraggableLayerController -------------------------------------- **/

function _DraggableLayerController()
{
	this._currentAction=Constant.NOT_INITED;
	this._currentKeyState=Constant.NOT_INITED;
	this._currentMouseState=Constant.NOT_INITED;
	this._activeLayer=null;
	this._beginCoord=_.dim(-1,-1);
	this._LT=_.dim(-1,-1);
	this._WH=_.dim(-1,-1);
	this._arDragLayer=[];
	this._arIgnoreLayer=[];
	this._arDragConstraint=[];
	this._arResizeConstraint=[];
	this._arDragAction=[];
	this._blnEventAttached=false;
	this._dragIndexes=[];
	this._ignoreIndexes=[];
	this._cancelRegisterCount=0;
}

_this=_DraggableLayerController.prototype;

_this.incrementCancelRegisterCount=function()

{
	this._cancelRegisterCount++;
};

_this.decrementCancelRegisterCount=function()
{
	if(this._cancelRegisterCount>0)
	{
		this._cancelRegisterCount--;
	}
};

_this.getCancelRegisterCount=function()
{
	return this._cancelRegisterCount;
};

_this.getDragIndexes=function()
{
	return this._dragIndexes.copy();
};

_this.getIgnoreIndexes=function()
{
	return this._ignoreIndexes.copy();
};

_this.isEventAttached=function()
{
	return this._blnEventAttached;
};

_this.setEventAttached=function(blnValue)
{
	this._blnEventAttached=blnValue;
};

_this.setCurrentAction=function(intState)
{
	this._currentAction=intState;
};

_this.setCurrentKeyState=function(intState)
{
	this._currentKeyState=intState;
};

_this.setCurrentMouseState=function(intState)
{
	this._currentMouseState=intState;
};

_this.setActiveLayer=function(obj)
{
	this._activeLayer=obj;
};

_this.setBeginCoord=function(x,y)
{
	this._beginCoord.setX(x);
	this._beginCoord.setY(y);
};

_this.setLT=function(left,top)
{
	this._LT.setX(left);
	this._LT.setY(top);
};

_this.setWH=function(width,height)
{
	this._WH.setX(width);
	this._WH.setY(height);
};

_this.registerDragLayer=function(obj)
{
	var strID=obj.getID();
	this._arDragLayer[strID]=obj;
	this._dragIndexes.push(strID);
};

_this.registerIgnoreLayer=function(obj)
{
	var strID=obj.getID();
	this._arIgnoreLayer[strID]=obj;
	this._ignoreIndexes.push(strID);
};

_this.registerDragConstraint=function(strID,obj)
{
	this._arDragConstraint[strID]=obj;
};

_this.registerResizeConstraint=function(strID,obj)
{
	this._arResizeConstraint[strID]=obj;
};

_this.registerDragAction=function(strID,intAction)
{
	this._arDragAction[strID]=intAction;
};

_this.getCurrentAction=function()
{
	return this._currentAction;
};

_this.getCurrentKeyState=function()
{
	return this._currentKeyState;
};

_this.getCurrentMouseState=function()
{
	return this._currentMouseState;
};

_this.getActiveLayer=function()
{
	return this._activeLayer;
};

_this.getBeginCoord=function()
{
	return this._beginCoord;
};

_this.getLT=function(left,top)
{
	return this._LT;
};

_this.getWH=function(width,height)
{
	return this._WH;
};

_this.getDragLayer=function(strID)
{
	return this._arDragLayer[strID];
};

_this.getIgnoreLayer=function(strID)
{
	return this._arIgnoreLayer[strID];
};

_this.getDragConstraint=function(strID)
{
	return this._arDragConstraint[strID];
};

_this.getResizeConstraint=function(strID)
{
	return this._arResizeConstraint[strID];
};

_this.getDragAction=function(strID)
{
	return this._arDragAction[strID];
};

var DraggableLayerController=new _DraggableLayerController();

/** EventObject --------------------------------------------------- **/

function EventObject(evt)
{
	this._evt=typeof(evt)=="undefined"?window.event:evt;
}

_this=EventObject.prototype;

_this.cancelDefaultAction=function()
{
	var e=this._evt;

	if(e.preventDefault)
	{
		e.preventDefault();
	}
	else
	{
		e.returnValue=false;
	}

	return false;
};

_this.getSource=function(_blnDragLayer)
{
	var e=this._evt,
		src=e.srcElement?e.srcElement:(e.target?e.target:null),
		arIgnore=DraggableLayerController.getIgnoreIndexes(),
		i=0;

	if(_blnDragLayer&&src.nodeName)
	{
		/* no drag operation for form elements */
		if(_.formelm(src))
		{
			return null;
		}

		while(true)
		{
			if(src.id)
			{
				for(i=0;i<arIgnore.length;i++)
				{
					if(src.id==arIgnore[i])
					{
						return null;
					}
				}

				if(DraggableLayerController.getDragLayer(src.id))
				{
					return src;
				}
			}

			if(src.parentNode)
			{
				src=src.parentNode;
			}
			else
			{
				return null;
			}

			if(!src.nodeName)
			{
				return null;
			}

			if(!_.defined(src.nodeName)||src.nodeName==="")
			{
				break;
			}
		}
	}

	return src;
};

_this.getObject=function()
{
	return this._evt;
};

/** EventRegistry ------------------------------------------------- **/

function _EventRegistry()
{
	this._arEvent=[];
}

_this=_EventRegistry.prototype;

_this.add=function(objEventModel)
{
	this._arEvent.push(objEventModel);
};

_this.removeAll=function()
{
	while(this._arEvent.length>0)
	{
		this._arEvent.pop().finalize();
	}
};

_this.finalize=function()
{
	/*detach all the events*/
	this.removeAll();
	/*defensive coding*/
	this._arEvent=null;
};

_this.remove=function(/*varargin*/)
{
	var obj=null,
		arEventModel=this._arEvent;
		
	for(var i=0;i<arguments.length;i++)
	{
		obj=_.o(arguments[i]);

		for(var j=0;j<arEventModel.length;j++)
		{
			if(arEventModel[j].getID()==obj.id)
			{
				arEventModel[j].finalize();
				arEventModel[j]=null;
			}
		}
	}

	arEventModel.compact();
};

var EventRegistry=new _EventRegistry();

/** EventModel ---------------------------------------------------- **/

function EventModel(elmID,strEventType,fncEventListener)
{
	this._elmID=elmID;
	this._strEventType=strEventType;
	this._fncEventListener=fncEventListener;
}

_this=EventModel.prototype;

_this.getID=function()
{
	return _.id(this._elmID);
};

_this.unregister=function()
{
	_.unchain(this._elmID,this._strEventType,this._fncEventListener);
};

_this.finalize=function()
{
	this.unregister();
	this._elmID=null;
	this._strEventType=null;
	this._fncEventListener=null;
};

_this.register=function()
{
	_.chain(this._elmID,this._strEventType,this._fncEventListener);
};

/** EventHandler -------------------------------------------------- **/

function _EventHandler()
{
	this.addEventListener(window,"unload",this._unregister,true);
}

_this=_EventHandler.prototype;

_this.addEventListener=function(elmID,strEventType,fncEventListener,
blnBypassRegistry)
{
	var	obj,
		arObj=[],
		arID=null,
		arEventType=null,
		i=0,
		j=0;

	if(!_.string(elmID))
	{
		arObj.push(elmID);
	}
	else
	{
		arID=elmID.split(/,/);
		for(i=0;i<arID.length;i++)
		{
			arObj.push(_.o(arID[i]));
		}
	}

	for(j=0;j<arObj.length;j++)
	{
		if(!(obj=arObj[j]))
		{
			continue;
		}

		arEventType=strEventType.toLowerCase().split(/,/);

		for(i=0;i<arEventType.length;i++)
		{
			if(_.defined(obj.addEventListener))
			{
				obj.addEventListener(arEventType[i],fncEventListener,false);
			}
			else if(_.defined(obj.attachEvent))
			{
				obj.attachEvent("on"+arEventType[i],fncEventListener);
			}
			else
			{
				alert("ERROR: unknown event handler: " + arEventType[i]);
			}

			if(!blnBypassRegistry)
			{
				EventRegistry.add(new EventModel(elmID,arEventType[i],
					fncEventListener));
			}
		}

	}
};

_this.removeEventListener=function(elmID,strEventType,fncEventListener)
{
	var obj=_.o(elmID);

	if(!obj)
	{
		return;
	}

	strEventType=strEventType.toLowerCase();

	if(obj.removeEventListener)
	{
		obj.removeEventListener(strEventType,fncEventListener,false);
	}
	else if(obj.detachEvent)
	{
		obj.detachEvent("on"+strEventType,fncEventListener);
	}
	else
	{
		alert("ERROR: cannot remove event handler!");
	}
};

_this._unregister=function()
{
	/*detach all the events.*/
	EventRegistry.finalize();
	/*remove the registry itself; defensive coding.*/
	EventRegistry=null;	
};

var EventHandler=new _EventHandler();

/** CollapseManagerController ------------------------------------- **/

function _CollapseManagerController()
{
	this._ar=[];
}

_this=_CollapseManagerController.prototype;

_this.add=function(obj)
{
	this._ar.push(obj);
};

_this.getAll=function()
{
	return this._ar.copy();
};

_this.getElementAt=function(intIndex)
{
	if(intIndex<0||intIndex>this.count())
	{
		alert("ERROR: indexOutOfBound @CollapseManager.getElementAt");
		return null;
	}

	return this._ar[intIndex];
};

_this.removeAll=function()
{
	this._ar.length=0;
};

 _this.count=function()
{
	return this._ar.length;
};
var CollapseManagerController=new _CollapseManagerController();

/** CollapseManager ----------------------------------------------- **/

function CollapseManager()
{
	this._arGroup=[];
	this._blnHover=false;
}

_this=CollapseManager.prototype;

_this.attach=function(blnHover)
{
	var arDiv=_.gtn("div"),
		i=0;

	for(i=0;i<arDiv.length;i++)
	{
		if(_.getclass(arDiv[i]).indexOf("collapseActuator")>-1)
		{
			_.chain(arDiv[i],"click",this._toggleCollapse,true);
		}
	}

	if(blnHover)
	{
		this._blnHover=true;

		for(i=0;i<arDiv.length;i++)
		{
			if(_.getclass(arDiv[i]).indexOf("collapseActuator")>-1)
			{
				_.chain(arDiv[i],"mouseover",this._toggleCollapse,true);
			}
		}
	}

	CollapseManagerController.add(this);
};

_this.detach=function()
{
	var arDiv=_.gtn("div"),
		i=0;

	for(i=0;i<arDiv.length;i++)
	{
		if(_.hasclass(arDiv[i],"collapseActuator"))
		{
			_.unchain(arDiv[i],"click",this._toggleCollapse);
		}
	}

	if(this._blnHover)
	{
		for(i=0;i<arDiv.length;i++)
		{
			if(_.hasclass(arDiv[i],"collapseActuator"))
			{
				_.unchain(arDiv[i],"mousemove",this._toggleCollapse);
			}
		}
	}

	CollapseManagerController.removeAll();
};

_this.collapseAll=function()
{
	var arDiv=_.gtn("div");

	for(var i=0;i<arDiv.length;i++)
	{
		if(_.hasclass(arDiv[i],"collapseActuator"))
		{
			_.remclass(arDiv[i],["expanded"]);
		}

		if(_.getclass(arDiv[i]).indexOf("Collapser")>-1)
		{
			_.setstyle(arDiv[i],"display","none");
		}
	}
};

_this.expandAll=function()
{
	var arDiv=_.gtn("div");

	for(var i=0;i<arDiv.length;i++)
	{
		if(_.hasclass(arDiv[i],"collapseActuator"))
		{
			_.addclass(arDiv[i],["expanded"]);
		}

		if(_.getclass(arDiv[i]).indexOf("Collapser")>-1)
		{
			_.setstyle(arDiv[i],"display","block");
		}
	}
};

_this.group=function(/*varargin*/)
{
	var arActuator=[];

	for(var i=0;i<arguments.length;i++)
	{
		arActuator.push(arguments[i]);
	}

	this._arGroup.push(arActuator);

	return this._arGroup.length-1;
};

_this.getGroupIndex=function(strActuatorID)
{
	for (var i=0;i<this._arGroup.length;i++)
	{
		if(this._arGroup[i].contains(strActuatorID))
		{
			return i;
		}
	}

	return -1;
};

_this.groupContains=function(intIndex,strID)
{
	if(this._arGroup.length>intIndex)
	{
		return this._arGroup[intIndex].contains(strID);
	}

	return false;
};

_this.collapse=function(strActuatorID)
{
	var arDiv=_.gtn("div");

	for(var i=0;i<arDiv.length;i++)
	{
		if(i===0)
		{
			_.remclass(strActuatorID,["expanded"]);
		}

		if(_.hasclass(arDiv[i],strActuatorID+"Collapser"))
		{
			_.setstyle(arDiv[i],"display","none");
		}
	}
};

_this.expand=function(strActuatorID)
{
	var arDiv=_.gtn("div");

	for(var i=0;i<arDiv.length;i++)
	{
		if(i===0)
		{
			_.addclass(strActuatorID,["expanded"]);
		}

		if(_.hasclass(arDiv[i],strActuatorID+"Collapser"))
		{
			_.setstyle(arDiv[i],"display","block");
		}
	}
};

_this.collapseGroup=function(intGroupIndex)
{
	var arGroup=this._arGroup[intGroupIndex],
		arDiv=_.gtn("div");

	if(!arGroup)
	{
		return;
	}

	for(var i=0;i<arDiv.length;i++)
	{
		for(var j=0;j<arGroup.length;j++)
		{
			if(i===0)
			{
				_.remclass(arGroup[j],["expanded"]);
			}

			if(_.hasclass(arDiv[i],arGroup[j]+"Collapser"))
			{
				_.setstyle(arDiv[i],"display","none");
			}
		}
	}
};

_this.expandGroup=function(intGroupIndex)
{
	var arGroup=this._arGroup[intGroupIndex],
		arDiv=_.gtn("div");

	if(!arGroup)
	{
		return;
	}

	for(var i=0;i<arDiv.length;i++)
	{
		for(var j=0;j<arGroup.length;j++)
		{
			if(i===0)
			{
				_.addclass(arGroup[j],["expanded"]);
			}

			if(_.hasclass(arDiv[i],arGroup[j]+"Collapser"))
			{
				_.setstyle(arDiv[i],"display","block");
			}
		}
	}
};

_this._toggleCollapse=function(evt)
{
	var obj=_.src(evt),
		selfRef=null,
		arDiv=null,
		strClass="",
		len=CollapseManagerController.count();

	for(var i=0;i<len;i++)
	{
		selfRef=CollapseManagerController.getElementAt(i);

		if(selfRef.groupContains(i,obj.id))
		{
			selfRef.collapseGroup(selfRef.getGroupIndex(obj.id));
		}

		arDiv=_.gtn("div");

		for(var j=0;j<arDiv.length;j++)
		{
			strClass=_.getclass(arDiv[j]);

			if(strClass.indexOf(obj.id+"Collapser")>-1)
			{
				if(_.getstyle(arDiv[j],"display")=="block")
				{
					_.remclass(obj,["expanded"]);
					_.setstyle(arDiv[j],"display","none");
					return;
				}
				else
				{
					_.addclass(obj,["expanded"]);
					_.setstyle(arDiv[j],"display","block");
					return;
				}
			}
		}
	}
};

/** CursorTracker ------------------------------------------------- **/

function _CursorTracker()
{
	this._cursorCoordinates=_.dim(-1,-1);
	this._construct();
}

_this=_CursorTracker.prototype;

_this.withinElement=function(objElement,enumOrientation)
{
	var pos=this.getCursorPosition(),
		offset=DOMManager.getOffset(objElement),
		lyr=new DynamicLayer(objElement),
		width=lyr.getWidth(),
		height=lyr.getHeight(),
		x=pos.getX(),
		y=pos.getY(),
		ox=offset.getX(),
		oy=offset.getY(),
		blnHorizontalInRange=(x>ox&&x<(ox+width)),
		blnVerticalInRange=(y>oy&&y<(oy+height));

	if(!enumOrientation)
	{
		enumOrientation=Constant.Orientation.BOTH;
	}

	if(enumOrientation==Constant.Orientation.HORIZONTAL)
	{
		return blnHorizontalInRange;
	}
	else if(enumOrientation==Constant.Orientation.VERTICAL)
	{
		return blnVerticalInRange;
	}

	return blnHorizontalInRange&&blnVerticalInRange;
};

_this.getCursorPosition=function()
{
	return this._cursorCoordinates;
};

_this.toString=function()
{
	return this._cursorCoordinates;
};

_this._construct=function()
{
	_.chain(document,"mousemove",this._getCursorPosition,true);
};

_this._getCursorPosition=function(evt)
{
	var posx=0,
		posy=0,
		e=_.oevt(evt);

	if(e.pageX||e.pageY)
	{
		posx=e.pageX;
		posy=e.pageY;
	}
	else if(e.clientX||e.clientY)
	{
		posx=e.clientX+WindowObject.getScrollOffset().getX();
		posy=e.clientY+WindowObject.getScrollOffset().getY();
	}

	CursorTracker._cursorCoordinates.setX(posx);
	CursorTracker._cursorCoordinates.setY(posy);
};

var CursorTracker=new _CursorTracker();

/** LayerObject --------------------------------------------------- **/

function LayerObject(elmID)
{
	this._obj=_.o(elmID);
}

LayerObject.prototype=new CBObject();
_this=LayerObject.prototype;

_this.setStyle=function(strSelector,strValue)
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return;
	}

	_.setstyle(obj,strSelector,strValue);
};

_this.getStyle=function(strSelectorExtended)
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return null;
	}

	return _.getstyle(obj,strSelectorExtended);
};

_this.setClass=function(strClass)
{
	_.setclass(this.getObject(),strClass);
};

_this.getClass=function()
{
	return _.getclass(this.getObject());
};

_this.isVisible=function()
{
	return this.getStyle("visibility")!="hidden"&&
		this.getStyle("display")!="none";
};

_this.show=function()
{
	this.setStyle("visibility","visible");
};

_this.hide=function()
{
	this.setStyle("visibility","hidden");
};

_this.collapse=function()
{
	this.setStyle("display","none");
};

_this.expandInline=function()
{
	this.setStyle("display","inline");
};

_this.expand=function()
{
	this.setStyle("display","block");
};

_this.changeContent=function(strNewHTML)
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return;
	}

	if(typeof(obj.innerHTML)!="undefined")
	{
		obj.innerHTML=strNewHTML;
	}
};

_this.addContentBefore=function(strHTML)
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return;
	}

	if(obj.innerHTML)
	{
		this.changeContent(strHTML+obj.innerHTML);
	}
};

_this.addContentAfter=function(strHTML)
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return;
	}

	if(obj.innerHTML)
	{
		this.changeContent(obj.innerHTML+strHTML);
	}
};

/** DynamicLayer -------------------------------------------------- **/

function DynamicLayer(elmID)
{
	this._obj=_.o(elmID);
}

DynamicLayer.prototype=new LayerObject();
_this=DynamicLayer.prototype;

_this.moveTo=function(objLeft,intTop)
{
	var left=0,
		top=0;

	if(arguments.length==1)
	{
		left=objLeft.getX();
		top=objLeft.getY();
	}
	else
	{
		left=objLeft;
		top=intTop;
	}

	this.setLeft(left);
	this.setTop(top );
	//alert( top );
	//alert( left  + " - " + top)
};

_this.moveToDeadCentre=function()
{
	this.moveTo(
		Math.floor((WindowObject.getInnerDimension().getX()-
			this.getWidth()+2*WindowObject.getScrollOffset().getX())/2),
		Math.floor((WindowObject.getInnerDimension().getY()-
			this.getHeight()+2*WindowObject.getScrollOffset().getY())/2));
			
};

_this.resizeTo=function(objWidth,intHeight)
{
	var width=0,
		height=0;

	if(arguments.length==1)
	{
		width=objWidth.getX();
		height=objWidth.getY();
	}
	else
	{
		width=objWidth;
		height=intHeight;
	}

	this.setWidth(width);
	this.setHeight(height);
};

_this.getLeft=function()
{
	var strLeft=this.getStyle("left"),
	intLeft=parseInt(strLeft,10),
	obj=this.getObject();
	
	if(!obj)
	{
		return 0;
	}

	if(!_.numeric(intLeft)||strLeft.indexOf("%")>-1)
	{
		if(obj.offsetLeft)
		{
			intLeft=obj.offsetLeft;
		}
	}

	return _.numeric(intLeft)?parseInt(intLeft,10):0;
};

_this.setLeft=function(intLeft)
{
	this.setStyle("left",intLeft+"px");
};

_this.getTop=function()
{
	var strTop=this.getStyle("top"),
		intTop=parseInt(strTop,10),
		obj=this.getObject();
		
	if(!obj)
	{
		return 0;
	}

	if(!_.numeric(intTop)||strTop.indexOf("%")>-1)
	{
		if(obj.offsetTop)
		{
			intTop=obj.offsetTop;
		}
	}

	return _.numeric(intTop)?parseInt(intTop,10):0;
};

_this.setTop=function(intTop)
{
	this.setStyle("top",intTop+"px");
};

_this.getHeight=function()
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return 0;
	}

	if(_.defined(obj.offsetHeight))
	{
		return parseInt(obj.offsetHeight,10);
	}
	
	return 0;
};

_this.setHeight=function(intHeight)
{
	var obj=null,
		intDifference=0,
		intCssHeight=0;

	if(!(obj=this.getObject()))
	{
		return;
	}

	if(_.defined(obj.offsetHeight))
	{
		this.setStyle("height",intHeight+"px");
		intDifference=(obj.offsetHeight-intHeight);
	}

	if(!_.numeric(intDifference))
	{
		intDifference=0;
	}

	intCssHeight=intHeight-intDifference;

	if(!_.positive(intCssHeight))
	{
		return;
	}

	this.setStyle("height",intCssHeight+"px");
};

_this.getWidth=function()
{
	var obj=null;

	if(!(obj=this.getObject()))
	{
		return 0;
	}

	if(_.defined(obj.offsetWidth))
	{
		return parseInt(obj.offsetWidth,10);
	}

	return 0;
};

_this.setWidth=function(intWidth)
{
	var obj=null,
		intDifference=0,
		intCssWidth=0;

	if(!(obj=this.getObject()))
	{
		return;
	}


	if(_.defined(obj.offsetWidth))
	{
		this.setStyle("width",intWidth+"px");
		intDifference=(obj.offsetWidth-intWidth);
	}

	if(!_.numeric(intDifference))
	{
		intDifference=0;
	}

	intCssWidth=intWidth-intDifference;

	if(!_.positive(intCssWidth))
	{
		return;
	}

	this.setStyle("width",intCssWidth+"px");
};

_this.getOpacity=function()
{
	var opacity=null,
		obj=this.getObject(),
		regOp=/alpha\(opacity=(.*)\)/;

	if(!obj)
	{
		return null;
	}

	if((opacity=_.getstyle(obj,"opacity")))
	{
		return parseFloat(opacity);
	}
	else if((opacity=_.getstyle(obj,"filter")))
	{
		opacity=opacity.match(regOp);

		if(opacity[1])
		{
			return parseFloat(opacity[1])/100;
		}
	}

	return 1;
};

_this.setOpacity=function(dblValue)
{
	var obj=this.getObject();

	if(!obj)
	{
		return null;
	}

	/* Look ma, no browser sniffing! */

	if(dblValue==1)
	{
		dblValue=0.99999;
	}
	else if(dblValue<0.00001)
	{
		dblValue=0;
	}

	_.setstyle(obj,"filter","alpha(opacity="+(dblValue*100)+")");
	_.setstyle(obj,"opacity",dblValue);
};

/** MessagePane  -------------------------------------------------- **/

function MessagePane(elm,strNormalClass,strErrorClass)
{
	this._obj=_.o(elm);
	this._normalClass=strNormalClass;
	this._errorClass=strErrorClass;
	this._arErrorField=[];

	/*
	 * 	 var _base=function(){this._obj=_.o(elm);};
	 * 	 _base.prototype=new DynamicLayer();
	 * 	 this.base=new _base();
	 *
	 * The code piece above will create a base.
	 * But it will unnecessarily duplicate an entire object.
	 * This will consume memory if the object is a large one.
	 *
	 * Better to override just the necessary methods
	 * as implemented below (this.super$show).
	 */

	/* First, store the original method. */
	this.super$show=this.show;

	/*
	 * For inheriting methods deeper:
	 *
	 * this.super$super$show=this.super$show;
	 * this.super$show=this.show;
	 */

	/* Then override base method. */
	this.show=function(strMessage,objErrorField,blnHasError)
	{
		this.changeContent(strMessage);
		this.super$show();

		if(blnHasError)
		{
			this.setClass(this._errorClass);
			if(objErrorField)
			{
				objErrorField.setError();
			}
		}
		else
		{
			this.setClass(this._normalClass);
		}

		Effect.alphaFade(this.getObject(),[0,1],
			function()
			{
				try
				{
					/*
					 * The line below will generate:
					 *
					 * "Permission denied to get property XULElement.accessKey'
					 * when calling method: [nsIDOMXULLabelElement::accessKey]"
					 *
					 * chrome exception in Firefox, which is a bug of Firefox's
					 * autocomplete feature and has been reported in bugzilla.
					 *
					 * I'm not adding a fix for it, since Firefox team
					 * possibly plan to fix it sooner or later.
					 */
					if(objErrorField)
					{
						objErrorField.getObject().focus();
					}
				}
				catch(ignore)
				{
				}
			}
		);

	};
}

MessagePane.prototype=new DynamicLayer();
_this=MessagePane.prototype;

_this.bindField=function(/*varargin*/)
{
	var len=arguments.length;
	for(var i=0;i<len;i++)
	{
		this._arErrorField.push(arguments[i]);
	}
};

_this._clearErrorField=function()
{
	var len=this._arErrorField.length;
	for(var i=0;i<len;i++)
	{
		this._arErrorField[i].clearError();
	}
};

_this.clear=function()
{
	this.setOpacity(0);
	this.hide();
	this.changeContent("");
	this.setClass(this._normalClass);
	this._clearErrorField();
};

/** DraggableLayer ------------------------------------------------ **/

function DraggableLayer(elmID,constraintMove,constraintResize,blnNoResize)
{
	this._obj=_.o(elmID);
	
	var id=this.getID(),
		width=this.getWidth(),
		height=this.getHeight();

	DraggableLayerController.registerDragAction(id,Constant.NOT_INITED);

	if(constraintMove)
	{
		DraggableLayerController.registerDragConstraint(id,constraintMove);
	}

	if(constraintResize)
	{
		DraggableLayerController.registerResizeConstraint(id,constraintResize);
	}

	if(blnNoResize)
	{
		DraggableLayerController.registerResizeConstraint(id,
			_.cns(width,height,width,height));
	}

	this._construct();
}

DraggableLayer.prototype=new DynamicLayer();
_this=DraggableLayer.prototype;

_this.ignoreLayer=function(/*varargin*/)
{
	var len=arguments.length;
	for(var i=0;i<len;i++)
	{
		DraggableLayerController.registerIgnoreLayer(
			new DynamicLayer(arguments[i]));
	}
};

_this.fixToDragMode=function()
{
	this._changeAction(Constant.Mouse.DRAG);
};

_this.fixToResizeMode=function()
{
	this._changeAction(Constant.Mouse.RESIZE);
};

_this.releaseFixes=function()
{
	this._changeAction(Constant.NOT_INITED);
};

_this._onKeyDown=function(evt)
{
	var e=_.oevt(evt),
		intCode=0,
		lyr=DraggableLayerController.getActiveLayer();

	if(!lyr)
	{
		return;
	}

	if(e)
	{
		intCode=_.defined(e.keyCode)?e.keyCode:e.which;
		/*ctrl, alt, tab*/
		if(Constant.Key.CTRL||Constant.Key.ALT||Constant.Key.TAB)
		{
			return;
		}
	}

	if(DraggableLayerController.getCurrentKeyState()!=Constant.Key.ANYKEY)
	{
		if(lyr.exists())
		{
			if(_.coord())
			{
				DraggableLayerController.setBeginCoord(
					_.coord().getX(),_.coord().getY());
				DraggableLayerController.setLT(lyr.getLeft(),lyr.getTop());
				DraggableLayerController.setWH(lyr.getWidth(),lyr.getHeight());
			}
		}
	}

	DraggableLayerController.setCurrentKeyState(Constant.Key.ANYKEY);
};

_this._onMouseDown=function(evt)
{
	var src=_.src(evt,true),
		intMaxIndex=0,
		objLayer=null,/*sýralama için: o anki katman.*/
		objMaxLayer=null,/*en üstteki katman.*/
		lyr=new DynamicLayer(src),
		zIndex=0,
		arDragID=DraggableLayerController.getDragIndexes(),
		i=0;

	/*
	 * The cursor style may be different in Opera
	 * Cursor changes but the Opera does not render it unless
	 * it hovers on another node
	 * ---
	 * Boþuna kasma.
	 */
	DraggableLayerController.setCurrentMouseState(Constant.Mouse.DOWN);

	if(src)
	{
		DraggableLayerController.setActiveLayer(lyr);

		if(!(src.id))
		{
			alert("ERROR: ID is a required "+
				"propery of Draggablelayer [DraggableLayer.onMouseDown]");
		}
		else
		{
			if(lyr.getStyle("z-index")!==null)
			{
				/*sort layers*/
				for(i=0;i<arDragID.length;i++)
				{
					objLayer=DraggableLayerController.getDragLayer(
						arDragID[i]);

					zIndex=objLayer.getStyle("z-index");

					if(!_.integer(zIndex)||parseInt(zIndex,10)<1)
					{
						objLayer.setStyle("zIndex",intMaxIndex+1);
						intMaxIndex+=1;
					}
					else
					{
						intMaxIndex=Math.max(intMaxIndex,
							objLayer.getStyle("z-index"));
					}
				}

				for(i=0;i<arDragID.length;i++)
				{
					objLayer=DraggableLayerController.getDragLayer(
						arDragID[i]);

					if(objLayer.getStyle("z-index")==intMaxIndex)
					{
						objMaxLayer=objLayer;
					}
				}

				if(parseInt(lyr.getStyle("z-index"),10)<intMaxIndex)
				{
					lyr.setStyle("zIndex",intMaxIndex);
					objMaxLayer.setStyle("zIndex",intMaxIndex-1);
				}
			}

			DraggableLayerController.setBeginCoord(_.coord().getX(),
				_.coord().getY());
			DraggableLayerController.setLT(lyr.getLeft(),lyr.getTop());
			DraggableLayerController.setWH(lyr.getWidth(),lyr.getHeight());
		}
	}
};

_this._onMouseUp=function(evt)
{
	var lyr=DraggableLayerController.getActiveLayer();

	if(!lyr)
	{
		return;
	}

	lyr.setStyle("cursor","default");

	DraggableLayerController.setCurrentMouseState(Constant.NOT_INITED);
	DraggableLayerController.setCurrentAction(Constant.NOT_INITED);
	DraggableLayerController.setCurrentKeyState(Constant.NOT_INITED);
	DraggableLayerController.setBeginCoord(-1,-1);
	DraggableLayerController.setLT(-1,-1);
	DraggableLayerController.setWH(-1,-1);
	DraggableLayerController.setActiveLayer(null);
};

_this._onMouseMove=function(evt)
{
	var lyr=DraggableLayerController.getActiveLayer();

	if(!lyr)
	{
		return;
	}

	if(!lyr.exists()||_.formelm(_.src(evt)))
	{
		return;
	}

	var id=lyr.getID(),
		registeredAction=DraggableLayerController.getDragAction(id),/* none, 
		                       Constant.Mouse.RESIZE or Constant.Mouse.DRAG */
		cons=null, /* contstarint for this layer */
		intMinTop,  /* the top and left    */
		intMinLeft, /* coordinate limits   */
		intMaxTop,  /* that come with      */
		intMaxLeft, /* constraint          */
		intMaxWidth,  /* the width and height */
		intMaxHeight, /* value ranges         */
		intMinWidth,  /* that come with       */
		intMinHeight, /* constraint           */
		intCurrentLeft,   /* current         */
		intCurrentTop,    /* left, top,      */
		intCurrentWidth,  /* width, height   */
		intCurrentHeight, /* values          */
		left,   /* left, top,        */
		top,    /* width, height     */
		width,  /* values            */
		height, /* to be calculated  */
		blnInHorizontalRange, /* range flags             */
		blnInVerticalRange,   /* that control            */
		blnWidthInRange,      /* whether the dimensions  */
		blnHeightRange,       /* are in correct ranges   */
		currentAction=null,   /* none, Constant.Mouse.RESIZE or 
		                         Constant.Mouse.DRAG */
		dragLT=DraggableLayerController.getLT(), /* Left and Top */
		dragBeginCoord=DraggableLayerController.getBeginCoord(), /* Where 
		                                                    I began dragging */
		dragWH=DraggableLayerController.getWH(), /* Width and height of the 
		                                            dragged object */
		arIgnore=DraggableLayerController.getIgnoreIndexes(); /* shall I 
		                                           ignore any child objects? */

	if(registeredAction!=Constant.NOT_INITED)
	{
		DraggableLayerController.setCurrentAction(registeredAction);
	}
	else
	{
		if(DraggableLayerController.getCurrentKeyState()==Constant.Key.ANYKEY)
		{
			DraggableLayerController.setCurrentAction(Constant.Mouse.RESIZE);
		}
		else
		{
			DraggableLayerController.setCurrentAction(Constant.Mouse.DRAG);
		}
	}

	currentAction=DraggableLayerController.getCurrentAction();

	if(currentAction==Constant.Mouse.DRAG)
	{
		lyr.setStyle("cursor","move");
	}
	else if(currentAction==Constant.Mouse.RESIZE)
	{
		lyr.setStyle("cursor","se-resize");
	}
	else
	{
		lyr.setStyle("cursor","default");
	}

	for(var i=0;i<arIgnore.length;i++)
	{
		if(arIgnore[i]==id)
		{
			return;
		}
	}

	if(currentAction==Constant.Mouse.DRAG)
	{
		left=dragLT.getX()+_.coord().getX()-dragBeginCoord.getX();
		top=dragLT.getY()+_.coord().getY()-dragBeginCoord.getY();

		if((cons=DraggableLayerController.getDragConstraint(id)))
		{
			intMinTop=cons.getLowerBound().getX();
			intMinLeft=cons.getLowerBound().getY();
			intMaxTop=cons.getUpperBound().getX();
			intMaxLeft=cons.getUpperBound().getY();

			/*kaldýrma; gerekiyor. constraint varken sapýtýyor yoksa.*/
			lyr.setLeft(left);
			lyr.setTop(top);

			intCurrentLeft=lyr.getLeft();
			intCurrentTop=lyr.getTop();

			blnInHorizontalRange=(intCurrentLeft>=intMinLeft&&
				intCurrentLeft<=intMaxLeft);
			blnInVerticalRange=(intCurrentTop>=intMinTop&&
				intCurrentTop<=intMaxTop);

			if(blnInHorizontalRange&&!blnInVerticalRange)
			{
				if(intCurrentTop<=intMinTop)
				{
					top=intMinTop;
				}
				else if(intCurrentTop>=intMaxTop)
				{
					top=intMaxTop;
				}

				lyr.setLeft(left);
				lyr.setTop(top);

				return;
			}
			else if(!blnInHorizontalRange&&blnInVerticalRange)
			{
				if(intCurrentLeft<=intMinLeft)
				{
					left=intMinLeft;
				}
				else if(intCurrentLeft>=intMaxLeft)
				{
					left=intMaxLeft;
				}

				lyr.setLeft(left);
				lyr.setTop(top);

				return;
			}
			else if(!blnInHorizontalRange&&!blnInVerticalRange)
			{
				if(intCurrentTop<=intMinTop)
				{
					top=intMinTop;
				}
				else if(intCurrentTop>=intMaxTop)
				{
					top=intMaxTop;
				}

				if(intCurrentLeft<=intMinLeft)
				{
					left=intMinLeft;
				}
				else if(intCurrentLeft>=intMaxLeft)
				{
					left=intMaxLeft;
				}

				lyr.setLeft(left);
				lyr.setTop(top);

				return;
			}
		}

		lyr.setLeft(left);
		lyr.setTop(top);
	}/*end if drag mode*/
	else
	{
		width=dragWH.getX()+_.coord().getX()-dragBeginCoord.getX();
		height=dragWH.getY()+_.coord().getY()-dragBeginCoord.getY();

		if((cons=DraggableLayerController.getResizeConstraint(id)))
		{
			intMaxWidth=cons.getUpperBound().getX();
			intMaxHeight=cons.getUpperBound().getY();
			intMinWidth=cons.getLowerBound().getX();
			intMinHeight=cons.getLowerBound().getY();

			/*kaldýrma; gerekiyor. constraint varken sapýtýyor yoksa.*/
			lyr.setWidth(width<0?10:width);
			lyr.setHeight(height<0?10:height);

			intCurrentWidth=lyr.getWidth();
			intCurrentHeight=lyr.getHeight();

			blnWidthInRange=(intCurrentWidth>=intMinWidth&&
				intCurrentWidth<=intMaxWidth);
			blnHeightRange=(intCurrentHeight>=intMinHeight&&
				intCurrentHeight<=intMaxHeight);

			if(blnWidthInRange&&!blnHeightRange)
			{
				if(intCurrentHeight<=intMinHeight)
				{
					height=intMinHeight;
				}
				else if(intCurrentHeight>=intMaxHeight)
				{
					height=intMaxHeight;
				}
			}
			else if(!blnWidthInRange && blnHeightRange)
			{
				if(intCurrentWidth<=intMinWidth)
				{
					width=intMinWidth;
				}
				else if(intCurrentWidth>=intMaxWidth)
				{
					width=intMaxWidth;
				}
			}
			else if(!blnWidthInRange&&!blnHeightRange)
			{
				if(intCurrentHeight<=intMinHeight)
				{
					height=intMinHeight;
				}
				else if(intCurrentHeight>=intMaxHeight)
				{
					height=intMaxHeight;
				}

				if(intCurrentWidth<=intMinWidth)
				{
					width=intMinWidth;
				}
				else if(intCurrentWidth>=intMaxWidth)
				{
					width=intMaxWidth;
				}
			}
		}

		lyr.setWidth((width<=10)?10:width);
		lyr.setHeight((height<=10)?10:height);
	}
};

_this._changeAction=function(strAction)
{
	DraggableLayerController.registerDragAction(this.getID(),strAction);
};

_this._construct=function()
{
	var objSelf=this.getObject(),
		objEvent=null,
		strNode="",
		cancelEvent=null;

	if(this.exists()&&this.getID())
	{
		DraggableLayerController.registerDragLayer(this);

		cancelEvent=function(evt)
		{
			objEvent=_.evto(evt);
			strNode=_.src(objEvent).nodeName.toLowerCase();

			if(strNode=="input"||strNode=="select"||
				strNode=="option"||strNode=="textarea")
			{
				return;
			}
			else
			{
				_.stop(objEvent);
			}
		};

		_.chain(objSelf,"mousedown",
			function(evt)
			{
				DraggableLayerController.incrementCancelRegisterCount();
				_.chain(document,"mousemove",cancelEvent,true);
				cancelEvent(evt);
			}
		);

		_.chain(objSelf,"mouseup",
			function(evt)
			{
				while(DraggableLayerController.getCancelRegisterCount()>0)
				{
					_.unchain(document,"mousemove",cancelEvent,true);
					DraggableLayerController.decrementCancelRegisterCount();
				}
			}
		);

		if(!DraggableLayerController.isEventAttached())
		{
			/*
			 * note that we're explicitly bypassing the EventRegistry.
			 * Since there is no closure, no need to register the Event
			 * to the EventRegistry.
			 */
			_.chain(document,"keydown",this._onKeyDown,true);
			_.chain(document,"mousedown",this._onMouseDown,true);
			_.chain(document,"mouseup",this._onMouseUp,true);
			_.chain(document,"mousemove",this._onMouseMove,true);
			DraggableLayerController.setEventAttached(true);
		}
	}
	else
	{
		alert("ERROR: object reference "+
			"not found or ID missing : DraggableLayer:_construct");
		return;
	}
};

/** ModalDialog --------------------------------------------------- **/

function ModalDialog(elmBgLayer,elmDragLayer,elmContentLayer,elmCloseBtn)
{
	var self=null;

	this._bgLayer=new DynamicLayer(elmBgLayer);
	this._dragLayer=new DraggableLayer(elmDragLayer);
	this._dragLayer.fixToDragMode();
	this._obj=this._dragLayer.getObject();
	this.moveToDeadCentre();

	this._contentLayer=new DynamicLayer(elmContentLayer);
	this._blnDisableClose=false;

	/*for opera*/
	this._bgLayer.collapse();

	if(_.defined(elmCloseBtn))
	{
		self=this;

		_.chain(elmCloseBtn,"click",
			function(evt)
			{
				if(!self.isCloseDisabled())
				{
					self._contentLayer.changeContent("");
					self.hide();
				}
			}
		);
	}
}

ModalDialog.prototype=new DynamicLayer();
_this=ModalDialog.prototype;

_this.disableClose=function()
{
	this._blnDisableClose=true;
};

_this.enableClose=function()
{
	this._blnDisableClose=false;
};

_this.isCloseDisabled=function()
{
	return this._blnDisableClose;
};

_this.show=function(strHTML)
{
	if(typeof(strHTML)!="undefined")
	{
		this._contentLayer.changeContent(strHTML);
	}
	//alert( 1 )
	this._bgLayer.expand();
	this._bgLayer.moveToDeadCentre();
	//alert( 2 )
	this.expand();
	//alert( 3 )
	this.moveToDeadCentre();

	this._replaceCombos();

};

_this._replaceCombos=function(blnReplaceBack)
{

	/*for(var i = 0; i < document.forms.length; i++) {
		for(var e = 0; e < document.forms[i].length; e++){
			if(document.forms[i].elements[e].tagName == "SELECT") {
				document.forms[i].elements[e].style.visibility="hidden";
			}
		}
	}*/

	/*var arSelect = document.getElementsByTagName("select"),
		len=arSelect.length,
		objSel=null,
		strNodeValue="",
		objSpan=null,
		o=null;

	if(!blnReplaceBack)
	{
		blnReplaceBack=false;
	}

	for(var i=0;i<len;i++)
	{
		objSel=arSelect[i];
		strNodeValue=objSel.childNodes[
			objSel.selectedIndex].childNodes[0].nodeValue;

		objSpan=new CBObject(objSel.id+"_ModalWrap");
		if(objSpan.exists())
		{
			o=objSpan.getObject();
			o.parentNode.removeChild(o);
		}

		objSpan=document.createElement("span");
		objSpan.id=objSel.id+"_ModalWrap";
		objSpan.appendChild(document.createTextNode(strNodeValue));
		objSpan.className="modalWrap";
		objSel.parentNode.insertBefore(objSpan,objSel);

		if(blnReplaceBack)
		{
			new DynamicLayer(objSpan).collapse();
			new DynamicLayer(objSel).expandInline();
		}
		else
		{
			new DynamicLayer(objSpan).expandInline();
			new DynamicLayer(objSel).collapse();
		}
	}*/
};

_this.hide=function()
{
	this._bgLayer.collapse();
	this.collapse();
	this._replaceCombos(true);
	this._blnDisableClose=false;
};

/** DropDownMenuController ---------------------------------------- **/

function _DropDownMenuController()
{
	this._timer=null;
	this._timeout=0;
	this._menuclass="";
}

_this=_DropDownMenuController.prototype;

_this.setMenuClass=function(strClass)
{
	this._menuclass=strClass;
};

_this.getMenuClass=function()
{
	return this._menuclass;
};

_this.setTimer=function(intTimerID)
{
	this._timer=intTimerID;
};

_this.setTimeout=function(intTimeout)
{
	this._timeout=intTimeout;
};

_this.getTimer=function()
{
	return this._timer;
};

_this.getTimeout=function()
{
	return this._timeout;
};

var DropDownMenuController=new _DropDownMenuController();

/** DropDownMenu -------------------------------------------------- **/

function _DropDownMenu()
{
}

_this=_DropDownMenu.prototype;

_this.initialize=function(intTimeout,strMenuClass)
{
	var arLink=_.gtn("a"),
		arUL=_.gtn("ul"),
		i=0,
		j=0;

	if(strMenuClass)
	{
		DropDownMenuController.setMenuClass(strMenuClass);
	}
	else
	{
		DropDownMenuController.setMenuClass("sardalyaMenu");
	}


	if(intTimeout)
	{
		DropDownMenuController.setTimeout(intTimeout);
	}

	_.chain(document,"mouseover",this._sniff,true);

	for(i=0;i<arLink.length;i++)
	{
		var id=arLink[i].id;

		if(id&&id!==""&&this._isMenuElement(id))
		{
			_.chain(arLink[i],"focus",this._sniff,true);
			_.chain(arLink[i],"click",this._click,true);
		}
	}

	for(i=0;i<arUL.length;i++)
	{
		if(arUL[i].className.indexOf(DropDownMenuController.getMenuClass())>-1)
		{
			for(j=0;j<arUL[i].childNodes.length;j++)
			{
				var theNode=arUL[i].childNodes[j];

				if(theNode.nodeType==Constant.NodeType.TEXT)
				{
					continue;
				}

				if(theNode.nodeName.toLowerCase()=="li")
				{
					this._closeRecursive(theNode);
				}
			}
		}
	}
};

_this._sniff=function(evt)
{
	var objSrc=_.src(evt);

	if(DropDownMenuController.getTimer())
	{
		clearTimeout(DropDownMenuController.getTimer());
	}

	DropDownMenuController.setTimer(
			setTimeout(function(){DropDownMenu._over(objSrc.id);},
		DropDownMenuController.getTimeout()));
};

_this._click=function(evt)
{
	var objSrc=_.src(evt);

	if(DropDownMenuController.getTimer())
	{
		clearTimeout(DropDownMenuController.getTimer());
	}

	DropDownMenuController.setTimer(setTimeout(function(){
		DropDownMenu._over(objSrc.id);},0));
};

_this._over=function(strElementID)
{
	this._hideSameLevel(strElementID);
	this._showChildren(strElementID);
	DropDownMenuController.setTimer(null);
};

_this._hideSameLevel=function(strElementID)
{
	var arUL=_.gtn("ul"),
		objNode,
		objUL,
		theNode,
		i=0,
		j=0;

	if(this._isMenuElement(strElementID))
	{
		objNode=_.o(strElementID);
		objUL=objNode.parentNode;

		while(objUL.nodeName.toLowerCase()!="ul")
		{
			objUL=objUL.parentNode;
		}

		for(i=0;i<objUL.childNodes.length;i++)
		{
			theNode=objUL.childNodes[i];

			if(theNode.nodeType==Constant.NodeType.TEXT)
			{
				continue;
			}

			if(theNode.nodeName.toLowerCase()=="li")
			{
				this._closeRecursive(theNode);
			}
		}
	}
	else
	{
		for(j=0;j<arUL.length;j++)
		{
			if(arUL[j].className!=DropDownMenuController.getMenuClass())
			{
				continue;
			}

			for(i=0;i<arUL[j].childNodes.length;i++)
			{
				if(arUL[j].childNodes[i].nodeType==Constant.NodeType.TEXT)
				{
					continue;
				}

				if(arUL[j].childNodes[i].nodeName.toLowerCase()=="li")
				{
					this._closeRecursive(arUL[j].childNodes[i]);
				}
			}
		}
	}
};

_this._closeRecursive=function(objNode)
{
	var arNode=objNode.childNodes,
		arChildNode,
		theNode,
		theChildNode,
		i=0,
		j=0;

	for(i=0;i<arNode.length;i++)
	{
		theNode=arNode[i];

		if(theNode.nodeType==Constant.NodeType.TEXT)
		{
			continue;
		}

		if(theNode.nodeName.toLowerCase()=="ul")
		{
			arChildNode=theNode.childNodes;

			for(j=0;j<arChildNode.length;j++)
			{
				theChildNode=arChildNode[j];

				if(theChildNode.nodeType==Constant.NodeType.TEXT)
				{
					continue;
				}

				if(theChildNode.nodeName.toLowerCase()=="li")
				{
					this._closeRecursive(theChildNode);
				}
			}

			theNode.className=theNode.className.remove(" hide");
			theNode.className=theNode.className.remove(" show");
			theNode.className+=" hide";
		}
	}
};

_this._showChildren=function(strElementID)
{
	var objNode=null,
		arNode=null,
		i=0;

	if(this._isMenuElement(strElementID))
	{
		objNode=_.o(strElementID);

		while(objNode.nodeName.toLowerCase()!="li")
		{
			objNode=objNode.parentNode;
		}

		arNode=objNode.childNodes;

		for(i=0;i<arNode.length;i++)
		{
			if(arNode[i].nodeType==Constant.NodeType.TEXT)
			{
				continue;
			}

			if(arNode[i].nodeName.toLowerCase()=="ul")
			{
				arNode[i].className=arNode[i].className.remove(" hide");
				arNode[i].className=arNode[i].className.remove(" show");
				arNode[i].className+=" show";
			}
		}
	}
};

_this._isMenuElement=function(strElementID)
{
	var objNode=_.o(strElementID);

	if(objNode)
	{
		while(objNode.parentNode)
		{
			if((objNode=objNode.parentNode).className==
				DropDownMenuController.getMenuClass())
			{
				return true;
			}
		}
	}

	return false;
};

var DropDownMenu=new _DropDownMenu();

/** ToolTip ------------------------------------------------------- **/

function ToolTip(elmTip,intTimeoutShow,intTimeoutHide,leftOffset,topOffset)
{
	this._lyr=new DynamicLayer(elmTip);

	if(_.defined(leftOffset))
	{
		this._leftOffset=leftOffset;
	}
	else
	{
		this._leftOffset=0;
	}

	if(_.defined(topOffset))
	{
		this._topOffset=topOffset;
	}
	else
	{
		this._topOffset=0;
	}

	this._xOffset=15+this._leftOffset;
	this._yOffset=15+this._topOffset;

	if(!_.defined(intTimeoutShow))
	{
		this._timeoutShow=1000;
	}
	else
	{
		this._timeoutShow=intTimeoutShow;
	}

	if(!_.defined(intTimeoutHide))
	{
		this._timeoutHide=1000;
	}
	else
	{
		this._timeoutHide=intTimeoutHide;
	}

	document._tip_object=this;

	this._hideThreadID=null;
	this._showThreadID=null;
	this._obj=_.o(elmTip);

	if(this.getWidth()<150)
	{
		this.setWidth(150);
	}

	this.hide();

	_.chain(document,"mouseout",this._hide,true);
}

ToolTip.prototype=new DynamicLayer();
_this=ToolTip.prototype;

_this.hide=function()
{
	if(this._lyr)
	{
		this._lyr.hide();
	}
};

_this.show=function(strTip)
{
	var deltaX=0,
		deltaY=0;

	if(_.coord())
	{
		this.changeContent(strTip);

		deltaX=_.coord().getX()+this._xOffset+this.getWidth()-
			WindowObject.getInnerDimension().getX()-
			WindowObject.getScrollOffset().getX();
		deltaY=_.coord().getY()+this._yOffset+this.getHeight()-
			WindowObject.getInnerDimension().getY()-
			WindowObject.getScrollOffset().getY();

		if(deltaX<0)
		{
			deltaX=0;
		}

		if(deltaY<0)
		{
			deltaY=0;
		}

		this.moveTo(
			_.coord().getX()+this._xOffset-deltaX,
			_.coord().getY()+this._yOffset-deltaY);

		if(this._getHideThreadID())
		{
			this.hide();
			clearTimeout(this._getHideThreadID());
			this._setHideThreadID(null);
		}

		if(!this.isVisible())
		{
			if(!this._getShowThreadID())
			{
				var self=this;
				this._setShowThreadID(setTimeout(function(){self._lyr.show();},
					this._timeoutShow));
			}
		}
		else{
			if(this._getShowThreadID())
			{
				clearTimeout(this._getShowThreadID());
				this._setShowThreadID(null);
			}
		}
	}
};

_this.passivate=function()
{
	_.unchain(document,"mouseout",this._hide);
};

_this._hide=function(evt)
{
	var obj=document._tip_object,
		objSelf=obj._lyr;

	if(obj._getShowThreadID())
	{
		clearTimeout(obj._getShowThreadID());
		obj._setShowThreadID(null);
	}

	if(objSelf.isVisible())
	{
		if(!obj._getHideThreadID())
		{
			obj._setHideThreadID(setTimeout(function(){objSelf.hide();},
				obj._timeoutHide));
		}
	}
	else{
		if(document._tip_object._getHideThreadID())
		{
			clearTimeout(obj._getHideThreadID());
			obj._setHideThreadID(null);
		}
	}
};

_this._setHideThreadID=function(intID)
{
	this._hideThreadID=intID;
};

_this._setShowThreadID=function(intID)
{
	this._showThreadID=intID;
};

_this._getHideThreadID=function()
{
	return this._hideThreadID;
};

_this._getShowThreadID=function()
{
	return this._showThreadID;
};

/** FormManager --------------------------------------------------- **/

function _FormManager()
{
}

_this=_FormManager.prototype;

_this.prepareFormField=function()
{
	var obj=null;

	for(var i=0;i<arguments.length;i++)
	{
		obj=_.o(arguments[i]);
		if(obj.nodeName.toLowerCase()=="textarea")
		{
			if(/\r\n/i.test(obj.value))
			{/*windows line break*/
				obj.value=obj.value.replace(/\r\n/ig,"[br /]");
				obj.value=_.safehtml(obj.value);
				obj.value=_.safews(obj.value);
				obj.value=obj.value.replace(/\[br \/\]/ig,"\r\n");
			}

			if(/\r/i.test(obj.value))
			{/*unix line break*/
				obj.value=obj.value.replace(/\r/ig,"[br /]");
				obj.value=_.safehtml(obj.value);
				obj.value=_.safews(obj.value);
				obj.value=obj.value.replace(/\[br \/\]/ig,"\r");
			}
		}
		else
		{
			obj.value=_.safehtml(obj.value);
			obj.value=_.safews(obj.value);
		}

	}
};

_this.repaintElement=function(objSrc,blnFocused)
{
	var strDefaultClass=objSrc._defaultClass;
	var strFocusClass=objSrc._focusClass;
	var strErrorClass=objSrc._errorClass;

	_.remclass(objSrc,[strErrorClass,strFocusClass,strDefaultClass]);

	if(objSrc._hasError)
	{
		_.addclass(objSrc,[strErrorClass]);
	}
	else
	{
		if(blnFocused)
		{
			_.addclass(objSrc,[strFocusClass]);
		}
		else
		{
			_.addclass(objSrc,[strDefaultClass]);
		}
	}
};

_this.isFormElement=function(elm)
{
	var theNodeName="";
	elm=_.o(elm);

	if(!elm)
	{
		return false;
	}

	theNodeName=elm.nodeName.toLowerCase();

	return theNodeName=="input"||theNodeName=="textarea"||
		theNodeName=="select"||theNodeName=="option";
};

var FormManager=new _FormManager();

/** FormField ----------------------------------------------------- **/

function FormField(elmField,strDefaultClass,strFocusClass,strErrorClass)
{
	this._obj=_.o(elmField);

	if(!this._obj)
	{
		alert("Error: FormObject not found!");
		return;
	}

	this._obj._defaultClass=strDefaultClass;
	this._obj._focusClass=strFocusClass;
	this._obj._errorClass=strErrorClass;

	_.chain(this.getObject(),"focus",this._changeFocus,true);
	_.chain(this.getObject(),"blur",this._changeBlur,true);


	_.remclass(this.getObject(),[strErrorClass,strFocusClass,strDefaultClass]);
	_.addclass(this.getObject(),[strDefaultClass]);
}

FormField.prototype=new CBObject();
_this=FormField.prototype;

_this.setError=function()
{
	this.getObject()._hasError=true;
	this.recalculate();
};

_this.clearError=function()
{
	this.getObject()._hasError=false;
	this.recalculate();
};

_this.hasError=function()
{
	return this.getObject()._hasError;
};

_this.recalculate=function()
{
	FormManager.repaintElement(this.getObject());
};

_this._changeFocus=function(evt)
{
	FormManager.repaintElement(_.src(evt),true);
};

_this._changeBlur=function(evt)
{
	FormManager.repaintElement(_.src(evt),false);
};

/** Preloader ----------------------------------------------------- **/

function _Preloader()
{
	this._arPreload=[];
	this._arQImage=[];
}

_this=_Preloader.prototype;

_this.enqueue=function()
{
	var strURL="",
		arPreload=this._arPreload,
		len=arguments.length;
	
	for(var i=0;i<len;i++)
	{
		strURL=arguments[i];
		if(!arPreload.contains(strURL))
		{
			arPreload.push(strURL);
		}
	}
};

_this.preload=function()
{
	var theImage;
	for(var i=0;i<this._arPreload.length;i++)
	{
		theImage=new Image();
		theImage.src=this._arPreload[i];
		this._arQImage.push(theImage);
	}
};

var Preloader=new _Preloader();

/** ImageButtonControler ------------------------------------------ **/

function _ImageButtonController()
{
	this._arObj=[];
}

_this=_ImageButtonController.prototype;

_this.add=function(strID,objButton)
{
	this._arObj[strID]=objButton;
};

_this.get=function(strID)
{
	return this._arObj[strID];
};

var ImageButtonController=new _ImageButtonController();

/** ImageButton --------------------------------------------------- **/

function ImageButton(elmID,strOnURL,strOffURL,intCurrentState)
{
	this._obj=_.o(elmID);

	if(!this.exists())
	{
		alert("Error:ImageButton: non existent id "+this.getID());
		return;
	}

	this._intState=intCurrentState;
	this._strURLOn=strOnURL;
	this._strURLOff=strOffURL;
	this._construct();
}

ImageButton.prototype=new CBObject();
_this=ImageButton.prototype;

_this.destruct=function()
{
	_.unchain(this.getObject(), "click", this._clickMe);
};

_this.isOn=function()
{
	return this._getButtonState==1;
};

_this.isOff=function()
{
	return !this.isOn();
};

_this.getButtonState=function()
{
	return this._intState;
};

_this.setButtonState=function(intState)
{
	this._intState=intState;
};

_this.getURL=function()
{
	if(this.getButtonState()===0)
	{
		return this._strURLOff;
	}

	return this._strURLOn;
};

_this._construct=function()
{
	var objSelf=this.getObject();

	if(objSelf.id)
	{
		ImageButtonController.add(objSelf.id,this);
	}

	if(objSelf.src)
	{
		objSelf.src=this.getURL();
		Preloader.enqueue(""+this._strURLOn);
		Preloader.enqueue(""+this._strURLOff);
	}

	_.chain(objSelf,"click",this._clickMe,true);
};

_this._clickMe=function(evt)
{
	var image=_.src(evt);
	var objButton=ImageButtonController.get(image.id);

	if(objButton.getButtonState()===0)
	{
		objButton.setButtonState(1);
		image.src=objButton.getURL();
	}
	else
	{
		objButton.setButtonState(0);
		image.src=objButton.getURL();
	}
};

/** ImageRolloverController --------------------------------------- **/

function _ImageRolloverController()
{
	this._arObj=[];
}

_this=_ImageRolloverController.prototype;

_this.add=function(strID,obj)
{
	this._arObj[strID]=obj;
};

_this.get=function(strID)
{
	return this._arObj[strID];
};

var ImageRolloverController=new _ImageRolloverController();

/** ImageRollover ------------------------------------------------- **/

function ImageRollover(elmID,strURL,strHoverURL,strBaseClass,strHoverClass)
{
	this._obj=new CBObject(elmID).getObject();
	this._strURL=strURL;
	this._strHoverURL=strHoverURL;
	this._strBaseClass=strBaseClass;
	this._strHoverClass=strHoverClass;
	this._construct();
}

ImageRollover.prototype=new CBObject();
_this=ImageRollover.prototype;

_this.getHoverURL=function()
{
	return this._strHoverURL;
};

_this.getURL=function()
{
	return this._strURL;
};

_this.getBaseClass=function()
{
	return this._strBaseClass;
};

_this.getHoverClass=function()
{
	return this._strHoverClass;
};

_this._construct=function()
{
	var obj=this.getObject();
	
	if(!this.exists())
	{
		alert("Error:ImageRollover: non existent id "+this.getID());
		return;
	}

	ImageRolloverController.add(this.getID(),this);

	Preloader.enqueue(""+this._strURL);
	Preloader.enqueue(""+this._strHoverURL);

	_.chain(obj,"mousemove",this._onMouseMove,true);
	_.chain(obj,"mouseout",this._onMouseOut,true);

	if(obj.parentNode&&obj.parentNode.nodeName.toLowerCase()=="a")
	{
		_.chain(obj.parentNode,"focus",this._onMouseMove,true);
		_.chain(obj.parentNode,"blur",this._onMouseOut,true);
	}
};

_this._onMouseMove=function(evt)
{
	var src=_.src(evt);
	var mySelf=null;
	var obj=null;
	var arNode=null;
	var len=0;

	if(src&&src.nodeName.toLowerCase()=="a")
	{
		arNode=src.childNodes;
		len=arNode.length;

		for(var i=0;i<len;i++)
		{
			if(arNode[i].nodeType==Constant.NodeType.TEXT)
			{
				continue;
			}

			if(arNode[i].nodeName.toLowerCase()=="img"&&arNode[i].id)
			{
				mySelf=ImageRolloverController.get(arNode[i].id);
				obj=mySelf.getObject();
			}
			else
			{
				continue;
			}
		}
	}
	else
	{
		if(src&&src.id)
		{
			src=src.id;
		}
		else
		{
			return;
		}

		mySelf=ImageRolloverController.get(src);
		obj=mySelf.getObject();
	}

	if(obj&&obj.src)
	{
		obj.src=mySelf.getHoverURL();
	}

	_.remclass(obj,[mySelf.getBaseClass(),mySelf.getHoverClass()]);
	_.addclass(obj,[mySelf.getHoverClass()]);
};

_this._onMouseOut=function(evt)
{
	var src=_.src(evt),
		mySelf=null,
		obj=null,
		arNode=null,
		len=0;

	if(src&&src.nodeName&&src.nodeName.toLowerCase()=="a")
	{
		arNode=src.childNodes;
		len=arNode.length;

		for(var i=0;i<len;i++)
		{
			if(arNode[i].nodeType==Constant.NodeType.TEXT)
			{
				continue;
			}

			if(arNode[i].nodeName.toLowerCase()=="img"&&arNode[i].id)
			{
				mySelf=ImageRolloverController.get(arNode[i].id);
				obj=mySelf.getObject();
			}
			else
			{
				continue;
			}
		}
	}
	else
	{
		if(src&&src.id)
		{
			src=src.id;
		}
		else
		{
			return;
		}

		mySelf=ImageRolloverController.get(src);
		obj=mySelf.getObject();
	}

	if(obj&&obj.src)
	{
		obj.src=mySelf.getURL();
	}

	_.remclass(obj,[mySelf.getBaseClass(),mySelf.getHoverClass()]);
	_.addclass(obj,[mySelf.getBaseClass()]);
};
