/***************************************************************************
*				maborak.js
*                        ------------------------
*   Copyleft	: (c) 2007 maborak.com <maborak@maborak.com>
*   Version	: 0.6
*
***************************************************************************/

/***************************************************************************
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.
*
***************************************************************************/
var maborak = function(){
	this.info={
		version	:"0.3",
		name	:"maborak",
		file	:"maborak.js"
	},
	/**
	* Make this Class
	* @param options = Object{Options.for.class} || {};
	* @access		 = Public;
	*/
	this.make=function(options)
	{
		this.protoCore();
		this.module={
			debug:function(flag){
				this.flag = flag || false;
				this.log=function(v)
				{
					if(typeof console!='undefined' && this.flag===true)
					{
						console.log(v || '');
					}
				};
				return this;
			}
		}.expand(this);
		this.options={
            thisIsNotPM:false
        }.concat(options || {});
		this.report	= new this.bitacora();
		this.loadMethods([this.checkBrowser],this);
		this.event	= this.factory(this.mantis,true);
		this.tools	= this.factory(this.extended.tools,true);
		this.file	= this.factory(this.fileCore,true);
		this.dom	= this.factory(this.extended.D0M,true);
		this.iphone	= this.factory(this.iphoneBrowser,true);
		this.cookie	= this.factory(this.extended.cookie,true);
		this.Package	= new this.PackageCore(this,this.file.db);

		this.report.add("Class loaded.");
		this.info.base=this.tools.baseJS(this.info.file);
		this.info.images=this.info.base+"images/";
		this.path_root=this.tools.path_root(this.info.base)+"/";

		if(this.options.modules){
			this.Package.Load(this.options.modules,{Instance:this,Type:"module"});
		}
		if(this.options.files){
			this.Package.Load(this.options.files,{Type:"file"});
		}
		this.exec(this.fix.memoryLeak);

		/* create Stylesheet BEGIN  */
		var st	=$dce('link');
		st.rel	='stylesheet';
		st.type	='text/css';
		st.href	=this.info.base+'stylesheet/default.css';
		this.dom.capture("tag.head 0").appendChild(st);
		/* create Stylesheet END  */
		this.expand(this);
		return this;
	};
	this.factory=function(Class,create)
	{
		var cl = (typeof Class==="function")?Class:function(){};
		cl.prototype.parent = this;
		if(create===true)
		{
			//return new cl().expand();
			return new cl();
		}
		else
		{
			return cl;
		}
	},
	this.Class=function()
	{
		var Vc = function(){};
		return new Vc();
	},
	/**
	* @class Manage Patterns Design
	*/
	this.pattern={
		observer:function(event)
		{
			this.event = event;
			this.g="aaa";
			this.db = [];
			this.register=function(launch,Class)
			{
				this.event = event;
				this.Class = Class;
				this.launch = launch;
				if(this.verify())
				{
					return this.write();
				}
				return true;
			};
			this.verify=function()
			{
				return (typeof this.launch==="function")?true:false;
			};
			this.write=function()
			{
				var cap = {
					//update:this.parent.closure({instance:this,method:this.update}),
					//unregister:this.parent.closure({instance:this,method:this.unregister,args:this.db.length})
					update:this.update,
					unregister:this.unregister.args(this.db.length)
				};
				this.db.push(this.launch);
				if(this.Class)
				{
					this.Class.observer = cap;
				}
				delete this.event;
				delete this.Class;
				delete this.launch;
				return this.db.length-1;
			};
			this.update=function()
			{
				var ln = this.db.length;
				for(i=0;i<ln;i++)
				{
					if(typeof this.db[i]=="function")
					{
						this.db[i]();
					}
				}
			};
			this.unregister=function(uid)
			{
				//alert(this.db[uid])
				if(this.db[uid])
				{
					this.db[uid]=null;
				}
			};
			this.expand(this);
		}
	};
	/**
	* Private functions{
	*/
	var argumentsToArray=function(a){
		var args=[];
		for(var i=0;i<a.length;i++){args.push(a[i]);};
		return args;
	};
	var tagScript = '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)';
	/**
	* }Private functions
	*/
	this.tmp= {
		rpc:{}
	};
	this.charset="utf-8";
	/**
	* Make Core Functions
	* @extends String || Array || Object
	*/
	this.protoCore=function()
	{
		/**
		 * document.getElementById
		 * @param {Object || String} el
		 */
		window['$'] = function(el){
			return (typeof el == "string") ? document.getElementById(el) : el;
		};
		/**
		 * document.createElement
		 * @param {String} el
		 */
		window['$dce'] = function(el){
			return document.createElement(el);
		};
		/**
		 * document.getElementsByName
		 * @param {Object || String} el
		 */
		window['$n'] = function(el){
			return (typeof el == "string")?document.getElementsByName(el):el;
		};
		Array.prototype.isArray		= true;
		Array.prototype.isObject	= false;
		/**
		* Only Int values in Array
		* @return Array
		*/
		Array.prototype.onlyInt		= function()
		{
			var valid=[];
			for(var i=0;i<this.length;i++)
			{
				if(!isNaN(this[i]))
				{
					valid.push(parseInt(this[i],10));
				}
			}
			return valid;
		};
		/**
		* Check if a value exists in an Array
		* @return Boolean
		*/
		Array.prototype.inArray	= function(search)
		{
			var valid=[];
			for(var i=0;i<this.length;i++)
			{
				if(this[i]===search)
				{
					return true;
				}
			}
			return false;
		};
		/**
		* Fill an array with values
		* @return Array
		*/
		Array.prototype.fill		= function(startIndex,cant,value)
		{
			for(var i=0;i<cant;i++)
			{
				this.splice(startIndex+i,0,value);
			}
			return this;
		};
		/**
		* Convert (Array || Object) to String
		* @param {Boolean} strict Optional: Exclude prototype (Methods && Properties)
		* @return String
		*/
		Array.prototype.toStr = Object.prototype.toStr	= function(strict)
		{
			var val, output = "";
			output += "{";
			for (var i in this) {
				val = this[i];
				if((!strict && this.propertyIsEnumerable(i)) || strict===true)
				{
					switch (typeof val) {
						case ("object"):
						if(typeof val.childNodes!="undefined")
						{
							output += i + ":[DOM.Object],\n";
						}
						else if (val.isArray || val.isObject) {
							output += i + ":" + val.toStr(strict) + ",\n";
						} else {
							output += i + ": Element||Event,\n\n";
						}
						break;
						case ("string"):
						output += i + ":'" + val + "',\n";
						break;
						case ("function"):
						output += i + ":FUNCTION,\n";
						break;
						default:
						output += i + ":" + val + ",\n";
					}
				}
			}
			output = output.substring(0, output.length-1) + "}";
			return output;
		};
		Array.prototype.indexOf=function(val)
		{
			for (var i = 0; i < this.length; i++)
			{
				if (this[i] == val){return i;}
			}
			return -1;
		};
		/**
		* Remove duplicate values
		* @return Array
		*/
		Array.prototype.unique = function()
		{
			if(this.length<2){return this;}
			var a = [], i, l = this.length;
			for( i=0; i<l; i++ ){
				if(a.indexOf(this[i])< 0 )
				{
					a.push( this[i]);
				}
			}
			return a;
		};
		/**
		* Fetch a key from an Array
		* @param {String|Boolean|Int|Object|Array} value Value to search
		* @return Int
		*/
		Array.prototype.key = function(value)
		{
			for(var i=0;i<this.length;i++) {
				if(this[i]===value){return i;}
			}
			return false;
		};
		/**
		* Return a random element
		* @param {Int} range Up to range
		* @return Value random
		*/
		Array.prototype.random = function(range)
		{
			var i = 0, l = this.length;
			if(!range) { range = this.length; }
			else if( range > 0 ) { range = range % l; }
			else { i = range; range = l + range % l; }
			return this[ Math.floor( range * Math.random() - i ) ];
		};
		/**
		* Map array elements
		* @param {Function} fun
		* @return Function
		*/
		Array.prototype.map = function(fun)
		{
			if(typeof fun!=="function"){return false;}
			var i = 0, l = this.length;
			for(i=0;i<l;i++)
			{
				fun(this[i]);
			}
			return true;
		};
		/**
		* Randomly interchange elements
		* @param {Boolean} recursive Shuffle recursive Array elements.
		* @return Array
		*/
		Array.prototype.shuffle = function(recursive)
		{
			var i = this.length, j, t;
			while( i ) {
				j = Math.floor( ( i-- ) * Math.random() );
				t = recursive && typeof this[i].shuffle!=='undefined' ? this[i].shuffle() : this[i];
				this[i] = this[j];
				this[j] = t;
			}
			return this;
		};
		/**
		* Eval scripts
		* @return String
		*/
		Array.prototype.evalScript = function(extracted)
		{
    		var s=this.map(function(sr){
				//window.setTimeout((sr.match(new RegExp(tagScript, 'im')) || ['', ''])[1],0);
				var sc=(sr.match(new RegExp(tagScript, 'im')) || ['', ''])[1];
				if(window.execScript){
					window.execScript(sc || " ");
				}
				else
				{
					//ndow.eval(code);
					window.setTimeout(sc,0);
				}
				//eval(sc);
			});
			return true;
		};
		/**
		* Clear Array
		* @return Array;
		*/
		Array.prototype.clear=function()
		{
			return this.splice(0,this.length);
		};
		/**
		* Copy Array
		* @return Array;
		*/
		Array.prototype.copy=function()
		{
			return this.slice(0,this.length);
		};
		/**
		* Insert data in Array key
		* @return Array
		*/
		Array.prototype.insert = function(key,value)
		{
			var na  = this.copy();
			value	= (!value || value.isArray===false)?[value]:value;
			this.clear();
			for(var i=0;i<na.length;i++)
			{
				if(i===key)
				{
						for(var j=0;j<value.length;j++)
						{
							this.push(value[j]);
						}
				}
				this.push(na[i]);
			}
			return this;
		};
		/**
		* Convert array to select data
		* @return Array
		*/
		Array.prototype.toSelect = function()
		{
            var s = [];
			for(var i=0;i<this.length;i++)
			{
			    s.push({value:i,text:this[i]});
			}
			return s;
		};

		Object.prototype.isObject	= true;
		Object.prototype.isArray	= false;

		/**
		* propertyIsEnumerable for Safari
		* @return Boolean
		**/
		Object.prototype.propertyIsEnumerable=function(i)
		{
			return (typeof Object.prototype[i]==="undefined")?true:false;
		};
		/**
		* Length of Object
		* @return Int
		*/
		/*Object.prototype.length	= function()
		{
			var j=0;
			for (var i in this) {
				if(this.propertyIsEnumerable(i))
				{
					j+=1;
				}
			}
			return j;
		};*/
		/**
		* Concat Object
		* @param {Object} obj Object
		* @return {Object} this
		*/
		Object.prototype.concat = function(obj)
		{
			for (var i in obj)
			{
				if(obj.propertyIsEnumerable(i))
				{
					this[i]=obj[i];
				}
			}
			return this;
		};
		/**
		* es| Obtener el valor de un Objeto a partir de su Key
		* @param {Int} id Key of object (1,2,3,4,5)
		* @return Key value
		*/
		Object.prototype.get_by_key= function(id,key)
		{
			var j=0;
			for (var i in this) {
				if(this.propertyIsEnumerable(i))
				{
					if(id===j){return (key)?i:this[i];}
					j+=1;
				}
			}
			return false;
		};
		/**
		* es| Verificar si existe un key
		* @param {String} key Key
		* @return Boolean
		*/
		Object.prototype.isset_key= function(key)
		{
			for (var i in this) {
				if(this.propertyIsEnumerable(i))
				{
					if(key===i){return true;}
				}
			}
			return false;
		};

		/**
		* es| Asignarle prototype.parent a todas las funciones
		* @param {Object} obj
		* @return {Object} this
		*/
		Object.prototype.setParent	= function(obj)
		{
			for (var i in this) {
				if(this.propertyIsEnumerable(i) && typeof this[i]==="function")
				{
					this[i].prototype.parent=obj || false;
				}
			}
			return this;
		};
		/**
		* es| Excluir objetos tipo DOM
		* @param {Boolean}
		*/
		Object.prototype.isObjectStrict	= function()
		{
			return (this.appendChild)?false:true;
		};
		/**
		* es| Expandir una Clase dentro de sus objetos literales
		* @param {Object}
		*/
		Object.prototype.expand=function(Class,recursive)
		{
			Class=Class || this;
			for(var i in this)
			{
				if(this.propertyIsEnumerable(i) && (typeof this[i]==="function" || (recursive===true && typeof this[i]==="object" && this[i].isObjectStrict())))
				{
					try{
						if(typeof this[i]==="function")
						{
							//kkk.push(this[i]);
							this[i]=this[i].extend(Class);
						}
						else
						{
							this[i]=this[i].expand(Class,recursive);
						}
					}
					catch(e){
						this[i]=this[i];
					}
				}
				else
				{
					//alert(i);
				}
			}
			return this;
		};
		Function.prototype.isObject	= false;
		Function.prototype.isArray	= false;
		/**
		* es| Expandir funciÃ³n en una Clase
		* @param {Funcion}
		*/
		Function.prototype.extend=function(Class)
		{
			try{
				//kkk.push(this);
				var oThis=this;
				var args=argumentsToArray(arguments);
				args.splice(0,1);
				return function()
				{
					return oThis.apply(Class,argumentsToArray(arguments).concat(args));
				};
			}
			catch(e){
				return this;
			}
		};
		/**
		* es| AÃ±adir argumentos a una funciÃ³n
		* @param {Function}
		*/
		Function.prototype.args=function()
		{
			var oThis=this;
			var args=argumentsToArray(arguments);
			return function()
			{
				return oThis.apply(oThis,argumentsToArray(arguments).concat(args));
			};
		};
		String.prototype.isAlphaUS=function()
		{
			var a = this.split("");
			var b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_".split("");
			//alert(b.length)
			for(var i=0;i<a.length;i++)
			{
				if(!b.inArray(a[i])){
					return false;
				}
			}
			return true;
		};
		/**
		* Strip whitespaces from the beginning and end of String
		* @return String with whitespaces stripped
		*/
		String.prototype.isString=true;
		/**
		* Strip whitespaces from the beginning and end of String
		* @return String with whitespaces stripped
		*/
		String.prototype.trim = function(){
			return( this.replace(new RegExp("^([\\s]+)|([\\s]+)$", "gm"), "") );
		};
		/**
		* Strip whitespaces from the beginning of String
		* @return String
		*/
		String.prototype.leftTrim = function(){
			return( this.replace(new RegExp("^[\\s]+", "gm"), "") );
		};
		/**
		* Strip whitespaces from the end of String
		* @return String
		*/
		String.prototype.rightTrim = function(){
			return( this.replace(new RegExp("[\\s]+$", "gm"), "") );
		};
		/**
		* Strip HTML tags from a string
		* @return String
		*/
		String.prototype.stripTags = function()
		{
			return this.replace(/<\/?[^>]+>/gi, '');
		};
		/**
		* Convert special characters to HTML entities
		* @return String
		*/
		String.prototype.escapeHTML = function()
		{
			var div = $dce('div');
			var text = document.createTextNode(this);
			div.appendChild(text);
			return div.innerHTML;
		};
		/**
		* Convert special HTML entities back to characters
		* @return String
		*/
		String.prototype.unescapeHTML = function()
		{
			var div = $dce('div');
			div.innerHTML = this.trim();
			return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
		};
		/**
		* Search and Replace
		* @return String
		*/
		String.prototype.sReplace = function(search,replace)
		{
			search = search || "";
			replace= replace || "";
			var re = new RegExp(search,"g");
			return this.replace(re,replace);
		};
		/**
		* Camelize String (text-align -> textAlign)
		* @return String
		*/
		String.prototype.camelize = function ()
		{
			var oStringList = this.split("-");
			if (oStringList.length == 1) {
				return oStringList[0];
			}
			var camelizedString = this.indexOf("-")===0 ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) : oStringList[0];
			for (var i = 1, len = oStringList.length; i < len; i++)
			{
				var s = oStringList[i];
				camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
			}
			return camelizedString;
		};
		/**
		* Convert String to Array
		* @return Array
		*/
		String.prototype.toArray = function()
		{
			return this.split("");
		};
		/**
		* extract script fragment
		* @return String
		*/
		String.prototype.extractScript = function()
		{
			var matchAll = new RegExp(tagScript, 'img');
    		return (this.match(matchAll) || []);
		};
		/**
		* Eval script fragment
		* @return String
		*/
		String.prototype.evalScript = function()
		{
    		return (this.match(new RegExp(tagScript, 'img')) || []).evalScript();
		};
		/**
		* strip script fragment
		* @return String
		*/
		String.prototype.stripScript = function()
		{
			return this.replace(new RegExp(tagScript, 'img'), '');
		};
		/**
		*	XMLSerializer Crossbrowser
		*/
		if((typeof XMLSerializer)==='undefined')
		{
			window.XMLSerializer = function() {
				this.toString=function()
				{
					return "[object XMLSerializer]";
				};
				this.serializeToString=function(xml){
					return xml.xml || xml.outerHTML || "Error XMLSerializer";
				};
			};	
		}
	};
	/**
	* Load methods
	* @param methods = Array[Method || Array[Method,[Argument1,Argument2,...],return]];
	* @param instance= Class;
	* @example:
	* 		this.loadMethods([
	* 				this.proto,
	*				[this.checkBrowser,['argument1',More...,12]]
	*		],this);
	* @access		 = Public;
	*/
	this.loadMethods = function(methods,instance)
	{
		var _return_ = [];
		var tmp;
		for(var i=0;i<methods.length;i++)
		{
			if(methods[i])
			{
				if(methods[i].isArray)
				{
					if(typeof methods[i][0]=="function")
					{
						var method = (methods[i][1])?((methods[i][1].isArray)?methods[i][1]:[methods[i][1]]):false;

						if(method===false)
						{
							tmp = methods[i][0].apply(instance);
						}
						else
						{
							tmp = methods[i][0].apply(instance,method);
						}
						if(methods[i][2]===true){_return_.push(tmp);}
					}
				}
				else if(typeof methods[i]=="function")
				{
					methods[i].apply(instance);
				}
			}
		}
		return (_return_.length==1)?_return_[0]:_return_;
	};
	/**
	* Identify User-Agent of Browser
	* @result
	* 	isIE	= "Microsoft Internet Explorer"
	* 	isNS	= "Netscape"
	* 	isFF	= "Mozilla Firefox"
	* 	isSF	= "Safari"
	* 	isGK	= "Browsers based on Gecko"
	* 	isOP	= "Opera"
	* @access	= Private;
	*/
	this.checkBrowser = function()
	{
		var userAgent=navigator.userAgent;
		var u;
		this.browser={
			isIE:((userAgent.indexOf('MSIE')>=0)?true:false),
			isNS:((userAgent.indexOf('Netscape6/')>=0)?true:false),
			isFF:((userAgent.indexOf('Firefox')>=0)?true:false),
			isSF:((userAgent.indexOf('Safari')>=0)?true:false),
			isGK:((userAgent.indexOf('Gecko')>=0)?true:false),
			isIphone:((userAgent.indexOf('iPhone')>=0)?true:false),
			isOP:((userAgent.indexOf('Opera')>=0)?true:false)
		};
		this.browser.isIE=(this.browser.isOP)?false:this.browser.isIE;
		var checkFor=["MSIE","Netscape/6","Firefox","Safari","Gecko","Opera","iPhone"];
		for(var i=0;i<checkFor.length;i++)
		{
			var j = userAgent.indexOf(checkFor[i]);
			this.browser.version = userAgent+"::::"+userAgent.substr(j + checkFor[i].length);
		}
	};
	/**
	* @class		 = Event manager
	*/
	this.mantis = function()
	{
		this.db=[];
		this.flush=function()
		{
			var i=0;
			while (this.db.length > 0)
			{
				if(this.db[0] && this.db[0].isObject===true)
				{
					this.remove(this.db[0]._object_,this.db[0]._event_,this.db[0]._function_,this.db[0]._bumble_);
				}
				this.db.splice(0,1);
			}
		};
		/**
		* Add new Event;
		* @param _object_	= DOMelement;
		* @param _event_	= event [load,focus,etc];
		* @param _function_ = Function || Object{method,instance,[arguments[Array],event[Boolean],argument_is_array[Boolean]]} || Function[virtual];
		* @param _bumble_	= true || false;
		* @example:
		*
		*	1)	Callback simple:
		*		this.event.add(Input,"unload",FunctionX);
		*
		*	2)	Callback is Object
		*		this.event.add(Input,"click",{
		*			method	: this.other,
		*			instance: this
		*		});
		*	3)	Callback is Object & Advanced options
		*		this.event.add(Input,"click",{
		*			method	: this.other,
		*			instance: this
		*			arguments:[989898,767676], //Arguments to Function Callback
		*			event	:true // es| Expandir evento como argumento
		*		});
		*	4)	Callback to Virtual Instance
		*		this.event.add(Input,"click",leimnud.closure({
		*			method:this.changes,
		*			instance:this,
		*			arguments:98989898
		*		}));
		*	5)	Callback to Virtual Function
		*		this.event.add(Input,"click",leimnud.closure({
		*			Function:foo,
		*			arguments:[bla,99]
		*		}));
		*/
		this.add=function(_object_,_event_,_function_,_bumble_)
		{
			_function_=(_function_.isObject)?this.parent.closure(_function_):_function_;
			_object_ = this.parent.dom.element(_object_);
			if (_object_.addEventListener)
			{
				_object_.addEventListener(_event_,_function_,((_bumble_===true)?true:false));
			}
			else if(_object_.attachEvent)
			{
				_object_.attachEvent("on"+_event_,_function_);
			}
			else
			{
				this.report("Event registration not supported");
			}
			var event = {
				_object_	:_object_,
				_event_		:_event_,
				_function_	:_function_,
				_bumble_	:((_bumble_===true)?true:false)
			};
			this.db.push(event);
			return (this.db.length-1);
		};
		/**
		* Remove Event;
		* @param {DOM Object} _object_	= DOMelement;
		* @param {event} _event_	= event [load,focus,etc];
		* @param {Function} _function_ = Function || Object{method,instance,[arguments[Array],event[Boolean],argument_is_array[Boolean]]} || Function[virtual];
		* @param {Boolean} _bumble_	= true || false;
		* @example:
		*		Add new Event Examples.
		*/
		this.remove=function(_object_,_event_,_function_,_bumble_,uidInDB)
		{
			_function_=(_function_.isObject)?this.parent.closure(_function_):_function_;
			_object_ = this.parent.dom.element(_object_);
			if (_object_.removeEventListener)
			{
				_object_.removeEventListener(_event_,_function_,((_bumble_===true)?true:false));
			}
			else if(_object_.detachEvent)
			{
				_object_.detachEvent("on"+_event_,_function_);
			}
			if(uidInDB)
			{
				if(uidInDB==(this.db.length-1))
				{
					this.db.pop();
				}
				else
				{
					this.db[uidInDB]=null;
				}
			}
		};
		/**
		* es| Remover evento basado en Uid
		*/
		this.removeFromUid=function(uid)
		{
			if(this.db[uid])
			{
				var e = this.db[uid];
				this.remove(e._object_,e._event_,e._function_,e._bumble_,uid);
			}
		};
		/**
		* Flush Collection events from DB
		* @param	{Array} arrayEventsInDB Array of Events.
		*/
		this.flushCollection=function(arrayEventsInDB)
		{
			var l=arrayEventsInDB.length;
			for(i=0;i<l;i++)
			{
				this.remove(this.db[arrayEventsInDB[i]]._object_,this.db[arrayEventsInDB[i]]._event_,this.db[arrayEventsInDB[i]]._function_,this.db[arrayEventsInDB[i]]._bumble_,arrayEventsInDB[i]);
			}
		};
		/**
		* es| Reportar fallos en el registro de eventos
		* @param {String} text String;
		*/
		this.report=function(text)
		{
			if(this.parent && this.parent.report)
			{
				this.parent.report.add(text);
			}
		};
		/**
		* Captura DOM event
		* @param {Object} event
		* @return DOM
		*/
		this.dom=function(event)
		{
			return event.target || window.event.srcElement;
		};
		/**
		* es| Arreglar fallo IE (sobreposiciÃ³n de eventos)
		* @param {Object} event
		*/
		this.Null=function(event)
		{
			if(event.preventDefault)
			{
				event.preventDefault();
			}
			event.returnValue = false;
		};
		this.expand(this);
	};
	/**
	* @class	= System report
	* @access	= Public;
	*/
	this.bitacora=function()
	{
		this.db=[];
		/**
		* @param	text = String;
		* @access 	Public;
		*/
		this.add=function(text)
		{
			this.db.push(text);
		};
	};
	/**
	* es| Objeto con bugs Crossbrowser.
	* @access	= Public;
	*/
	this.fix={
		memoryLeak:function()
		{
			this.event.add(window,"unload",this.event.flush);
		}
	};
	/**
	* es |  Ejecuta un mÃ©todo de forma encapsulada
	*		especial para funciones en Objetos Literales
	* @param _function_ = method
	* @param _arguments_= arguments || false
	* @param _return_	= true || false
	* @param _instance_	= instance || this
	* @access	= Public;
	*/
	this.exec=function(_function_,_arguments_,_return_,_instance_)
	{
		/**return ((_instance_)?_instance_:this).loadMethods([[_function_,((_arguments_)?_arguments_:null),_return_ || false]],((_instance_)?_instance_:this));*/
		return this.loadMethods([[_function_,((_arguments_)?_arguments_:null),_return_ || false]],((_instance_)?_instance_:this));
	};
	/**
	* es|  Crear funciones virtuales
	* @param {Object} options = {
	*		method	:Method,
	*		instance:Instance,
	*		Function:Function,
	*		arguments:Array["sample",var,222]
	*		event	:true || false,   		#Expand event?
	*		argument_is_array:true || false		#Arguments is Array?
	*	} Options
	* @example:
	*	1)	Virtual Instance
	*		var virtualFunction = leimnud.closure({
	*			method:this.foo,
	*			instance:this,
	*			arguments:98989898
	*		});
	*	2)	Virtual Function
	*		var virtualFunction = leimnud.closure({
	*			Function:foo,
	*			arguments:[bla,99]
	*		});
	*/
	this.closure=function(options)
	{
		var method	=options.method;
		var instance=options.instance;
		var args	=(options.args || (typeof options.args=="number" && options.args===0))?options.args:false;
		var _function=options.Function || false;
		var isArr	=options.args_is_array || false;
		var _event	=options.event || false;
		var rf		=options.Return || false;
		return function(hEvent)
		{
			//window.status="EEE=> "+(h || window.event);
			var argss=(args===false)?false:((args.isArray && isArr===false)?args:[args]);
			//window.status = typeof _event+":"+hEvent+":"+_event;
			//window.status = args;

			var param=(_event)?[(hEvent || window.event)].concat(argss):argss;
			if(_function===false)
			{
				//window.status="EventHandler:=> "+param;
				method.apply(instance,param || [null]);
			}
			else
			{
				_function.apply(_function,param || [null]);
			}
			return rf;
		};
	};
	/**
	* es| Clase para cargar archivos,mÃ³dulos,objetos
	*
	* @class			= Package Manager;
	* @param	parent	= Leimnud Class || Leimnud Instance;
	* @param	db		= Class File Manager;
	* @access			= Public;
	*/
	this.PackageCore=function(parent,db)
	{
		this.parent	= parent || false;
		this.db		= db || false;
		/**
		* Load new Package
		*/
		this.Load	= function(file,options)
		{
			this.options	=	{
				zip:false
			}.concat(options || {});			
			if(arguments.length<2 || !this.check()){return false;}
			this.toLoad = ((this.options.Absolute===true)?this.options.Path:file).split(",");
			if(this.type === 'module' && (this.options.zip===true || this.parent.options.zip===true))
			{				
				var tl = [];
				for (var i = this.toLoad.length; i > 0; i--)
				{
					this.name = this.toLoad[this.toLoad.length - i];
					if (!this.isset()) {
						tl.push(this.name);
						this.write(false);
					}
				}
				//alert(this.parent.options.thisIsNotPM);
				if (tl.length > 0) {
					var script = $dce("script");
					this.parent.dom.capture("tag.head 0").appendChild(script);
					script.src = (this.parent.options.inGulliver===true)?this.path+'maborak.loader.js':this.path + 'server/maborak.loader.php?load=' + tl.join(',');
//					script.src = this.path + 'maborak.loader.js';
//                    alert(script.src)
					script.type = "text/javascript";
					script.charset = this.parent.charset;
					if (this.type == "module") {
						this.write(script);
					}
				}
			}
			else
			{
				for (var i = this.toLoad.length; i > 0; i--)
				{
					this.name = this.toLoad[this.toLoad.length - i];
					if (!this.isset()) {
						//if (this.options.noWrite === false && this.type!='module')
						//{
							this.src = this.source();
							var script = $dce("script");
							this.parent.dom.capture("tag.head 0").appendChild(script);
							//script.src	=	this.src+"?d="+Math.random();
							script.src = this.src;
							script.type = "text/javascript";
							script.charset = this.parent.charset;
						//}
						if (this.type == "module") {
							this.write(script);
						}
					}
				}
			}
			delete this.Class;
			delete this.file;
			delete this.info;
			delete this.path;
			delete this.toLoad;
			delete this.type;
			delete this.src;
			return true;
		};
		/**
		* es| Obtener la ruta del archivo,modulo a cargar
		*
		* @access	= Private;
		*/
		this.source=function()
		{
			if(this.type=="module")
			{
				return this.path+"module."+this.name+".js";
			}
			else if(this.type=="file")
			{
				var nroute= (this.options.Absolute===true)?this.path:this.path+this.name+"/core/"+this.name+".js";
				return nroute;
			}
			return false;
		};
		/**
		* Probe conditions
		*
		* @access	= Private;
		*/
		this.check	= function()
		{
			if(!this.db || !this.options.Type){
				return false;
			}
			this.type	= this.options.Type.toLowerCase();
			if(this.type=="file")
			{
				this.path	= this.options.Path || this.parent.path_root;
				return true;
			}
			else if(this.type=="module")
			{
				this.Class=(this.options.Instance)?this.options.Instance:((this.options.Class)?this.options.Class.prototype:false);
				if(this.Class===false || !this.Class.info){return false;}
				if(!this.Class.module)
				{
					this.Class.module={};
				}
				this.path	= this.options.Path || this.Class.info.base || false;
				return (this.path===false)?false:true;
			}
			else
			{
				return false;
			}
		};
		/**
		* Prevent duplicate
		*
		* @access	= Private;
		*/
		this.isset	= function()
		{
			if(this.type=="module")
			{
				for(var i=this.db.length;i>0;i--)
				{
					if(this.db[this.db.length-i].name==this.Class.info.name)
					{
						this.file=this.db[this.db.length-i];
						break;
					}
				}
				if(!this.file)
				{
					this.db.push({
						name:this.Class.info.name,
						Class:this.Class,
						_Package_:[]
					});
					this.file=this.db[this.db.length-1];
				}
				for(i=this.file._Package_.length;i>0;i--)
				{
					var nm=this.file._Package_[this.file._Package_.length-i];
					if(nm.name==this.name && nm.type==this.type)
					{
						return true;
					}
				}
				this.Class.module[this.name]=true;
				return false;
			}
			else if(this.type=="file")
			{
				return false;
			}
			return false;
		};
		this.write	= function(script,option)
		{
			this.file._Package_.push({
				type	:this.type,
				loaded	:false,
				name	:this.name,
				script	:script,
				onLoad	:this.options.onLoad || false
			});
		};
		this.Public	= function(Package)
		{
			if(!Package || !Package.info || !Package.info.Class || !Package.info.Name || !Package.info.Type || !Package.content){return false;}
			for(var i=this.db.length;i>0;i--)
			{
				if(this.db[this.db.length-i].name==Package.info.Class)
				{
					this._file_=this.db[this.db.length-i];
					break;
				}
			}
			if(!this._file_)
			{
				return false;
			}
			else
			{
				this.tmpPgk=this._file_.Class.module[Package.info.Name];
				if(this.tmpPgk===true)
				{
					if(typeof Package.content=="function")
					{
						Package.content.prototype.parent=this._file_.Class;
					}
					else if(typeof Package.content=="object")
					{
						Package.content.setParent(this._file_.Class);
						//alert(Package.content+":"+this._file_.Class)
					}
					this._file_.Class.module[Package.info.Name]=Package.content;
					for(i=this._file_._Package_.length;i>0;i--)
					{
						var nm=this._file_._Package_[this._file_._Package_.length-i];
						if(nm.name==Package.info.Name && nm.type==Package.info.Type)
						{
							nm.loaded=true;
							if(!this.parent.browser.isIE)
							{
								this.parent.dom.remove(nm.script);
							}
							delete nm.script;
							if(nm.onLoad)
							{
								nm.onLoad();
							}
							break;
						}
					}
					delete this._file_;
				}
			}
			return true;
		};
	};
	this.fileCore	=function()
	{
		this.db		= [];
	};
	this.extended={
		cookie:function()
		{
			this.set = function(name, value, days, path, domain, secure)
			{
				var expires = -1;
				if(typeof days == "number" && days >= 0) {
					var d = new Date();
					d.setTime(d.getTime()+(days*24*60*60*1000));
					expires = d.toGMTString();
				}
				value = escape(value);
				document.cookie = name + "=" + value + ";"
				+ (expires != -1 ? " expires=" + expires + ";" : "")
				+ (path ? "path=" + path : "")
				+ (domain ? "; domain=" + domain : "")
				+ (secure ? "; secure" : "");
			};
			this.get = function(name)
			{
				var idx = document.cookie.lastIndexOf(name+'=');
				if(idx == -1) { return null; }
				var value = document.cookie.substring(idx+name.length+1);
				var end = value.indexOf(';');
				if(end == -1) { end = value.length; }
				value = value.substring(0, end);
				value = unescape(value);
				return value;
			};
			this.del = function(name)
			{
				this.set(name, "-",0);
			};
		},
		tools:function()
		{
			this.baseURL	=function()
			{
				return window.location;
			};
			this.path_root	=function(jsPath)
			{
				if(this.parent.browser.isIE)
				{
					//alert(jsPath)
					return jsPath+"../..";
				}
				else
				{
					var a = jsPath.split("/");
					a.pop();
					a.pop();
					a.pop();
					return a.join("/");
				}
			};
			this.baseJS	=function(js)
			{
				var Isrc="",script = document.getElementsByTagName('script');
				for (var i=script.length-1; i>=0; i--){
					if (script[i].src && (script[i].src.indexOf(js) != -1))
					{
						Isrc = script[i].src;
						Isrc = Isrc.substring(0, Isrc.lastIndexOf('/'));
						this.parent.info.domBaseJS=script[i];
						break;
					}
				}
				return Isrc+"/";
			};
			this.head=function()
			{
				return document.getElementsByTagName("HTML")[0].getElementsByTagName("HEAD")[0];
			};
			this.createUID=function()
			{
				return Math.random();
			};
			this.expand(this);
		},
		/**
		* @class Manage DOM elements
		* @param {Object} parent Leimnud instance
		*/
		D0M:function()
		{
			this.get_html=function()
			{
				return document.getElementsByTagName('html')[0];
			};
			this.get_doc=function(){
			    var doc = window.document;
			    return (!doc.compatMode || doc.compatMode == 'CSS1Compat')?this.get_html():doc.body;
			};
			/**
			* Capture DOM object from (String || DOM element)
			* @param {string || object} element String.id || DOM object
			* @return DOM object
			*/
			this.element=function(element)
			{//return document.getElementById(element);
//				return (!element)?false:((typeof element=="object")?element:(($(element))?$(element):false));
				return (!element)?false:((typeof element=="object")?element:((document.getElementById(element))?document.getElementById(element):false));
			};
			/**
			* Remove Elements
			* @param {DOM || Array.DOM} DOM Elements
			*/
			this.remove=function(DOM){
				DOM = (DOM.isArray || (DOM.isObject && !DOM.appendChild))?DOM:[DOM];
				for(var i in DOM)
				{
					if(DOM.propertyIsEnumerable(i))
					{
						if(DOM[i].isObject && !DOM[i].appendChild)
						{
							this.remove(DOM[i]);
						}
						else
						{
							var element=this.element(DOM[i]);
							if(element && element.parentNode)
							{
								element.parentNode.removeChild(element);
							}
						}
					}
				}
				return true;
			};
			/**
			* Automate DOM || HTMLCollection => ArrayDOMCollection
			* @param {string || DOM} DOM DOM || HTMLCollection
			* @param {Array} style ArrayDOMCollection
			*/
			this.automateDOMToCollection = function(DOM)
			{
				return ((!DOM.isArray && (DOM.isObject || (this.parent.browser.isIE && !DOM.isObject))) || DOM.isArray)?DOM:[DOM];
			};
			/**
			* Apply styles to DOM object
			* @param {string || DOM} DOM String.id || DOM object
			* @param {object} style es| Objeto con valores de estilo
			*/
			this.setStyle = function(DOM,styles)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				var sizeInPixel=["width","height","left","top","right","bottom",
						 "margin","marginLeft","marginRight","marginTop","marginBottom","marginLeftWidth","marginRightWidth","marginTopWidth","marginBottomWidth",
						 "padding","paddingLeft","paddingRight","paddingTop","paddingBottom","paddingLeftWidth","paddingRightWidth","paddingTopWidth","paddingBottomWidth",
						 "borderLeftWidth","borderRightWidth","borderTopWidth","borderBopttomWidth"
						 ];
				for(var j=0;j<DOM.length;j++)
				{
					var d0m=this.element(DOM[j]);
					if(d0m)
					{
						for (var value in styles)
						{
							if(styles.propertyIsEnumerable(value)){
								//console.info(value+":"+styles[value])
								var val = (typeof styles[value]=="function")?styles[value]():styles[value];
								try{
									var valu= (typeof val!="undefined")?val:" ";
									var prop=value.camelize();
									valu=(sizeInPixel.inArray(prop) && typeof valu==="number")?valu+"px":valu;
									d0m.style[prop] = valu;
								}
								catch(e){}
							}
						}
					}
				}
			};
			/**
			* Apply properties to DOM object
			* @param {string || DOM} DOM String.id || DOM object
			* @param {object} properties es| Objeto con propiedades
			*/
			this.setProperties = function(DOM,properties)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				for(var j=0;j<DOM.length;j++)
				{
					var d0m=this.element(DOM[j]);
					if(d0m)
					{
						for (var value in properties)
						{
							if(properties.propertyIsEnumerable(value)){
								//console.info(value+":"+styles[value])
								var val = properties[value];
								try{
								d0m[value] = (typeof val!="undefined")?val:" ";
								}
								catch(e){}
							}
						}
					}
				}
			};

			/**
			* Get styles from DOM object
			* @param {string || DOM} DOM String.id || DOM object
			* @param {object} style Propertie to get
			*/
			this.getStyle = function(DOM,style)
			{
				var d0m = this.element(DOM),rs;
				if(typeof style=="string")
				{
					var st	= style.split(",");
					rs	= [];
					//alert(style)
					for(var i=0;i<st.length;i++)
					{
						var stringStyle = st[i].camelize();
						//alert(d0m.style[stringStyle])
						var value = d0m.style[stringStyle];
						//console.info(st[i].camelize()+":"+value+"<-- A PEDIR")
						if (!value)
						{
							if(document.defaultView && document.defaultView.getComputedStyle)
							{
								var css = document.defaultView.getComputedStyle(d0m, null);
								value = css ? css.getPropertyValue(stringStyle) : null;
							}
							else if(d0m.currentStyle)
							{
								value = d0m.currentStyle[stringStyle];
							}
						}
						rs.push((value == 'auto')?null:value);
					}
					rs = (rs.length<2)?rs[0]:rs;
				}
				else if(style.isObject)
				{
					rs= {};
					for(i in style)
					{
						if(style.propertyIsEnumerable(i))
						{
							//alert(i+":"+this.getStyle(DOM,i))
							rs[i]=this.getStyle(DOM,i);
						}
					}
				}
				/*if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
				{
				if (this.getStyle(element, 'position') == 'static')
				{
				value = 'auto';
				};
				}*/
				//console.info(style+":"+rs)
				return rs;
			};
			/**
			* es| Capturar coordenadas X,Y de un elemento DOM
			* @param {String || DOM} DOM String.id || DOM object
			* @param {Boolean} Final Return coordinates x2,y2
			* @return {Object} position Coordinates x,y
			*/
			this.position=function(DOM,Final,StopOnAbsolute)
			{
				DOM = this.element(DOM);
				var position,initial = DOM;
				if(this.parent.dom.getStyle(DOM,"position")=="absolute")
				{
					position={
						x:parseInt(this.parent.dom.getStyle(DOM,"left"),10),
						y:parseInt(this.parent.dom.getStyle(DOM,"top"),10)
					};
				}
				else
				{
					position={
						x:0,
						y:0
					};
					if(!DOM){return position;}
					//var m = parseInt(this.parent.dom.getStyle(DOM,"margin"),10) || 0;
					
					position.x=parseInt(DOM.offsetLeft,10);
					position.y=parseInt(DOM.offsetTop,10);
					//alert(DOM.offsetParent);
					while (DOM.offsetParent){
						DOM = DOM.offsetParent;
						//alert(StopOnAbsolute)
						var sta = (typeof StopOnAbsolute=="string")?(StopOnAbsolute==DOM.id):StopOnAbsolute;
//						console.info(position.x+":"+position.y+":"+StopOnAbsolute+":"+DOM.id+":"+sta);
						if(sta && (this.parent.dom.getStyle(DOM,"position")=="absolute" || this.parent.dom.getStyle(DOM,"position")=="relative"))
						{
							break;
						}
						else
						{
							var gt = this.position(DOM,false,StopOnAbsolute);
							position.x += gt.x;
							position.y += gt.y;
						}
					}
				}
				//alert(position.x+":"+position.y)
				return (Final===true)?{x:(position.x+parseInt(initial.offsetWidth,10)),y:(position.y+parseInt(initial.offsetHeight,10))}:position;
			};
			/**
			* Transform HTMLCollection to ArrayCollection
			* @param {HTMLCOLLECTION} Collection Html Collection
			* @return {Array} Array Collection;
			*/
			this.CollectionToArray = function(Collection)
			{
				var r=[];
				for(var i=0;i<Collection.length;i++)
				{
					r.push(Collection[i]);
				}
				return r;
			};
			/**
			* Coordinates x,y Mouse
			* @param {Event} event Event
			* @return {Object} position Coordinates x,y
			*/
			this.mouse = function(event)
			{
				return {
					x:(this.parent.browser.isIE)?(window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft):(event.clientX + (window.scrollX || document.body.scrollLeft || 0)),
					y:(this.parent.browser.isIE)?(window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop):(event.clientY + (window.scrollY || document.body.scrollTop ||0))
				};
			};
			/**
			* Set Opacity
			* @param {DOM} DOM
			* @param {integer} integer Opacity
			*/
			this.opacity = function(DOM,opacity)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				for(var j=0;j<DOM.length;j++)
				{
					var d0m=this.element(DOM[j]);
					if(this.parent.browser.isIE)
					{
						this.setStyle(d0m,{
							filter:"alpha(opacity="+opacity+")"
						});
					}
					else
					{
						this.setStyle(d0m,{
							opacity:opacity/100
						});
					}
				}
				return true;
			};
			/**
			* Get Opacity
			* @param {DOM} DOM
			* @param {Float} Float Opacity
			*/
			this.getOpacity = function(DOM)
			{
				var opacity;
				var DOM = this.element(DOM);
				if(opacity = this.getStyle(DOM, 'opacity'))
				{
					return parseFloat(opacity);
				}
				if (opacity = (this.getStyle(DOM, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
				{
					if(opacity[1])
					{
						return parseFloat(opacity[1]) / 100;
					}
				}
				return 1.0;
			};

			/**
			* Null right click
			* @param {DOM || Array[DOM]} DOM Elements
			* @return {Event} event Event false
			*/
			this.nullContextMenu = function(DOM)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				for(var i=0;i<DOM.length;i++)
				{
					DOM[i].oncontextmenu=function(){return false;};
				}
			};

			/**
			* DOM elements, range positions
			* @param {DOM || Array[DOM]} DOM Elements
			* @return {Object} position Coordinates x1:y1,x2:y2
			*/
			this.positionRange = function(DOM,StopOnAbsolute)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				var r={};
				for(var i=0;i<DOM.length;i++)
				{
					var p1 = this.position(DOM[i],false,StopOnAbsolute || false);
					r.x1=(!r.x1 || (p1.x<r.x1))?p1.x:r.x1;
					r.y1=(!r.y1 || (p1.y<r.y1))?p1.y:r.y1;
					var p2 = this.position(DOM[i],true,StopOnAbsolute || false);
					r.x2=(!r.x2 || (p2.x>r.x2))?p2.x:r.x2;
					r.y2=(!r.y2 || (p2.y>r.y2))?p2.y:r.y2;
				}
				return r;
			};
			/**
			* DOM elements, Fix positions if out of range
			* @param {DOM || Array[DOM]} DOM Elements
			* @param {Object} range Current range
			*/
			this.positionRangeFix = function(DOM,range)
			{
				DOM = (DOM.isArray)?DOM:[DOM];
				var r={};
				for(var i=0;i<DOM.length;i++)
				{
					var sL=parseInt(this.parent.dom.getStyle(DOM[i],"left"),10);
					var sT=parseInt(this.parent.dom.getStyle(DOM[i],"top"),10);
					this.parent.dom.setStyle(DOM[i],{
						left:sL+1
					});
				}
				return r;
			};

			/**
			* Capture DOM Element
			* @param {String} DOMstring Object to Search [(id|name|tag).(id|name|tag) (Index=0)]
			* @return Object HEAD
			* leimnud.dom.capture("id.html 0");
			*/
			this.capture=function(DOMstring)
			{
				var str = DOMstring.trim();
				var index = str.split(" ");
				var iDom  = index[0];
				iDom	  = iDom.split(".");
				if(iDom.length<2){return false;}
				index = (index.length<2)?"0":index[index.length-1];
				var all = (index==="*")?true:false;
				var pindex =index.split(",").onlyInt();
				index = pindex.unique();
				var by = iDom[0];
				iDom.splice(0,1);
				var el = iDom.join(".");
				var oDom;
				switch (by)
				{
					case "id":
					return $(el);
					case "name":
					oDom=document.getElementsByName(el);
					break;
					case "tag":
					oDom=document.getElementsByTagName(el);
					break;
					default:
					return false;
				}
				if(all)
				{
					return this.CollectionToArray(oDom);
				}
				else
				{
					if(index.length===0)
					{return false;}
					else if(index.length==1)
					{
						return oDom[0];
					}
					else
					{
						var nDom=[].fill(0,index.length,false);
						for(var i=0;i<oDom.length;i++)
						{
							if(index.inArray(i))
							{
								nDom[index.key(i)]=oDom[i];
							}
						}
						return nDom;
					}
				}
			};
			/**
			* Cancel Event Bubble
			* @param {Event} evt Event in !browser.isIE
			* @return {boolean} false
			*/
			this.bubble = function(allow,evt)
			{
				evt = evt || window.event || false;
				allow = (allow===true)?true:false;
				if(!evt){return false;}
				if(this.parent.browser.isIE)
				{
					evt.cancelBubble=!allow;
				}
				else
				{
					if(allow===false)
					{
						evt.stopPropagation();
					}
					else
					{

					}
				}
				return true;
			};
			/**
			* Load javascript file
			* @param {String} file
			* @return {boolean} result
			*/
			this.loadJs = function(file)
			{
				var jsS = document.getElementsByTagName("script");
				for(var i=0;i<jsS.length;i++)
				{
					if(jsS[i].src.indexOf(file)>-1){
						return false;
					}
				}
				var script = $dce("script");
				this.capture("tag.head 0").appendChild(script);
				script.src = file;
				script.type = "text/javascript";
				script.charset = this.parent.charset;
				return true;
			};
			this.getPageScroll=function()
			{
				return [window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop];
			};
			this.getPageSize = function()
				{	        
				    var xScroll, yScroll;					
					if (window.innerHeight && window.scrollMaxY) {	
						xScroll = window.innerWidth + window.scrollMaxX;
						yScroll = window.innerHeight + window.scrollMaxY;
					} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
						xScroll = document.body.scrollWidth;
						yScroll = document.body.scrollHeight;
					} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
						xScroll = document.body.offsetWidth;
						yScroll = document.body.offsetHeight;
					}
					
					var windowWidth, windowHeight;
					
					if (self.innerHeight) {	// all except Explorer
						if(document.documentElement.clientWidth){
							windowWidth = document.documentElement.clientWidth; 
						} else {
							windowWidth = self.innerWidth;
						}
						windowHeight = self.innerHeight;
					} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
						windowWidth = document.documentElement.clientWidth;
						windowHeight = document.documentElement.clientHeight;
						//alert(windowHeight);
					} else if (document.body) { // other Explorers
						windowWidth = document.body.clientWidth;
						windowHeight = document.body.clientHeight;
					}	
					
					// for small pages with total height less then height of the viewport
					if(yScroll < windowHeight){
						pageHeight = windowHeight;
					} else { 
						pageHeight = yScroll;
					}
				
					// for small pages with total width less then width of the viewport
					if(xScroll < windowWidth){	
						pageWidth = xScroll;		
					} else {
						pageWidth = windowWidth;
					}			
					return [pageWidth,pageHeight];
				};
			this.serializer = this.parent.factory(function(DOM,obj)
			{
				/**
				* Serialize form Element
				* @param {FormElement} form
				* @return {String} serialized
				*/
				this.DOM = DOM;
				this.inObject = (obj===true)?true:false;
				this.serialized = (this.inObject)?{}:"";
				this.parse=function()
				{

				};
				this.rake = function(val)
				{
					if(!val){return val;}
					if(typeof val==="object")
					{
						this.serialized.concat(val);
					}
					else
					{
						this.serialized+=val;
					}
					return true;
				};
				this.form = function()
				{
					var form = this.DOM;
					var serializeds = [];
					serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("input"),this.inObject).input());
					serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("select"),this.inObject).select());
					serializeds.push(new this.parent.dom.serializer(form.getElementsByTagName("textarea"),this.inObject).textarea());
					for (var i=0;i<serializeds.length;i++)
					{
						this.rake(serializeds[i]);
					}
					return this.serialized;
				};
				this.input = function()
				{
					for(var i=0;i<this.DOM.length;i++)
					{
						var inp = this.DOM[i];
						if(inp.name)
						{
							if(inp.type==="text")
							{
								var cn =(inp.name+"="+((inp.value)?escape(inp.value):"")+"&");
								this.rake(cn);
							}
							else if(inp.type==="radio")
							{
								var cn =(inp.checked===true)?(inp.name+"="+escape(inp.value)+"&"):"";
								this.rake(cn);
							}
							else if(inp.type==="checkbox")
							{
								var cn =(inp.checked===true)?inp.name+"="+escape(inp.value)+"&":"";
								this.rake(cn);
							}
							else
							{
								var cn =(inp.name+"="+((inp.value)?escape(inp.value):"")+"&");
								this.rake(cn);
							}
						}
					}
					return this.serialized;
				};				
				this.select = function()
				{
					for(var i=0;i<this.DOM.length;i++)
					{
						var inp = this.DOM[i];
						if(inp.name)
						{
							if(inp.multiple===true)
							{
								for(var j=0;j<inp.options.length;j++)
								{
									if(inp.options[j].selected)
									{
										var cn =inp.name+"="+escape(inp.options[j].value)+"&";
										this.rake(cn);
									}
								}
							}
							else
							{
								try
								{
									var cn =inp.name+"="+escape(inp.options[inp.options.selectedIndex].value)+"&";
								}
								catch(e)
								{
									var cn =inp.name+"=&";
								}
								this.rake(cn);
							}
						}
					}
					return this.serialized;
				};
				this.textarea = function()
				{
					for(var i=0;i<this.DOM.length;i++)
					{
						var inp = this.DOM[i];
						if(inp.name)
						{
							var cn =(inp.name+"="+((inp.value)?escape(inp.value):"")+"&");
							this.rake(cn);
						}
					}
					return this.serialized;
				};
				this.expand(this);
				return this;
			});
		}
	};
	this.iphoneBrowser = function()
	{
		this.make=function()
		{
			this.parent.event.add(window,"load",function(){
				document.body.orient="landscape";
				//alert(window.innerWidth)
				window.scrollTo(0,1);
			});
		};
	};
	return this;
};
/* PACKAGE : COMMON
 */
  function get_xmlhttp() {
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
        xmlhttp = false;
      }
    }
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
        xmlhttp = new XMLHttpRequest();
    }
    return xmlhttp;
  }
  /* ajax_function
   * Envia una solicitud GET a ajax_server con la variables "function" y las definidas en parameters.
   * @author       Julio Cesar Laura Avendano <juliocesar@colosa.com, julces2000@gmail.com>
   * @version 1.0
   * @package ajax
   * @param string ajax_server  url de la pagina servidor
   * @param string function     función solicitada en el lado del servidor
   * @param string parameters   variables pasadas por url. Ej. variable=valor&otravariable=suvalor
   */
  function ajax_function(ajax_server, funcion, parameters, method)
  {
      var objetus;
      objetus = get_xmlhttp();
      var response;
      try
      {
      	if (parameters) parameters = '&' + encodeURI(parameters);
      	if (!method ) method ="POST";
      	data = "function=" + funcion + parameters;
      	questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?';
        var callServer;
        callServer = new leimnud.module.rpc.xmlhttp({
        		url			: ajax_server,
        		async   : false,
        		method	: method,
        		args    : data
        	});
      	callServer.make();
      	response = callServer.xmlhttp.responseText;
      	var scs = callServer.xmlhttp.responseText.extractScript();

	  	scs.evalScript();
      	delete callServer;
    	} catch(ss){
    		alert("Error: "+ss.message+var_dump(ss));
    	}
      return response;//objetus.responseText;
  }
  /* ajax_message
   * Envia una solicitud GET a ajax_server con la variables "function" y las definidas en parameters.
   * @author       Julio Cesar Laura Avendano <juliocesar@colosa.com, julces2000@gmail.com>
   * @version 1.0
   * @package ajax
   * @param string ajax_server  url de la pagina servidor
   * @param string function     función solicitada en el lado del servidor
   * @param string parameters   variables pasadas por url. Ej. variable=valor&otravariable=suvalor
   */
  function ajax_message(ajax_server, funcion, parameters, method, callback)
  {
      var objetus;
      objetus = get_xmlhttp();
      var response;
      try
      {
      	if (parameters) parameters = '&' + encodeURI(parameters);
      	if (!method ) method ="POST";
      	data = "function=" + funcion + parameters;
      	questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?';
      	objetus.open( method, ajax_server + ((method==='GET')? questionMark+data : '') , true );
        objetus.onreadystatechange=function() {
          if ( objetus.readyState==4)
          {
            if( objetus.status==200)
            {
                if ( callback ) callback(objetus.responseText);
            }
          }
        }
        if (method==='POST') objetus.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        objetus.send(((method==='GET')? null : data));
    	}catch(ss)
    	{
    		alert("error"+ss.message);
    	}
  }
  /* ajax_post
   * Envia una solicitud GET/POST a ajax_server con los parametros definidos
   * o los campos de un formulario
   * @author       Julio Cesar Laura Avendano <juliocesar@colosa.com, julces2000@gmail.com>
   * @version 1.0
   * @package ajax
   * @param string ajax_server  url de la pagina servidor
   * @param string function     función solicitada en el lado del servidor
   * @param string parameters   variables pasadas por url o formulario.
   * @example: ajax_post('foo.com', document.form[0], "POST", callback )
   */
  function ajax_post(ajax_server, parameters, method, callback, asynchronous )
  {
      var objetus;
      objetus = get_xmlhttp();
      var response;
      try
      {
        if (typeof(parameters)==='object') parameters = ajax_getForm(parameters);
      	if (!method ) method ="POST";
      	if (typeof(asynchronous)==='undefined') asynchronous = false;
      	data = parameters;
      	questionMark = (ajax_server.split('?').length > 1 ) ? '&' : '?';
      	if (method==='GET/POST') {
      	  objetus.open( 'POST', ajax_server + ((data.length<1024)?(questionMark+data):''), asynchronous );
      	} else {
      	  objetus.open( method, ajax_server + ((method==='GET')? questionMark+data : '') , asynchronous );
      	}
        objetus.onreadystatechange=function() {
          if ( objetus.readyState==4)
          {
            if( objetus.status==200)
            {
                if ( callback ) callback(objetus.responseText);
            }
          }
        }
        if ((method==='POST')||(method==='GET/POST')) objetus.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
        objetus.send(((method==='GET')? null : data));
      	if (!asynchronous)
      	{
          if ( callback ) callback(objetus.responseText);
      	  return objetus.responseText;
        }
    	}catch(ss)
    	{
    		alert("Error: "+ var_dump(ss));
    	}
  }

  /*
   * Refactoring.......................
   * Fixed by checkboxes binary values
   * By Neyek <erik@colosa.com>
   * Date March 27th, 2009 12:20:00 GMT-4
   */

  function ajax_getForm( thisform ) {
	var formdata='';

	// Loop through form fields
	for (var i=0; i < thisform.length; i++) {
	  if ( formdata!=='' ) formdata += '&';
	  //Build Send String
	  if(thisform.elements[i].type == "text") { //Handle Textbox's
		  formdata += thisform.elements[i].name + "=" + encodeURIComponent(thisform.elements[i].value);
	  } else if(thisform.elements[i].type == "textarea") { //Handle textareas
		  formdata += thisform.elements[i].name + "=" + encodeURIComponent(thisform.elements[i].value);
	  } else if(thisform.elements[i].type == "checkbox") { //Handle checkbox's
		  formdata += thisform.elements[i].name + '=' + ((thisform.elements[i].checked)? '1': '0');
	  } else if(thisform.elements[i].type == "radio") { //Handle Radio buttons
		  if(thisform.elements[i].checked==true){
			  formdata += thisform.elements[i].name + "=" + thisform.elements[i].value;
		  }
	  } else if(thisform.elements[i].type == "select-multiple") { //Handle list box
		  for(var j=0; j<thisform.elements[i].options.length ;j++) {
			  if ( j!==0 ) formdata += '&';
			  formdata += ( (thisform.elements[i].options[j].selected)? thisform.elements[i].name.replace('[]', '[' + j + ']') + "=" + encodeURIComponent(thisform.elements[i].options[j].value): '');
		  }
	  } else {
		  //finally, this should theoretically this is a select box.
		  formdata += thisform.elements[i].name + "=" + encodeURIComponent(thisform.elements[i].value);
	  }
	}
	return formdata;
  }

/* COMMON FUNCTIONS
 */


function isNumber (sValue)
{
	var sValue = new String(sValue);
  var bDot   = false;
  var i, sCharacter;
  if ((sValue == null) || (sValue.length == 0))
  {
    if (isNumber.arguments.length == 1)
    {
    	return false;
    }
    else
    {
    	return (isNumber.arguments[1] == true);
    }
  }
  for (i = 0; i < sValue.length; i++)
  {
    sCharacter = sValue.charAt(i);
    if (i != 0)
    {
      if (sCharacter == '.')
      {
        if (!bDot)
        {
          bDot = true;
        }
        else
        {
          return false;
        }
      }
      else
      {
        if (!((sCharacter >= '0') && (sCharacter <= '9')))
        {
        	return false;
        }
      }
    }
    else
    {
      if (sCharacter == '.')
      {
        if (!bDot)
        {
          bDot = true;
        }
        else
        {
          return false;
        }
      }
      else
      {
        if (!((sCharacter >= '0') && (sCharacter <= '9') && (sCharacter != '-') || (sCharacter == '+')))
        {
        	return false;
        }
      }
    }
  }
  return true;
}

function roundNumber(iNumber, iDecimals)
  {
	var iNumber   = parseFloat(iNumber || 0);
	var iDecimals = parseFloat(iDecimals || 2);
	return Math.round(iNumber * Math.pow(10, iDecimals)) / Math.pow(10, iDecimals);
}

function toMaskNumber(iNumber,dec)
{
	iNumber = fix(iNumber.toString(),dec || 2);
	var t=iNumber.split(".");
	var arrayResult=iNumber.replace(/\D/g,'').replace(/^0*/,'').split("").reverse();
	var final="";
	var aux=0;
	var sep=0;
	for(var i=0;i<arrayResult.length;i++)
	{
		if(i==1)
		{
			final="."+arrayResult[i]+final;
		}
		else
		{
			if(i>1 && aux>=3 && ((aux%3)==0))
			{
				final=arrayResult[i]+","+final;
				aux+=1;
				sep+=1;
			}
			else
			{
				final=arrayResult[i]+final;
				if(i>1)
				{
					aux+=1;
				}
			}
		}
	}
	return final;
}

function fix(val, dec)
{
	var a = val.split(".");
	var r="";
	if(a.length==1)
	{
		r=a[0]+"."+creaZero(dec);
	}
	else
	{
		if(a[1].length<=dec)
		{
			r=a[0]+"."+a[1]+creaZero(dec-a[1].length);
		}
		else
		{
			r=a[0]+"."+a[1].substr(0,dec);
		}
	}
	return r;
}

function creaZero(cant)
{
	var a="";
	for(var i=0;i<cant;i++)
	{
		a+="0";
	}
	return a;
}

function toUnmaskNumber(iNumber)
{
	var aux = "";
	var num = new String (iNumber);
	var len = num.length;
	var i = 0;
	for (i = 0; i < len; i++ ) {
		if (num.charAt ( i) != ',' && num.charAt (i) != '$' && num.charAt (i) != ' ' && num.charAt (i) != '%' ) aux = aux + num.charAt ( i);
	}
	return parseFloat(aux,2);
}

function compareDates(datea, dateB,porDias)
{
	var a = datea.split('/');

	var b = dateB.split('/');
	x = new Date(a[2], a[1], (porDias)?1:a[0]);
	y = new Date(b[2], b[1], (porDias)?1:b[0]);
	return ((x - y) <= 0) ? false : true;
}

/****THE ANSWER*****/
/*diferencia entre 2 fechas*/
function diff_date(fecha1, fecha2)
{ var f1 = fecha1.split('-');
	fecha1 = new Date();
	fecha1.setDate(f1[2]);
	fecha1.setMonth(f1[1]);
	fecha1.setYear(f1[0]);

  var f2 = fecha2.split('-');
	fecha2 = new Date();
	fecha2.setDate(f2[2]);
	fecha2.setMonth(f2[1]);
	fecha2.setYear(f2[0]);

	var dias = Math.floor((fecha1.getTime()-fecha2.getTime())/(3600000*24));
	return dias;
}

/*
 * author <julces2000@gmail.com>
 */
function getField( fieldName , formId )
{
  if (formId)
  {
    var form = document.getElementById(formId);
    if (!form) {form=document.getElementsByName(formId);
      if (form) {
      	if (form.length > 0) {
      	  form = form[0];
        }
      }
    }
    if (form.length > 0) {
      return form.elements[ 'form[' + fieldName + ']' ];
    }
    else {
    	//return null;
    	return document.getElementById( 'form[' + fieldName + ']' );
    }
  }
  else
  {
    return document.getElementById( 'form[' + fieldName + ']' );
  }
}

/*
 * author <julces2000@gmail.com>
 */
function getElementByName( fieldName )
{
  var elements = document.getElementsByName( fieldName );
  try{
    var x=0;
    if (elements.length === 1)
      return elements[0];
    else if (elements.length === 0)
      return elements[0];
    else
      return elements;
  } catch (E)
  {}
}


var myDialog;
function commonDialog ( type, title , text, buttons, values, callbackFn )  {
	myDialog = new leimnud.module.panel();
	myDialog.options = {
	  size:{w:400,h:200},
	  position:{center:true},
		title: title,
		control: { close	:false, roll	:false, drag	:true, resize	:false },
    fx: {
      //shadow	:true,
      blinkToFront:false,
      opacity	:true,
      drag:false,
      modal: true
    },
	  theme:"processmaker"
	};

	myDialog.make();
    switch (type) {
    case 'question':
       icon = 'question.gif';
       break
    case 'warning':
       icon = 'warning.gif';
       break
    case 'error':
       icon = 'error.gif';
       break
    default:
       icon = 'information.gif';
       break
    }

    var contentStr = '';
    contentStr += "<div><table border='0' width='100%' > <tr height='70'><td width='60' align='center' >";
    contentStr += "<img src='/js/maborak/core/images/" + icon + "'></td><td >" + text + "</td></tr>";
    contentStr += "<tr height='35' valign='bottom'><td colspan='2' align='center'> ";
    if ( buttons.custom && buttons.customText )
      contentStr += "<input type='button' value='" + buttons.customText + "' onclick='myDialog.dialogCallback(4); ';> &nbsp; ";
    if ( buttons.cancel )
      contentStr += "<input type='button' value='Cancel' onclick='myDialog.dialogCallback(0);'> &nbsp; ";
    if ( buttons.yes )
      contentStr += "<input type='button' value=' Yes ' onclick='myDialog.dialogCallback(1);'> &nbsp; ";
    if ( buttons.no )
      contentStr += "<input type='button' value=' No ' onclick='myDialog.dialogCallback(2);'> &nbsp; ";
    contentStr += "</td></tr>";
    contentStr += "</table>";

    myDialog.addContent( contentStr );
    myDialog.values = values;
	  myDialog.dialogCallback = function ( dialogResult ) {
		  myDialog.remove( );
      if ( callbackFn )
        callbackFn ( dialogResult );
    }

}
function var_dump(obj)
{
	var o,dump;
	dump='';
	if (typeof(obj)=='object') {
  	for(o in obj) if (typeof(obj[o])!=='function')
  	{
  		dump+=o+'('+typeof(obj[o])+'):'+obj[o]+"\n";
  	}
  }
	else
	dump=obj;
	return dump;
}

/*
 * @author David Callizaya
 */
var currentPopupWindow;
function popupWindow ( title , url, width, height, callbackFn , autoSizeWidth, autoSizeHeight,modal,showModalColor)  {
	modal = (modal===false)?false:true;
	showModalColor = (showModalColor===false)?false:true;
	var myPanel = new leimnud.module.panel();
	currentPopupWindow = myPanel;
	myPanel.options = {
		size:{w:width,h:height},
		position:{center:true},
		title: title,
		theme: "processmaker",
		control: { close :true, roll	:false, drag	:true, resize	:false},
		fx: {
			//shadow	:true,
			blinkToFront:true,
			opacity	:true,
			drag:true,
			modal: modal
		      //opacityModal:{static:'1'}
		}
	};
	if(showModalColor===true)
	{
		//Panel.setStyle={modal:{backgroundColor:"#ECF3F6"}};
	}
	else
	{
		myPanel.styles.fx.opacityModal.Static='0';
	}
	myPanel.make();
	myPanel.loader.show();
	var r = new leimnud.module.rpc.xmlhttp({url:url});
	r.callback=leimnud.closure({Function:function(rpc,myPanel){
  		myPanel.addContent(rpc.xmlhttp.responseText);
  		var myScripts = myPanel.elements.content.getElementsByTagName('SCRIPT');
  		for(var rr=0; rr<myScripts.length ; rr++){
  		  try {
  		    if (myScripts[rr].innerHTML!=='')
  		      if (window.execScript)
  	          window.execScript( myScripts[rr].innerHTML, 'javascript' );
  	        else
  	          window.setTimeout( myScripts[rr].innerHTML, 0 );
  		  } catch (e) {
  		    alert(e.description);
  		  }
  		}
  		/* Autosize of panels, to fill only the first child of the
  		 * rendered page (take note)
  		 */
  		var panelNonContentHeight = 62;
  		var panelNonContentWidth  = 28;
  		myPanel.elements.content.style.padding="0px;";
  		try {
  		  if (autoSizeWidth)
    		  myPanel.resize({w:myPanel.elements.content.childNodes[0].clientWidth+panelNonContentWidth});
  		  if (autoSizeHeight)
    		  myPanel.resize({h:myPanel.elements.content.childNodes[0].clientHeight+panelNonContentHeight});
  	  } catch (e) {
  	    alert(':(');
  	  }
  		delete newdiv;
  		delete myScripts;
			myPanel.command(myPanel.loader.hide);
	},args:[r, myPanel]});
	r.make();

/*
  myPanel.dialogCallback = function (  ) {
  }
*/
  delete myPanel;
}

// Get an object left position from the upper left viewport corner
// Tested with relative and nested objects
function getAbsoluteLeft(o) {
	oLeft = o.offsetLeft            // Get left position from the parent object
	while(o.offsetParent!=null) {   // Parse the parent hierarchy up to the document element
		oParent = o.offsetParent    // Get parent object reference
		oLeft += oParent.offsetLeft // Add parent left position
		o = oParent
	}
	// Return left postion
	return oLeft
}
// Get an object top position from the upper left viewport corner
// Tested with relative and nested objects
function getAbsoluteTop(o) {
	oTop = o.offsetTop            // Get top position from the parent object
	while(o.offsetParent!=null) { // Parse the parent hierarchy up to the document element
		oParent = o.offsetParent  // Get parent object reference
		oTop += oParent.offsetTop // Add parent top position
		o = oParent
	}
	// Return top position
	return oTop
}
/*
 */
function showHideElement(id)
{
  var element;
  if (typeof(id)=='object') element=id;
  else element=document.getElementById(id);
  if (element.style.display==='none') {
    switch(element.type) {
      case 'table':
        element.style.display = 'table';
        break;
      default:
        element.style.display = '';
    }
  } else {
    element.style.display = 'none';
  }
}
/*
 */
function showHideSearch(id,aElement,openText,closeText)
{
  var element=document.getElementById(id);
  if (element.style.display==='none') {
    if (!closeText) closeText=G_STRINGS.ID_CLOSE_SEARCH;
    if (aElement) {
      aElement.innerHTML=closeText;
      var bullet = document.getElementById(aElement.id+'[bullet]');
      bullet.src='/images/bulletButtonDown.gif';
    }
    switch(element.type) {
      case 'table':
        document.getElementById(id).style.display = 'table';
        break;
      default:
        document.getElementById(id).style.display = '';
    }
  } else {
    if (!openText) openText=G_STRINGS.ID_OPEN_SEARCH;
    if (aElement) {
      aElement.innerHTML=openText;
      var bullet = document.getElementById(aElement.id+'[bullet]');
      bullet.src='/images/bulletButton.gif';
    }
    document.getElementById(id).style.display = 'none';
  }
}
/* Loads a page but in a non visible div with absolute on (x,y)
 * and execute the javascript node that it contains.
 */
function loadPage ( url, x, y , visibility , div )  {
    visibility = typeof(visibility)==='udefined'?'hidden':visibility;
  	var r = new leimnud.module.rpc.xmlhttp({url:url});
  	r.callback=leimnud.closure({Function:function(rpc,div){
  	    if (typeof(div)==='undefined') div=createDiv('');
        if (typeof(x)!=='undefined') div.style.left=x;
        if (typeof(y)!=='undefined') div.style.top =y;
        div.innerHTML=rpc.xmlhttp.responseText;
    		var myScripts = div.getElementsByTagName('SCRIPT');
    		for(var rr=0; rr<myScripts.length ; rr++){
    		  try {
    		    if (myScripts[rr].innerHTML!=='')
    		      if (window.execScript)
    		          window.execScript( myScripts[rr].innerHTML, 'javascript' );
    		        else
    		          window.setTimeout( myScripts[rr].innerHTML, 0 );
    		  } catch (e) {
    		    alert(e.description);
    		  }
    		}
    		delete div;
    		delete myScripts;
  	},args:[r,div]});
  	r.make();
}
function createDiv(id) {

   var newdiv = document.createElement('div');
   newdiv.setAttribute('id', id);

   newdiv.style.position = "absolute";
   newdiv.style.left = 0;
   newdiv.style.top = 0;

   newdiv.style.visibility="hidden";

   document.body.appendChild(newdiv);

   return newdiv;
}

/* THIS FUNCTIONS WHERE COPIED FROM JSFORMS */

/*if (window.attachEvent)
  window.attachEvent('onload', _OnLoad_);
else
  window.addEventListener('load', _OnLoad_, true);*/

//function _OnLoad_() {


/*onload=function(){

	if (self.setNewDates)
    self.setNewDates();

  if (self.setReloadFields)
    self.setReloadFields();

  if (self.enableHtmlEdit)
    self.enableHtmlEdit();

  if (self.dynaformOnloadUsers)
    self.dynaformOnloadUsers();

  if (self.dynaformOnload)
    self.dynaformOnload();


}*/



function refillText( fldName, ajax_server, values ) {
	var objetus;
    objetus = get_xmlhttp();
    objetus.open ("GET", ajax_server + "?" + values, false);
    objetus.onreadystatechange=function() {
        if ( objetus.readyState == 1 )
        {
          var textfield = document.getElementById( 'form[' + fldName + ']' );
          if ( ! isdefined( textfield ))
            var textfield = document.getElementById( fldName );
          textfield.value = '';

        }
        else if ( objetus.readyState==4)
        {
            if( objetus.status==200)
            {
//              alert ( objetus.responseText );
              var xmlDoc = objetus.responseXML;
              if ( xmlDoc ) {
                 var textfield = document.getElementById( 'form[' + fldName + ']' );
                 if ( ! isdefined( textfield ))
                   var textfield = document.getElementById( fldName );
                 var dataArray = xmlDoc.getElementsByTagName('value');
                 if (dataArray[0].firstChild)
                 	 if((dataArray[0].firstChild.xml)!='_vacio'){
                 		 textfield.value = dataArray[0].firstChild.xml;
                 		 if(textfield.type != 'hidden')
                 		   if ( textfield.onchange )
                 			   textfield.onchange();
                 	 }
              }
            }
            else
            {
                window.alert('error-['+ objetus.status +']-' + objetus.responseText );
            }
        }
    }
    objetus.send(null);
}

function refillCaption( fldName, ajax_server, values ){
	var objetus;
    objetus = get_xmlhttp();
    objetus.open ("GET", ajax_server + "?" + values, false);
    objetus.onreadystatechange=function() {
        if ( objetus.readyState == 1 )
        {
          var textfield = document.getElementById( 'FLD_' + fldName );
          textfield.innerHTML = '';

        }
        else if ( objetus.readyState==4)
        {
            if( objetus.status==200)
            {
              var xmlDoc = objetus.responseXML;
              if ( xmlDoc ) {
                 var textfield = document.getElementById( 'FLD_' + fldName );
                 var dataArray = xmlDoc.getElementsByTagName('value');
                 if (dataArray[0].firstChild)
                 	  if((dataArray[0].firstChild.xml)!='_vacio')
                 		  //textfield.innerHTML = '<font size="1">' + dataArray[0].firstChild.xml + '</font>';
                 		  textfield.innerHTML = dataArray[0].firstChild.xml;
              }
            }
            else
            {
                window.alert('error-['+ objetus.status +']-' + objetus.responseText );
            }
        }
    }
    objetus.send(null);
}


function refillDropdown( fldName, ajax_server, values , InitValue)
{

	var objetus;
    objetus = get_xmlhttp();
    objetus.open ("GET", ajax_server + "?" + values, false);
    objetus.onreadystatechange=function() {
        if ( objetus.readyState == 1 )
        {
          var dropdown = document.getElementById( 'form[' + fldName + ']' );

          while ( dropdown.hasChildNodes() )
            dropdown.removeChild(dropdown.childNodes[0]);

        }
        else if ( objetus.readyState==4)
        {
            if( objetus.status==200)
            {
              var xmlDoc = objetus.responseXML;

              if ( xmlDoc ) {
                 var dropdown = document.getElementById( 'form[' + fldName + ']' );
                 var dataArray = xmlDoc.getElementsByTagName('item');
                 itemsNumber = dataArray.length;

                 if(InitValue == true) itemsNumber = dataArray.length-1;
                 for (var i=0; i<itemsNumber; i++){
                    dropdown.options[ dropdown.length] = new Option(dataArray[i].firstChild.xml, dataArray[i].attributes[0].value );
                    if(InitValue == true) {
                    	if(dropdown.options[ dropdown.length-1].value == dataArray[dataArray.length-1].firstChild.xml)
                    		dropdown.options[i].selected = true;
                    }
                 }
                 dropdown.onchange();
              }
            }
            else
            {
                window.alert('error-['+ objetus.status +']-' + objetus.responseText );
            }
        }
    }
    objetus.send(null);
}

function iframe_get_xmlhttp() {
  try {
    xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

function get_xmlhttp() {
        try {
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
                try {
                        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (E) {
                        xmlhttp = false;
                }
        }
        if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
                xmlhttp = new XMLHttpRequest();
        }
        return xmlhttp;
}



function refillTextError( div_container, fldName, ajax_server, values )
{
	var objetus;
    objetus = get_xmlhttp();
    objetus.open ("GET", ajax_server + "?" + values, false);
    objetus.onreadystatechange=function() {
        if ( objetus.readyState == 1 )
        {
          var textfield = document.getElementById( 'form[' + fldName + ']' );
          textfield.value = '';
          document.getElementById(div_container).innerHTML = '';

        }
        else if ( objetus.readyState==4)
        {
            if( objetus.status==200)
            {
              var xmlDoc = objetus.responseXML;
              if ( xmlDoc ) {
                 var textfield = document.getElementById( 'form[' + fldName + ']' );
                 var dataArray = xmlDoc.getElementsByTagName('value');
                 textfield.value = dataArray[0].firstChild.xml;
                 var dataArray = xmlDoc.getElementsByTagName('message');
                 if ( dataArray[0].firstChild )
                   document.getElementById(div_container).innerHTML = '<b>' + dataArray[0].firstChild.xml + '</b>';
              }
            }
            else
            {
                window.alert('error-['+ objetus.status +']-' + objetus.responseText );
            }
        }
    }
    objetus.send(null);
}



function iframe_get_xmlhttp() {
  try {
    xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

function iframe_ajax_init(ajax_server, div_container, values, callback) {
	var objetus;
  objetus = iframe_get_xmlhttp();
  objetus.open ('GET', ajax_server + '?' + values, true);
  objetus.onreadystatechange = function() {
    if ( objetus.readyState == 1 ) {
      document.getElementById(div_container).style.display = '';
      document.getElementById(div_container).innerHTML = '...';
    }
    else if (objetus.readyState==4) {
      if (objetus.status==200) {
        document.getElementById(div_container).innerHTML = objetus.responseText;
        if (callback != '')
          callback();
      }
      else {
        window.alert('error-['+ objetus.status +']-' + objetus.responseText );
      }
    }
  }
  objetus.send(null);
}

function iframe_ajax_init_2(ajax_server, div_container, values, callback) {
	var objetus;
  objetus = iframe_get_xmlhttp();
  objetus.open ('GET', ajax_server + '?' + values, true);
  objetus.onreadystatechange = function() {
    if ( objetus.readyState == 1 ) {
      div_container.style.display = '';
      div_container.innerHTML = '...';
    }
    else if (objetus.readyState==4) {
      if (objetus.status==200) {
        div_container.innerHTML = objetus.responseText;
        if (callback != '')
          callback();
      }
      else {
        window.alert('error-['+ objetus.status +']-' + objetus.responseText );
      }
    }
  }
  objetus.send(null);
}

function myEmptyCallback() {
}

function disable (obj) {
  obj.disabled = true;
  return;
}

function enable (obj) {
  obj.disabled = false;
  return;
}

function disableById (id) {
  obj = getField(id);
  obj.disabled = true;
  return;
}

function enableById (id) {
  obj = getField(id);
  obj.disabled = false;
  return;
}

function visible (obj) {
  if (obj.style) {
    obj.style.visibility = 'visible';
  }
  return;
}

function hidden (obj) {
  if (obj.style) {
    obj.style.visibility = 'hidden';
  }
  return;
}

function visibleById (id) {
  obj = getField(id);
  obj.style.visibility = 'visible';
  return;
}

function hiddenById (id) {
  obj = getField(id);
  obj.style.visibility = 'hidden';
  return;
}

function hiddenRowById (id) {
	row = 'DIV_'+ id +'.style.visibility = \'hidden\';';
	hiden = 'DIV_'+ id +'.style.display = \'none\';';
	eval(row);
	eval(hiden);
  return;
}
function visibleRowById (id) {
	row = 'DIV_'+ id +'.style.visibility = \'visible\';';
	block = 'DIV_'+ id +'.style.display = \'block\';';
	eval(row);
	eval(block);
  return;
}

function setFocus (obj) {
  obj.focus();
  return;
}

function setFocusById (id) {
  obj = getField (id);
  setFocus(obj);
  return;
}

function submitForm () {
  document.webform.submit();
  return;
}

function changeValue(id, newValue) {
  obj = getField(id);
  obj.value = newValue;
  return ;
}

function getValue(obj) {
  return obj.value;
}

function getValueById (id) {
  obj = getField(id);
  return obj.value;
}

function removeCurrencySign (snumber) {
   var aux = '';
   var num = new String (snumber);
   var len = num.length;
   var i = 0;
   for (i=0; !(i>=len); i++)
     if (num.charAt(i) != ',' && num.charAt(i) != '$' && num.charAt(i) != ' ') aux = aux + num.charAt(i);
   return aux;
 }

 function removePercentageSign (snumber) {
   var aux = '';
   var num = new String (snumber);
   var len = num.length;
   var i = 0;
   for (i=0; !(i>=len); i++)
     if (num.charAt(i) != ',' && num.charAt(i) != '%' && num.charAt(i) != ' ') aux = aux + num.charAt(i);
   return aux;
 }

 function toReadOnly(obj) {
 	 if (obj) {
     obj.readOnly = 'readOnly';
     obj.style.background = '#CCCCCC';
   }
   return;
 }

 function toReadOnlyById(id) {
   obj = getField(id);
   if (obj) {
     obj.readOnly = 'readOnly';
     obj.style.background = '#CCCCCC';
   }
   return ;
 }

function getGridField(Grid, Row, Field) {
	obj = document.getElementById('form[' + Grid + ']' + '[' + Row + ']' + '[' + Field + ']');
  return obj;
}

function getGridValueById(Grid, Row, Field) {
  obj = getGridField(Grid, Row, Field);
  if (obj)
    return obj.value;
  else
    return '';
}

function Number_Rows_Grid(Grid, Field) {
	Number_Rows = 1;
	if (getGridField(Grid, Number_Rows, Field)) {
		Number_Rows = 0;
	  while (getGridField(Grid, (Number_Rows + 1), Field))
	    Number_Rows++;
	  return Number_Rows;
	}
	else
	  return 0;
}

function attachFunctionEventOnChange(Obj, TheFunction) {
	Obj.oncustomize = TheFunction;
}

function attachFunctionEventOnChangeById(Id, TheFunction) {
	Obj = getField(Id);
	Obj.oncustomize = TheFunction;
}

function attachFunctionEventOnKeypress(Obj, TheFunction) {
	Obj.attachEvent('onkeypress', TheFunction);
}

function attachFunctionEventOnKeypressById(Id, TheFunction) {
	Obj = getField(Id);
	Obj.attachEvent('onkeypress', TheFunction);
}

function unselectOptions ( field ) {
var radios = document.getElementById('form[' + field + ']');
	if (radios) {
	  var inputs = radios.getElementsByTagName ('input');
	  if (inputs) {
		  for(var i = 0; i < inputs.length; ++i) {
		  	inputs[i].checked = false;
			}
	  }
	}
}

function validDate(TheField, Required) {
	TheYear  = getField(TheField + '][YEAR');
	TheMonth = getField(TheField + '][MONTH');
	TheDay   = getField(TheField + '][DAY');
	if (!TheYear || !TheMonth || !TheDay)
	  return false;
	if (Required)
	  if ((TheYear.value == 0) || (TheMonth.value == 0) || (TheDay.value == 0))
	    return false;
	if (TheMonth.value == 2)
	  if (TheDay.value > 29)
	    return false;
	if ((TheMonth.value == 4) || (TheMonth.value == 6) || (TheMonth.value == 9) || (TheMonth.value == 11))
	  if (TheDay.value > 30)
	    return false;
	return true;
}

/* @author David S. Callizaya S.
 */
function globalEval(scriptCode) {
  if (scriptCode!=='')
    if (window.execScript)
      window.execScript( scriptCode, 'javascript' );
    else
      window.setTimeout( scriptCode, 0 );
}
function switchImage(oImg,url1,url2){
  if (oImg && (url2!=='')) {
    oImg.src=(oImg.src.substr(oImg.src.length-url1.length,url1.length)===url1)? url2: url1;
  }
}
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}
function backImage(oImg,p){
  oImg.style.background=p;
}

/* javascript para el toolbar */
var lc=false;
var sh=function(a,i)
{
    var c = (a.nextSibling.nextSibling)?a.nextSibling.nextSibling:a.nextSibling;
    if(lc && lc.c!=i){
        lc.d.style.display='none';
        lc.a.style.color='#666';
    }
    lc={d:c,c:i,a:a};
    a.style.color=(c.style.display=='' || c.style.display=='none')?"black":"#666";
    c.style.display=(!c.style.display || c.style.display=='none')?"block":"none";
}

/**
 * Set focus to first field from a dynaform
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @return false
 */
function dynaformSetFocus(){

	/* looking for the inputs fields */
	var inputs = document.getElementsByTagName('input');
	for(i in inputs) {
		type = inputs[i].type;
		if(type == "text" || type == "radio" || type == "checkbox" || type == "file" || type == "password"){
			try {
	      inputs[i].focus();
	    } catch (e) {
	      //nothing
	    }
			return false;
		}
	}
	/* if there is no inputs fields, maybe it has a textarea field */
	var ta = document.getElementsByTagName('textarea');
	if(ta.length > 0){
		inputs[0].focus();
		return false;
	}
	return false;
}

/**
 * ********************************* Misc Functions by Neyek ****************************************
 */

/**
 * get the htmlentities from a string
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param (string) string within the htmlentities to parse
 * @Param (string) quote_style it can be (ENT_QUOTES or ENT_NOQUOTES)
 * @Return (string) the parsed string with htmlentities at the string passed such as parameter
 */
function htmlentities (string, quote_style) {

    var hash_map = {}, symbol = '', tmp_str = '', entity = '';
    tmp_str = string.toString();

    if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
        return false;
    }
    hash_map["'"] = '&#039;';
    for (symbol in hash_map) {
        entity = hash_map[symbol];
        tmp_str = tmp_str.split(symbol).join(entity);
    }

    return tmp_str;
}

function get_html_translation_table (table, quote_style) {
    //example 1: get_html_translation_table('HTML_SPECIALCHARS');
    //returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}

    var entities = {}, hash_map = {}, decimal = 0, symbol = '';
    var constMappingTable = {}, constMappingQuoteStyle = {};
    var useTable = {}, useQuoteStyle = {};

    // Translate arguments
    constMappingTable[0]      = 'HTML_SPECIALCHARS';
    constMappingTable[1]      = 'HTML_ENTITIES';
    constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
    constMappingQuoteStyle[2] = 'ENT_COMPAT';
    constMappingQuoteStyle[3] = 'ENT_QUOTES';

    useTable       = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
    useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';

    if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
        throw new Error("Table: "+useTable+' not supported');
        // return false;
    }

    entities['38'] = '&amp;';
    if (useTable === 'HTML_ENTITIES') {
        entities['160'] = '&nbsp;';
        entities['161'] = '&iexcl;';
        entities['162'] = '&cent;';
        entities['163'] = '&pound;';
        entities['164'] = '&curren;';
        entities['165'] = '&yen;';
        entities['166'] = '&brvbar;';
        entities['167'] = '&sect;';
        entities['168'] = '&uml;';
        entities['169'] = '&copy;';
        entities['170'] = '&ordf;';
        entities['171'] = '&laquo;';
        entities['172'] = '&not;';
        entities['173'] = '&shy;';
        entities['174'] = '&reg;';
        entities['175'] = '&macr;';
        entities['176'] = '&deg;';
        entities['177'] = '&plusmn;';
        entities['178'] = '&sup2;';
        entities['179'] = '&sup3;';
        entities['180'] = '&acute;';
        entities['181'] = '&micro;';
        entities['182'] = '&para;';
        entities['183'] = '&middot;';
        entities['184'] = '&cedil;';
        entities['185'] = '&sup1;';
        entities['186'] = '&ordm;';
        entities['187'] = '&raquo;';
        entities['188'] = '&frac14;';
        entities['189'] = '&frac12;';
        entities['190'] = '&frac34;';
        entities['191'] = '&iquest;';
        entities['192'] = '&Agrave;';
        entities['193'] = '&Aacute;';
        entities['194'] = '&Acirc;';
        entities['195'] = '&Atilde;';
        entities['196'] = '&Auml;';
        entities['197'] = '&Aring;';
        entities['198'] = '&AElig;';
        entities['199'] = '&Ccedil;';
        entities['200'] = '&Egrave;';
        entities['201'] = '&Eacute;';
        entities['202'] = '&Ecirc;';
        entities['203'] = '&Euml;';
        entities['204'] = '&Igrave;';
        entities['205'] = '&Iacute;';
        entities['206'] = '&Icirc;';
        entities['207'] = '&Iuml;';
        entities['208'] = '&ETH;';
        entities['209'] = '&Ntilde;';
        entities['210'] = '&Ograve;';
        entities['211'] = '&Oacute;';
        entities['212'] = '&Ocirc;';
        entities['213'] = '&Otilde;';
        entities['214'] = '&Ouml;';
        entities['215'] = '&times;';
        entities['216'] = '&Oslash;';
        entities['217'] = '&Ugrave;';
        entities['218'] = '&Uacute;';
        entities['219'] = '&Ucirc;';
        entities['220'] = '&Uuml;';
        entities['221'] = '&Yacute;';
        entities['222'] = '&THORN;';
        entities['223'] = '&szlig;';
        entities['224'] = '&agrave;';
        entities['225'] = '&aacute;';
        entities['226'] = '&acirc;';
        entities['227'] = '&atilde;';
        entities['228'] = '&auml;';
        entities['229'] = '&aring;';
        entities['230'] = '&aelig;';
        entities['231'] = '&ccedil;';
        entities['232'] = '&egrave;';
        entities['233'] = '&eacute;';
        entities['234'] = '&ecirc;';
        entities['235'] = '&euml;';
        entities['236'] = '&igrave;';
        entities['237'] = '&iacute;';
        entities['238'] = '&icirc;';
        entities['239'] = '&iuml;';
        entities['240'] = '&eth;';
        entities['241'] = '&ntilde;';
        entities['242'] = '&ograve;';
        entities['243'] = '&oacute;';
        entities['244'] = '&ocirc;';
        entities['245'] = '&otilde;';
        entities['246'] = '&ouml;';
        entities['247'] = '&divide;';
        entities['248'] = '&oslash;';
        entities['249'] = '&ugrave;';
        entities['250'] = '&uacute;';
        entities['251'] = '&ucirc;';
        entities['252'] = '&uuml;';
        entities['253'] = '&yacute;';
        entities['254'] = '&thorn;';
        entities['255'] = '&yuml;';
    }

    if (useQuoteStyle !== 'ENT_NOQUOTES') {
        entities['34'] = '&quot;';
    }
    if (useQuoteStyle === 'ENT_QUOTES') {
        entities['39'] = '&#39;';
    }
    entities['60'] = '&lt;';
    entities['62'] = '&gt;';


    // ascii decimals to real symbols
    for (decimal in entities) {
        symbol = String.fromCharCode(decimal);
        hash_map[symbol] = entities[decimal];
    }

    return hash_map;
}

function stripslashes (str) {
    return (str+'').replace(/\\(.?)/g, function (s, n1) {
        switch (n1) {
            case '\\':
                return '\\';
            case '0':
                return '\0';
            case '':
                return '';
            default:
                return n1;
        }
    });
}

function addslashes (str) {
    return (str+'').replace(/([\\"'])/g, "\\$1").replace(/\u0000/g, "\\0");
}

/**
 * This function sets netsted properties to dom elements
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param (object) dom element refered by ID
 * @Param (array) nested array of properties strings
 * @Param (string) value to set
 * @Return <none>
 *
 * Example:
 * 		setNestedProperty(document, ['body','style','backgroundColor'], 'black');
 */
function setNestedProperty(obj, propertyName, propertyValue){
	var oTarget = obj;
	for (var i=0; i<propertyName.length; i++){
		if (i == (propertyName.length - 1)){
			oTarget[propertyName[i]] = propertyValue;
			return false;
		}
		oTarget = oTarget[propertyName[i]];
	}
}

/**
 * This function gets the user client browser and its version
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param <none>
 * @Return (objeect) {browser:sBrowser, version:sVersion}
 */
function getBrowserClient(){

    var aBrowFull = new Array("opera", "msie", "firefox", "opera", "safari");
    var sInfo = navigator.userAgent.toLowerCase();
    sBrowser = "";
    for (var i = 0; i < aBrowFull.length; i++){
		if ((sBrowser == "") && (sInfo.indexOf(aBrowFull[i]) != -1)){
			sBrowser = aBrowFull[i];
			sVersion = String(parseFloat(sInfo.substr(sInfo.indexOf(aBrowFull[i]) + aBrowFull[i].length + 1)));
			return {browser:sBrowser, version:sVersion}
		}
    }
    return false;
}

/**
 * Create and send cookie
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param (string) cookie name
 * @Param (string) cookie value
 * @Param (int) cookie number of days for expires
 * @Return <none>
 */
function createCookie(name, value, days){
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	} else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

/**
 * read a cookie
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param cookie name
 * @Return (string) cookie content
 */
function readCookie(name){
	var ca = document.cookie.split(';');
	var nameEQ = name + "=";
	for(var i=0; i < ca.length; i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
	}
	return null;
}

/**
 * delete a cookie
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param cookie name
 * @Return <none>
 */
function eraseCookie(name){
	createCookie(name, "", -1);
}

/**
 * highlightRow a html element (setting background)
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param (object) html element
 * @Param (string) some color in hexadecimal format
 * @Return <none>
 */
function highlightRow(o, color){
	o.style.background = color
}

/**
 * left and right delete the blank characteres (String prototype)
 *
 * Example:
 *	var str = String("  some_string_with_spaces ");
 *  str.trim(); //clean the blank characteres
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param <none>
 * @Return <none>
 */
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+get/g,"");
}

function clearCalendar(id){
	document.getElementById(id).value='';
	document.getElementById(id+'[div]').innerHTML = '';
	setTimeout('enableCalendar()', 350);
}

function lockCalendar(){
	G_CALENDAR_MEM_OFFSET = 'lock';

	//G_CALENDAR_CURRENT_OBJ.hide();
}

function enableCalendar(){
	G_CALENDAR_MEM_OFFSET = 'enable';
}

function parseDateFromMask (inputArray, mask){
	/* inputArray is an associative array with properties
	year, month, day, hour, minute 	*/

	/* format mask
	 * Y 	-> 2009
	 * y	-> 09
	 * m	-> 02
	 * d	-> 01
	 *
	 * h	-> 12
	 * i	-> 59
	 *
	 * d/m/y -> 01/02/09
	 * d/m/Y -> 01/02/2009
	 * Y-m-d -> 2009-02-01
	 *
	 * Y-m-d h:m -> 2009-02-01 12:59
	 *
	 */

	result = mask;
	result = result.replace("Y", inputArray.year);

	year = new String(inputArray.year);
	result = result.replace("y", year.substr(2,3));
	result = result.replace("m", inputArray.month);
	result = result.replace("d", inputArray.day);
	result = result.replace("h", inputArray.hour);
	result = result.replace("i", inputArray.minute);

	return result;

}

Array.prototype.walk = function( funcionaplicada ) {
    for(var i=0, parar=false; i<this.length && !parar; i++ )
        parar = funcionaplicada( this[i], i);
    return (this.length==i)? false : (i-1);
}

Array.prototype.find = function(q) {
    var dev = this.walk(function(elem) {
        if( elem==q )
            return true;
    } );
    if( this[dev]==q ) return dev;
    else return -1;
}

Array.prototype.drop = function(x) {
    this.splice(x,1);
}

Array.prototype.deleteByValue = function(val) {
    var eindex = this.find(val);
    this.drop(eindex);
}

/**
 * schedule a action js callback
 *
 * @Author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@gmail.com>
 * @Param (string) function name
 * @Param (int) time in seconds
 * @Return <none>
 */
function Timer(functionName, time) {
	setTimeout(functionName, time*1000);
}

function clearTemporalMessage(){
	Timer(function(){
		try{
				document.getElementById('temporalMessage').innerHTML = '';
		}catch(e){}},
		3
	);
}


/* Web Resource
 * @author: David Callizaya <davidsantos@colosa.com>
 * Depend of common.js
 */
function WebResource(uri,parameters,method)
{
    var request;
    request = get_xmlhttp();
    var response;
    try
    {
    	if (!method ) method ="POST";
    	if (parameters != '') {
    		parameters += '&rand=' + Math.random();
    	}
    	else {
    		parameters = 'rand=' + Math.random();
    	}
    	data = parameters;
    	request.open( method, uri + ((method==='GET')?('?'+data): '') , false);
      if (method==='POST') request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      request.send(((method==='GET')? null : data));
      var type=request.getResponseHeader('Content-Type');
      var reType=/\w+\/\w+/;
      var maType=reType.exec(type);
      type=maType?maType[0]:'';//type.split(String.fromCharCode(9)).join("").trim();
  	}catch(ss)
  	{
  		alert("error"+ss.message);
  	}
      switch(type)
      {
        case "text/json":
          try
          {
            eval('response='+request.responseText+';');
            break;
          }
          catch (err)
          {
          }
            G.alert('<textarea style="width:100%;" rows="9">'+request.responseText+'</textarea>');
            return ;
          break;
        case "text/javascript":
          if (window.execScript)
              window.execScript( request.responseText ,'javascript');
          else
              window.setTimeout( request.responseText, 0 );
          break;
        case "text/html":
          response=$dce('div');
          response.innerHTML=request.responseText;
          break;
      }
    /*var r;
    for(r in response)
    {
      eval('this.'+r+'=response[r];');
    }*/
    return response;
}
function __wrCall(uri,func,parameters)
{
  var param=[];
  for(var a=0;a<parameters.length;a++) param.push(parameters[a]);
  return WebResource(uri,"function="+func+"&parameters="+encodeURIComponent(param.toJSONString()));
}
/* Required functions */
if (!Object.prototype.toJSONString) {
    Array.prototype.toJSONString = function () {
        var a = ['['],
            b,
            i,
            l = this.length,
            v;
        function p(s) {
            if (b) {
                a.push(',');
            }
            a.push(s);
            b = true;
        }
        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {
            case 'undefined':
            case 'function':
            case 'unknown':
                break;
            case 'object':
                if (v) {
                    if (typeof v.toJSONString === 'function') {
                        p(v.toJSONString());
                    }
                } else {
                    p("null");
                }
                break;
            default:
                p(v.toJSONString());
            }
        }
        a.push(']');
        return a.join('');
    };
    Boolean.prototype.toJSONString = function () {
        return String(this);
    };
    Date.prototype.toJSONString = function () {
        function f(n) {
            return n < 10 ? '0' + n : n;
        }
        return '"' + this.getFullYear() + '-' +
                f(this.getMonth() + 1) + '-' +
                f(this.getDate()) + 'T' +
                f(this.getHours()) + ':' +
                f(this.getMinutes()) + ':' +
                f(this.getSeconds()) + '"';
    };
    Number.prototype.toJSONString = function () {
        return isFinite(this) ? String(this) : "null";
    };
    Object.prototype.toJSONString = function () {
        var a = ['{'],
            b,
            k,
            v;
        function p(s) {
            if (b) {
                a.push(',');
            }
            a.push(k.toJSONString(), ':', s);
            b = true;
        }
        for (k in this) {
            if (this.hasOwnProperty(k)) {
                v = this[k];
                switch (typeof v) {
                case 'undefined':
                case 'function':
                case 'unknown':
                    break;
                case 'object':
                    if (v) {
                        if (typeof v.toJSONString === 'function') {
                            p(v.toJSONString());
                        }
                    } else {
                        p("null");
                    }
                    break;
                default:
                    p(v.toJSONString());
                }
            }
        }
        a.push('}');
        return a.join('');
    };

    (function (s) {
        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };
        s.parseJSON = function (filter) {
            try {
                if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
                        test(this)) {
                    var j = eval('(' + this + ')');
                    if (typeof filter === 'function') {

                        function walk(k, v) {
                            if (v && typeof v === 'object') {
                                for (var i in v) {
                                    if (v.hasOwnProperty(i)) {
                                        v[i] = walk(i, v[i]);
                                    }
                                }
                            }
                            return filter(k, v);
                        }

                        j = walk('', j);
                    }
                    return j;
                }
            } catch (e) {
            }
            throw new SyntaxError("parseJSON");
        };

        s.toJSONString = function () {
            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                    var c = m[b];
                    if (c) {
                        return c;
                    }
                    c = b.charCodeAt();
                    return '\\u00' +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}
if (!String.prototype.trim)
{
  String.prototype.trim=function()
  {
    var cadena=this;
  	for(i=0; i<cadena.length; )
  	{
  		if(cadena.charAt(i)==" ")
  			cadena=cadena.substr(i+1, cadena.length);
  		else
  			break;
  	}

  	for(i=cadena.length-1; i>=0; i=cadena.length-1)
  	{
  		if(cadena.charAt(i)==" ")
  			cadena=cadena.substr(0,i);
  		else
  			break;
  	}
  	return cadena.toString();
  }
}function DVEditor(where,body,oHiddenInput,height)
{
  var me=this;
  var hiddenInput=oHiddenInput;
  var iframe=$dce("iframe");
  //NOTE: className no funciona en FIREFOX
  iframe.style.width="100%";
  iframe.style.height=height;
  iframe.style.margin="0px";
  iframe.style.padding="0px";
  iframe.style.border="none";
  where.appendChild(iframe);
  var head=document.childNodes[0].childNodes[0];
  var header='';
  if (iframe.contentWindow)
  {
    var doc=iframe.contentWindow.document;
  }
  else
  {
    var doc=iframe.contentDocument;
  }
  var _header=$dce("head");// head.cloneNode(true);
  for(var i=0;i<head.childNodes.length;i++) {
    try{
      if ((head.childNodes[i].tagName==='LINK')&&
          (head.childNodes[i].type="text/css"))
      {
      	_header.appendChild(head.childNodes[i].cloneNode(true));
      }
      else
      {
      }
    }
    catch(e)
    {
    }
  }
  header=_header.innerHTML;
  //alert(header);
  doc.open();
  doc.write('<html><head>'+header+'</head><body style="height:100%;padding:0px;margin:0px;border:none;background-color:ThreeDHighlight;cursor:text;">'+body+'</body></html>');
  doc.close();
  doc.designMode="on";
  doc.contentEditable=true;
  this.doc=doc;
  me.insertHTML=function (html)
  {
    var cmd = 'inserthtml';
    var bool = false;
    var value = html;
    try
    {
      doc.execCommand(cmd,bool,value);
    } catch (e) {
    }
    return false;
  };
  me.command=function()
  {
    var cmd = this.getAttribute('name');
    var bool = false;
    var value = this.getAttribute('cmdValue') || null;
    if (value == 'promptUser')
    value = prompt(
        (typeof(G_STRINGS[this.getAttribute('promptText')])!=='undefined')?
          G_STRINGS[this.getAttribute('promptText')]:
          this.getAttribute('promptText')
      );
    try
    {
      doc.execCommand(cmd,bool,value);
    } catch (e) {
    }
    return false;
  }
  me.loadToolBar=function(uri)
  {
    var tb=WebResource(uri);
    iframe.parentNode.insertBefore(tb,iframe);
    me.setToolBar(tb);
  }
  me.setToolBar=function(toolbar)
  {
    var buttons=toolbar.getElementsByTagName('area');
    for(var b=0;b<buttons.length;b++)
    {
      buttons[b].onclick=me.command;
    }
  }
  me.getHTML=function()
  {
    var body='';
    try {
      body=doc.getElementsByTagName('body')[0];
      body=body.innerHTML;
    } catch (e) {
    }
    return body;
  }
  me.setHTML=function(html)
  {
    try {
      body=doc.getElementsByTagName('body')[0];
      body.innerHTML=html;
    } catch (e) {
    }
    return body;
  }
  me.refreshHidden=function()
  {
    if(hiddenInput)
    {
      var html=me.getHTML();
      var raiseOnChange=hiddenInput.value!==html;
      hiddenInput.value=html;
      if (raiseOnChange && hiddenInput.onchange) hiddenInput.onchange();
    }
  }
  me.syncHidden=function(name)
  {
    me.refreshHidden();
    setTimeout(name+".syncHidden('"+name+"')",500);
  }
}/* Manages a table of Tree type.
 * @author David Callizaya
 */
function G_Tree() {
  this.lastSelected = false;
  this.lastSelectedClassName = 'treeNode';
  var me = this;
  this.changeSign = function( element, newSign ){
    /*element must be the TR of the current node */
    var spans = element.cells[0].childNodes;//getElementsByTagName('SPAN');
    for(var r= 0 ; r<spans.length ; r++ ) {
      if(spans[r].nodeName==='SPAN') {
        if(spans[r].getAttribute('name')===newSign) {
          spans[r].style.display='';
        } else {
          spans[r].style.display='none';
        }
      }
    }
  };
  this.getRowOf=function (element) {
    //NOTE: IF (element.offsetParent==null) there is no efect.
    while(element.nodeName!='BODY') {
      if (element.getAttribute('name')) {
        if (element.getAttribute('name').substr(0,9)==='treeNode[') {
          var regexp = /^treeNode\[[^\]]+\]\[([^\]]+)\]$/;
          result = regexp.exec(element.getAttribute('name'));
          if (!(result && result.length>=2)) return false;
          //Now element is the TR of the current node.
          return element.parentNode;
        }
      }
      element = element.parentNode;
    }
    return false;
  };
  this.contract=function( element ){
    if (!(element = this.getRowOf(element))) return;
    var row = element.rowIndex;
    if ( (row+1)>= element.parentNode.rows.length ) return;
    element.parentNode.rows[row+1].style.display = 'none';
    this.changeSign( element , 'plus' );
  };

this.expand=function( element ){
    if (!(element = this.getRowOf(element))) return;
    var row = element.rowIndex;
    if ( (row+1)>= element.parentNode.rows.length ) return;
    element.parentNode.rows[row+1].style.display = '';
    this.changeSign( element , 'minus' );
  };
  this.select=function( element ){
    if (!(element = this.getRowOf(element))) return;
    if (me.lastSelected) {
     if (me.lastSelected.cells[1]) me.lastSelected.cells[1].className=me.lastSelectedClassName;
    }
    me.lastSelected = element ;
    //me.lastSelected.cells[1].style.filter='Light';
    //me.lastSelected.cells[1].filters['Light'].addAmbient(155,155,155,255);
    me.lastSelectedClassName=me.lastSelected.cells[1].className;
    me.lastSelected.cells[1].className="treeNodeSelected";
  };
  this.refresh=function( div , server ) {
    div.innerHTML = ajax_function( server ,'','' );
  };
};
var tree = new G_Tree();
/* PACKAGE : json.js 2007-03-21
 */
if (!Object.prototype.toJSONString) {
    Array.prototype.toJSONString = function () {
        var a = ['['],
            b,
            i,
            l = this.length,
            v;
        function p(s) {
            if (b) {
                a.push(',');
            }
            a.push(s);
            b = true;
        }
        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {
            case 'undefined':
            case 'function':
            case 'unknown':
                break;
            case 'object':
                if (v) {
                    if (typeof v.toJSONString === 'function') {
                        p(v.toJSONString());
                    }
                } else {
                    p("null");
                }
                break;
            default:
                p(v.toJSONString());
            }
        }
        a.push(']');
        return a.join('');
    };
    Boolean.prototype.toJSONString = function () {
        return String(this);
    };
    Date.prototype.toJSONString = function () {
        function f(n) {
            return n < 10 ? '0' + n : n;
        }
        return '"' + this.getFullYear() + '-' +
                f(this.getMonth() + 1) + '-' +
                f(this.getDate()) + 'T' +
                f(this.getHours()) + ':' +
                f(this.getMinutes()) + ':' +
                f(this.getSeconds()) + '"';
    };
    Number.prototype.toJSONString = function () {
        return isFinite(this) ? String(this) : "null";
    };
    Object.prototype.toJSONString = function () {
        var a = ['{'],
            b,
            k,
            v;
        function p(s) {
            if (b) {
                a.push(',');
            }
            a.push(k.toJSONString(), ':', s);
            b = true;
        }
        for (k in this) {
            if (this.hasOwnProperty(k)) {
                v = this[k];
                switch (typeof v) {
                case 'undefined':
                case 'function':
                case 'unknown':
                    break;
                case 'object':
                    if (v) {
                        if (typeof v.toJSONString === 'function') {
                            p(v.toJSONString());
                        }
                    } else {
                        p("null");
                    }
                    break;
                default:
                    p(v.toJSONString());
                }
            }
        }
        a.push('}');
        return a.join('');
    };

    (function (s) {
        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };
        s.parseJSON = function (filter) {
            try {
                if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
                        test(this)) {
                    var j = eval('(' + this + ')');
                    if (typeof filter === 'function') {

                        function walk(k, v) {
                            if (v && typeof v === 'object') {
                                for (var i in v) {
                                    if (v.hasOwnProperty(i)) {
                                        v[i] = walk(i, v[i]);
                                    }
                                }
                            }
                            return filter(k, v);
                        }

                        j = walk('', j);
                    }
                    return j;
                }
            } catch (e) {
            }
            throw new SyntaxError("parseJSON");
        };

        s.toJSONString = function () {
            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                    var c = m[b];
                    if (c) {
                        return c;
                    }
                    c = b.charCodeAt();
                    return '\\u00' +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}
/* PACKAGE : GULLIVER FORMS
 */	
  function G_Form ( element, id )
  {
    var me=this;
    this.info = {name:'G_Fom', version :'1.0'};
    /*this.module=RESERVED*/
    this.formula='';
    this.element=element;
    if (!element) return;
    this.id=id;
    this.aElements=[];
    this.ajaxServer='';
    this.getElementIdByName = function (name)  {
      if (name=='') return -1;
      var j;
      for(j=0;j<me.aElements.length;j++) {
        if (me.aElements[j].name===name) return j;
      }
      return -1;
    }
    this.getElementByName = function (name)  {
      var i=me.getElementIdByName(name);
      if (i>=0) return me.aElements[i]; else return null;
    }
    this.hideGroup = function( group, parentLevel ){
      if (typeof(parentLevel)==='undefined') parentLevel = 1;
      for( var r=0 ; r < me.aElements.length ; r++ ) {
        if ((typeof(me.aElements[r].group)!=='undefined') && (me.aElements[r].group == group ))
          me.aElements[r].hide(parentLevel);
      }
    }
    this.showGroup = function( group, parentLevel ){
      if (typeof(parentLevel)==='undefined') parentLevel = 1;
      for( var r=0 ; r < me.aElements.length ; r++ ) {
        if ((typeof(me.aElements[r].group)!=='undefined') && (me.aElements[r].group == group ))
          me.aElements[r].show(parentLevel);
      }
    }
    this.verifyRequiredFields=function(){
      var valid=true;
      for(var i=0;i<me.aElements.length;i++){
        var verifiedField=((!me.aElements[i].required)||(me.aElements[i].required && (me.aElements[i].value()!=='')));
        valid=valid && verifiedField;
        if (!verifiedField) {
          me.aElements[i].highLight();
        }
      }
      return valid;
    }
  };

  function G_Field ( form, element, name )
  {
    var me=this;
    this.form=form;
    this.element=element;
    this.name=name;
    this.dependentFields=[];
    this.dependentOf=[];
    this.hide = function( parentLevel ){
      if (typeof(parentLevel)==='undefined') parentLevel = 1;
      var parent = me.element;
      for( var r=0; r< parentLevel ; r++ )
        parent = parent.parentNode;
      parent.style.display = 'none';
    }
    this.show = function( parentLevel ){
      if (typeof(parentLevel)==='undefined') parentLevel = 1;
      var parent = me.element;
      for( var r=0; r< parentLevel ; r++ )
        parent = parent.parentNode;
      parent.style.display = '';
    }
    this.setDependentFields = function(dependentFields) {
      var i;
      if (dependentFields.indexOf(',') > -1) {
        dependentFields = dependentFields.split(',');
      }
      else {
        dependentFields = dependentFields.split('|');
      }
      for(i=0;i<dependentFields.length;i++) {
        if (me.form.getElementIdByName(dependentFields[i])>=0) {
          me.dependentFields[i] = me.form.getElementByName(dependentFields[i]);
          me.dependentFields[i].addDependencie(me);
        }
      }
    }
    this.addDependencie = function (field) {
      var exists = false;
      for (i=0;i<me.dependentOf.length;i++)
        if (me.dependentOf[i]===field) exists = true;
      if (!exists) me.dependentOf[i] = field;
    }
    this.updateDepententFields=function(event) {
      if (me.dependentFields.length===0) return true;
      var fields=[],i,grid='',row=0;
      for(i in me.dependentFields) {
        if (me.dependentFields[i].dependentOf) {
          for (var j = 0; j < me.dependentFields[i].dependentOf.length; j++) {
            var oAux = me.dependentFields[i].dependentOf[j];
            if (oAux.name.indexOf('][') > -1) {
              var aAux  = oAux.name.split('][');
              grid      = aAux[0];
              row       = aAux[1];
              eval("var oAux2 = {" + aAux[2] + ":'" + oAux.value() + "'}");
              fields = fields.concat(oAux2);
            }
            else {
              fields = fields.concat(me.dependentFields[i].dependentOf);
            }
          }
        }
      }
      var callServer;
      callServer = new leimnud.module.rpc.xmlhttp({
      		url			: me.form.ajaxServer,
      		async   : false,
      		method	: "POST",
      		args    : "function=reloadField&" + 'form='+encodeURIComponent(me.form.id)+'&fields='+encodeURIComponent(fields.toJSONString())+(grid!=''?'&grid='+grid:'')+(row>0?'&row='+row:'')
      	});
    	callServer.make();
    	var response = callServer.xmlhttp.responseText;

      //Validate the response
      if (response.substr(0,1)==='[') {
        var newcont;
        eval('newcont=' + response + ';');
        if (grid == '') {
          for(var i=0;i<newcont.length;i++) {
            var j=me.form.getElementIdByName(newcont[i].name);
            me.form.aElements[j].setValue(newcont[i].value);
            me.form.aElements[j].setContent(newcont[i].content);
            if (me.form.aElements[j].element.fireEvent) {
  		        me.form.aElements[j].element.fireEvent("onchange");
  		      } else {
              var evObj = document.createEvent('HTMLEvents');
              evObj.initEvent( 'change', true, true );
    		      me.form.aElements[j].element.dispatchEvent(evObj);
  		      }
          }
        }
        else {
          for(var i=0;i<newcont.length;i++) {
            var oAux = me.form.getElementByName(grid);
            if (oAux) {
              var oAux2 = oAux.getElementByName(row, newcont[i].name);
              if (oAux2) {
                if (newcont[i].content.type == 'dropdown') {
                  oAux2.setValue(newcont[i].value);
                }
                oAux2.setContent(newcont[i].content);
                if (oAux2.element.fireEvent) {
  		            oAux2.element.fireEvent("onchange");
  		          } else {
                  var evObj = document.createEvent('HTMLEvents');
                  evObj.initEvent( 'change', true, true );
    		          oAux2.element.dispatchEvent(evObj);
  		          }
              }
            }
          }
        }
      } else {
        alert('Invalid response: '+response);
      }
      return true;
    }
    this.setValue = function(newValue) {
      me.element.value = newValue;
    }
    this.setContent = function(newContent) {

    }
    
    this.setAttributes = function (attributes) {
      for(var a in attributes) {
      	
      	if(a=='formula' && attributes[a]){
           //here we called a this function if it has a formula
      	   sumaformu(this.element,attributes[a]);
      	  }
      	
        switch (typeof(attributes[a])) {
          case 'string':
          case 'int':
          case 'boolean':
          if (a != 'strTo') {
            switch (true) {
              case typeof(me[a])==='undefined':
              case typeof(me[a])==='object':
              case typeof(me[a])==='function':
              case a==='isObject':
              case a==='isArray':
                break;
              default:
                me[a] = attributes[a];
            }
          }
          else {
            me[a] = attributes[a];
          }
        }
        
      }
    }
    this.value=function() {
      return me.element.value;
    }
    this.toJSONString=function()  {
      return '{'+me.name+':'+me.element.value.toJSONString()+'}';
    }
    this.highLight=function(){
      try{
        G.highLight(me.element);
        if (G.autoFirstField) {
          me.element.focus();
          G.autoFirstField=false;
          setTimeout("G.autoFirstField=true;",1000);
        }
      } catch (e){
      }
    }
  }

  function G_DropDown( form, element, name )
  {
    var me=this;
    this.parent = G_Field;
    this.parent( form, element, name );
    this.setContent=function(content) {
      var dd=me.element;
      while(dd.options.length>0) dd.remove(0);
      for(var o=0;o<content.options.length;o++) {
        var optn = $dce("OPTION");
        optn.text = content.options[o].value;
        optn.value = content.options[o].key;
        dd.options[o]=optn;
      }
    }
    if (!element) return;
    leimnud.event.add(this.element,'change',this.updateDepententFields);
  }
  G_DropDown.prototype=new G_Field();
	/*
	function G_Formulation(vvv){
		alert(vvv)
		}*/
		
	function G_Text( form, element, name )
  { var me=this;
    this.parent = G_Field;
    this.parent( form, element, name );
    if (element) {
      this.prev = element.value;
    }
    this.validate = 'Any';
    this.mask='';
    this.required=false;
    this.formula='';
    var doubleChange=false;
    
    this.setContent=function(content) {
      me.element.value = '';
      if (content.options) {
        if (content.options[0]) {
          me.element.value = content.options[0].value;
        }
      }
    }

    this.validateKey=function(event) {
      if(me.element.readOnly)  return true;
      me.prev = me.element.value;
      if (window.event) event=window.event;
      var keyCode= window.event ? event.keyCode : event.which ;
      me.mask = typeof(me.mask)==='undefined'?'':me.mask;
      if (me.mask !=='' ) {
      	if((keyCode===118 || keyCode===86) && event.ctrlKey) return false;
        if (event.ctrlKey) return true;
        if (event.altKey) return true;
        if (event.shiftKey) return true;
      }
      if ((keyCode===0) ) if (event.keyCode===46) return true; else return true;
      if ( (keyCode===8)) return true;
      if (me.mask ==='') {
        if (me.validate == 'NodeName') {
          if (me.getCursorPos() == 0) {
            if ((keyCode >= 48) && (keyCode <= 57)) {
              return false;
            }
          }
          var k=new leimnud.module.validator({
            valid	:['Field'],
            key		:event,
            lang	:(typeof(me.language)!=='undefined')?me.language:"en"
          });
          return k.result();
        }
        else {
      	  var k=new leimnud.module.validator({
            valid	:[me.validate],
            key		:event,
            lang	:(typeof(me.language)!=='undefined')?me.language:"en"
          });
          return k.result();
        }
      } else {
        //return true;
        if (doubleChange) {doubleChange=false;return false;}
        var sel = me.getSelectionRange();
        var myValue = String.fromCharCode(keyCode);
        var startPos=sel.selectionStart;
        var endPos=sel.selectionEnd;
        var myField = me.element;
        var newValue = myField.value
        if (keyCode===8) {
          if (startPos>0)
          newValue = myField.value.substring(0, startPos + ((startPos==endPos)?-1:0) )
                    + myField.value.substring(endPos, myField.value.length);
        } else {
          newValue = myField.value.substring(0, startPos)
                    + myValue
                    + myField.value.substring(endPos, myField.value.length);
        }
        var Esperado = newValue;
        startPos++;
        var newValue2=G.cleanMask( newValue, me.mask, startPos );

        newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor );

        me.element.value=newValue2.result;
  		  me.setSelectionRange(newValue2.cursor, newValue2.cursor);


  		  if (me.element.fireEvent) {
  		    me.element.fireEvent("onchange");
  		  } else {
          var evObj = document.createEvent('HTMLEvents');
          evObj.initEvent( 'change', true, true );
    		  me.element.dispatchEvent(evObj);
  		  }

        return false;
      }
    }

    this.preValidateChange=function(event) {
      if(me.element.readOnly)  return true;
      if (me.mask ==='') return true;
      if (event.keyCode===46) {
        var sel=me.getSelectionRange();
        var startPos = sel.selectionStart;
        var endPos   = sel.selectionEnd;
        var myField  = me.element;
        var newValue = myField.value
        if (startPos<myField.value.length) {
          var newValue = myField.value.substring(0, startPos)
          + myField.value.substring(endPos+1, myField.value.length);
          newValue2=G.cleanMask( newValue, me.mask, startPos );
          newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor );
          me.element.value=newValue2.result;
    		  me.setSelectionRange(startPos, startPos);
  		  }
        return false;
      }
      if (event.keyCode===8) {
        var sel=me.getSelectionRange();
        var startPos = sel.selectionStart;
        var endPos   = sel.selectionEnd;
        var myField = me.element;
        var newValue = myField.value
        if (startPos>0) {
          newValue = myField.value.substring(0, startPos-1)
          + myField.value.substring(endPos, myField.value.length);
          newValue2=G.cleanMask( newValue, me.mask, startPos );
          newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor );
          me.element.value=newValue2.result;
    		  me.setSelectionRange(startPos-1, startPos-1);
  		  }
        return false;
      }
      me.prev=me.element.value;
      return true;
    }
    this.execFormula=function(event) {
    	
    	//alert(me.formula); return;
    	      
      if(  me.formula != ''){
      	
	    	leimnud.event.add(getField('faa'),'keypress',function(){
				  alert(getField('faa').value);
				});
	    }
      return false;
      
    }
    this.validateChange=function(event) {
      if (me.mask ==='') return true;
		  var sel=me.getSelectionRange();
      var newValue2=G.cleanMask( me.element.value, me.mask, sel.selectionStart );
	    newValue2=G.toMask( newValue2.result, me.mask, newValue2.cursor);
	    me.element.value = newValue2.result;
		  me.setSelectionRange(newValue2.cursor, newValue2.cursor);
      return true;
    }

    this.value=function()
    {
      return me.element.value;
    }

    this.getCursorPos = function () {
      var textElement=me.element;
      if (!document.selection) return textElement.selectionStart;
      //save off the current value to restore it later,
      var sOldText = textElement.value;

    //create a range object and save off it's text
      var objRange = document.selection.createRange();
      var sOldRange = objRange.text;

    //set this string to a small string that will not normally be encountered
      var sWeirdString = '#%~';

    //insert the weirdstring where the cursor is at
      objRange.text = sOldRange + sWeirdString; objRange.moveStart('character', (0 - sOldRange.length - sWeirdString.length));

    //save off the new string with the weirdstring in it
      var sNewText = textElement.value;

    //set the actual text value back to how it was
      objRange.text = sOldRange;

    //look through the new string we saved off and find the location of
    //the weirdstring that was inserted and return that value
      for (i=0; i <= sNewText.length; i++) {
        var sTemp = sNewText.substring(i, i + sWeirdString.length);
        if (sTemp == sWeirdString) {
          var cursorPos = (i - sOldRange.length);
          return cursorPos;
        }
      }
    }
    this.setSelectionRange = function(selectionStart, selectionEnd) {
      var input=me.element;
      if (input.createTextRange) {
      var range = input.createTextRange();
      range.collapse(true);
      range.moveEnd('character', selectionEnd);
      range.moveStart('character', selectionStart);
      range.select();
      }
      else if (input.setSelectionRange) {
      input.focus();
      input.setSelectionRange(selectionStart, selectionEnd);
      }
    }
    this.getSelectionRange = function() {
      if (document.selection) {
        var textElement=me.element;
        var sOldText = textElement.value;
        var objRange = document.selection.createRange();
        var sOldRange = objRange.text;
        var sWeirdString = '#%~';
        objRange.text = sOldRange + sWeirdString; objRange.moveStart('character', (0 - sOldRange.length - sWeirdString.length));
        var sNewText = textElement.value;
        objRange.text = sOldRange;
        for (i=0; i <= sNewText.length; i++) {
          var sTemp = sNewText.substring(i, i + sWeirdString.length);
          if (sTemp == sWeirdString) {
            var cursorPos = (i - sOldRange.length);
            return {selectionStart: cursorPos, selectionEnd: cursorPos+sOldRange.length};
          }
        }
      } else {
        var sel={selectionStart: 0, selectionEnd: 0};
        sel.selectionStart = me.element.selectionStart;
        sel.selectionEnd = me.element.selectionEnd;
        return sel;
      }
    }
    if (!element) return;
    if (!window.event)
      this.element.onkeypress = this.validateKey;
    else
      leimnud.event.add(this.element,'keypress',this.validateKey);
    leimnud.event.add(this.element,'change',this.updateDepententFields);
	
	
	
	this.element.onblur=function()
	{
		//////////////////////////////////////////
		
		
		/*
		if(this.validate == 'Int'|| this.validate == 'Real'){
			alert(this.formula);
		  symOp=typeOperation(this.formula);
    	if(this.formula){ 		 	
	    	 operations=this.formula.split(symOp);
    	   
    	  var resdo=iniAcum(symOp);
    	   for (var i=0;i<operations.length;i++){
    	  	 		var sums=getField(operations[i]);
    	  	 		//getField(operations[i]).addEvent('onBlur',function(){alert(233);});
    	  	 		if(sums.value!=''){ 
    	  	 		  if(isnumberk(sums.value)){
		    	  	 		   switch(symOp){
		    	  	 		    case '+': resdo =resdo+ parseFloat(sums.value);break;
		    	  	 		    case '*': resdo =resdo* parseFloat(sums.value);break;
		    	  	 		    case '-': resdo =-resdo-parseFloat(sums.value);break;
		    	  	 		    //case '/': resdo =resdo/parseInt(sums.value);break;		    	  	 		             
		    	  	 		             
		    	  	 		    }
    	  	 		   }
    	  	 		}else resdo=0;
    	  	 		/***alert(getField(operations[i]).name)
							   	leimnud.event.add(getField(operations[i]),'change',function(){alert(3434);});
							   	*********/
							   	/*
    	  	 		    getField(operations[i]).onblur=function(){
    	  	 		    	sumElem(sums,element,operations);
    	  	 		    	}*/
    	   /*}
    	   this.element.value=resdo;
    	 }
    }
    */
		///////////////////////////
	  
	  if(this.validate=="Email")
		{
			var pat=/^[\w\_\-\.Ã§Ã±]{2,255}@[\w\_\-]{2,255}\.[a-z]{1,3}\.?[a-z]{0,3}$/;
			if(!pat.test(this.element.value))
			{
				this.element.className=this.element.className.split(" ")[0]+" FormFieldInvalid";
			}
			else
			{
				this.element.className=this.element.className.split(" ")[0]+" FormFieldValid";
			}
		}
		if (this.strTo) {
		  switch (this.strTo) {
		    case 'UPPER':
		      this.element.value = this.element.value.toUpperCase();
		    break;
		    case 'LOWER':
		      this.element.value = this.element.value.toLowerCase();
		    break;
		  }
		}
  
    	
	
		if (this.validate == 'NodeName') {
		  var pat = /^[a-z\_](.)[a-z\d\_]{1,255}$/i;
		  if(!pat.test(this.element.value)) {
		    this.element.value = '_' + this.element.value;
		  }
		}
	}.extend(this);
/*    leimnud.event.add(this.element,'blur',function() {
    	if (this.validate == 'Email') {
 		//if (!this.element.value.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\$")) {
		var pat=/^[\w\_\.Ã§Ã±]{2,255}@[\w]{2,255}\.[a-z]{1,3}\.?[a-z]{0,3}$/;
		if(!pat.test(this.element.value)){
 	//	if (!this.element.value.match("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2-3})\$")) {
    			new leimnud.module.app.alert().make({
					  label:G_STRINGS.ID_INVALID_EMAIL
					});
    			this.element.value = '';
    		}
    	}
    }.extend(this));*/
    
    leimnud.event.add(this.element,'keydown',this.preValidateChange);
    //leimnud.event.add(this.element,'keypress',this.execFormula); 
  }

  
  G_Text.prototype=new G_Field();

  function G_Percentage( form, element, name )
  {
    var me=this;
    this.parent = G_Text;
    this.parent( form, element, name );
    this.validate = 'Int';
    this.mask= '###.##';
  }
  G_Percentage.prototype=new G_Field();

  function G_Currency( form, element, name )
  {
    var me=this;
    this.parent = G_Text;
    this.parent( form, element, name );
    this.validate = 'Int';
    this.mask= '_###,###,###,###,###;###,###,###,###,###.00';
  }
  function G_TextArea( form, element, name )
  {
    var me=this;
    this.parent = G_Text;
    this.parent( form, element, name );
    this.validate = 'Any';
    this.mask= '';
  }
  G_Percentage.prototype=new G_Field();

  function G_Date( form, element, name )
  {
    var me=this;
    this.parent = G_Text;
    this.parent( form, element, name );
    this.mask= 'dd-mm-yyyy';
  }
  G_Percentage.prototype=new G_Field();

function G()
{
  /*MASK*/
  var reserved=['_',';','#','.','0','d','m','y','-'];
  function invertir(num)
  {
    var num0='';
    num0=num;num="";
    for(r=num0.length-1;r>=0;r--) num+= num0.substr(r,1);
    return num;
  }
  function __toMask(num, mask, cursor)
  {
    var inv=false;
    if (mask.substr(0,1)==='_') {mask=mask.substr(1);inv=true;}
    var re;
    if (inv) {
      mask=invertir(mask);
      num=invertir(num);
    }
    var minAdd=-1;
    var minLoss=-1;
    var newCursorPosition=cursor;
    var betterOut="";
    for(var r0=0;r0< mask.length; r0++) {
      var out="";
      var j=0;
      var loss=0;var add=0;
      loss=0;add=0;var cursorPosition=cursor;
      var i=-1;
      var dayPosition=0;
      var mounthPosition=0;
      var dayAnalized ='';
      var mounthAnalized ='';
      var blocks={};
      for(var r=0;r< r0 ;r++) {
        var e=false;
        var m=mask.substr(r,1);
        __parseMask();
      }
      i=0;
      for(r=r0;r< mask.length;r++) {
        j++;if (j>200) break;
        e=num.substr(i,1);
        e=(e==='')?false:e;
        m=mask.substr(r,1);
        __parseMask();
      }
      var io=num.length - i;
      io=(io<0)?0:io;
      loss+=io;
      loss=loss+add/1000;
      //var_dump($loss);
      if (loss===0) {betterOut=out;minLoss=0;newCursorPosition=cursorPosition; break;}
      if ((minLoss===-1)||(loss< minLoss)) { minLoss=loss; betterOut=out; newCursorPosition=cursorPosition; }
      //echo('min:');var_dump($minLoss);
    }
  //  var_dump($minLoss);
    out=betterOut;
    if (inv) {
      out=invertir(out);
      mask=invertir(mask);
    }
    return {'result':out,'cursor':newCursorPosition,'value':minLoss,'mask':mask};
    function searchBlock( where , what )
    {
      for(var r=0; r < where.length ; r++ ) {
        if (where[r].key === what) return where[r];
      }
    }
    function __parseMask()
    {
      var ok=true;
      switch(false) {
        case m==='d': dayAnalized='';break;
        case m==='m': mounthAnalized='';break;
        default:
      }
      if ( e!==false ) {
        if (typeof(blocks[m])==='undefined') blocks[m] = e; else blocks[m] += e;
      } 
      switch(m) {
      case '0':
        if (e===false) {out+='0';add++; break;}
      case 'y':
      case '#':
        if (e===false) {out+='';break;}
        //Use direct comparition to increse speed of processing
        if ((e==='0')||(e==='1')||(e==='2')||(e==='3')||(e==='4')||(e==='5')||(e==='6')||(e==='7')||(e==='8')||(e==='9')||(e==='-')) {
          out+=e;i++;
        } else {
          //loss
          loss++;
          i++;r--;
        }
        break;
      case '(':
          if (e===false) {out+='';break;}
          out+=m;
          if (i<cursor){cursorPosition++;}
          break;
      case 'd':
        if (e===false) {out+='';break;}
        if ((e==='0')||(e==='1')||(e==='2')||(e==='3')||(e==='4')||(e==='5')||(e==='6')||(e==='7')||(e==='8')||(e==='9')) ok=true; else ok=false;
        //if (ok) if (dayPosition===0) if (parseInt(e)>3) ok=false
        //dayPosition=(dayPosition+1) | 1;
        if (ok) dayAnalized = dayAnalized + e;
        if ((ok) && (parseInt(dayAnalized)>31)) ok = false;
        if (ok) {
          out+=e;i++;
          
        } else {
          //loss
          loss++;
          i++;r--;
        }
        break;
      case 'm':
        if (e===false) {out+='';break;}
        if ((e==='0')||(e==='1')||(e==='2')||(e==='3')||(e==='4')||(e==='5')||(e==='6')||(e==='7')||(e==='8')||(e==='9')) ok=true; else ok=false;
        if (ok) mounthAnalized = mounthAnalized + e;
        if ((ok) && (parseInt(mounthAnalized)>12)) ok=false;
        if (ok) {
          out+=e;i++;
        } else {
          //loss
          loss++;
          i++;r--;
        }
        break;
      
      default:
        if (e===false) {out+='';break;}
        if (e===m) {
          out+=e;i++;
        }else {
          //if (m==='.') alert(i.toString() +'.'+ cursor.toString());
          out+=m;add++;if (i<cursor){cursorPosition++;};
          /*if(m!='-'){ out+=m;}
          else {out+=String.fromCharCode(45);}
       	add++;if (i<cursor){cursorPosition++;};*/
        }
      }
    }
  }
  this.toMask = function (num, mask, cursor)
  {
    if (mask==='') return {'result':new String(num), 'cursor':cursor};
    var subMasks=mask.split(';');;
	    var result = [];
    num = new String(num);
    for(var r=0; r<subMasks.length; r++) {
      result[r]=__toMask(num, subMasks[r], cursor);
    }
    var betterResult=0;
    for(r=1; r<subMasks.length; r++) {
      if (result[r].value<result[betterResult].value) betterResult=r;
    }
    return result[betterResult];
  }
  this.cleanMask = function (num, mask, cursor)
  {
    mask = typeof(mask)==='undefined'?'':mask;
    if (mask==='') return {'result':new String(num), 'cursor':cursor};
    var a,r,others=[];
    num = new String(num);
    //alert(oDebug.var_dump(num));
    if (typeof(cursor)==='undefined') cursor=0;
    a = num.substr(0,cursor);
    for(r=0; r<reserved.length; r++) mask=mask.split(reserved[r]).join('');
    while(mask.length>0) {
      r=others.length;
      others[r] = mask.substr(0,1);
      mask= mask.split(others[r]).join('');
      num = num.split(others[r]).join('');
      cursor -= a.split(others[r]).length-1;
    }
    return {'result':num, 'cursor':cursor};
  }
  this.getId=function(element){
    var re=/(\[(\w+)\])+/;
		var res=re.exec(element.id);
		return res?res[2]:element.id;
  }
  this.getObject=function(element){
    var objId=G.getId(element);
    switch (element.tagName){
      case 'FORM':
        return eval('form_'+objId);
        break;
      default:
        if (element.form) {
          var formId=G.getId(element.form);
          return eval('form_'+objId+'.getElementByName("'+objId+'")');
        }
    }
  }

  /*BLINK EFECT*/
  this.blinked=[];
  this.blinkedt0=[];
  this.autoFirstField=true;
  this.pi=Math.atan(1)*4;
  this.highLight = function(element){
    var newdiv = $dce('div');
    newdiv.style.position="absolute";
    newdiv.style.display="inline";
    newdiv.style.height=element.clientHeight+2;
    newdiv.style.width=element.clientWidth+2;
    newdiv.style.background = "#FF5555";
    element.style.backgroundColor='#FFCACA';
    element.parentNode.insertBefore(newdiv,element);
    G.doBlinkEfect(newdiv,1000);
  }
  this.setOpacity=function(e,o){
    e.style.filter='alpha';
    if (e.filters) {
      e.filters['alpha'].opacity=o*100;
    } else {
      e.style.opacity=o;
    }
  }
  this.doBlinkEfect=function(div,T){
    var f=1/T;
    var j=G.blinked.length;
    G.blinked[j]=div;
    G.blinkedt0[j]=(new Date()).getTime();
    for(var i=1;i<=20;i++){
      setTimeout("G.setOpacity(G.blinked["+j+"],0.3-0.3*Math.cos(2*G.pi*((new Date()).getTime()-G.blinkedt0["+j+"])*"+f+"));",T/20*i);
    }
    setTimeout("G.blinked["+j+"].parentNode.removeChild(G.blinked["+j+"]);G.blinked["+j+"]=null;",T/20*i);
  }
  var alertPanel;
  this.alert=function(html, title , width, height, autoSize, modal, showModalColor, runScripts)
  {
    html='<div>'+html+'</div>';
  	width = (width)?width:300;
  	height = (height)?height:200;
  	autoSize = (showModalColor===false)?false:true;
  	modal = (modal===false)?false:true;
  	showModalColor = (showModalColor===true)?true:false;
  	var alertPanel = new leimnud.module.panel();
  	alertPanel.options = {
  		size:{w:width,h:height},
  		position:{center:true},
  		title: title,
  		theme: "processmaker",
  		control: { close :true, roll	:false, drag	:true, resize	:true},
  		fx: {
  			blinkToFront:true,
  			opacity	:true,
  			drag:true,
  			modal: modal
  		}
  	};
  	if(showModalColor===false)
  	{
  		alertPanel.styles.fx.opacityModal.Static='0';
  	}
  	alertPanel.make();
		alertPanel.addContent(html);
		if(runScripts)
		{
  		var myScripts=alertPanel.elements.content.getElementsByTagName('SCRIPT');
  		var sMyScripts=[];
  		for(var rr=0; rr<myScripts.length ; rr++) sMyScripts.push(myScripts[rr].innerHTML);
  		for(var rr=0; rr<myScripts.length ; rr++){
  		  try {
  		    if (sMyScripts[rr]!=='')
  		      if (window.execScript)
  	          window.execScript( sMyScripts[rr], 'javascript' );
  	        else
  	          window.setTimeout( sMyScripts[rr], 0 );
  		  } catch (e) {
  		    alert(e.description);
  		  }
  		}
  	}
		/* Autosize of panels, to fill only the first child of the
		 * rendered page (take note)
		 */
		var panelNonContentHeight = 44;
		var panelNonContentWidth  = 28;
		try {
		  if (autoSize)
		  {
		    var newW=alertPanel.elements.content.childNodes[0].clientWidth+panelNonContentWidth;
		    var newH=alertPanel.elements.content.childNodes[0].clientHeight+panelNonContentHeight;
  		  alertPanel.resize({w:((newW<width)?width:newW)});
  		  alertPanel.resize({h:((newH<height)?height:newH)});
  		}
	  } catch (e) {
	    alert(var_dump(e));
	  }
		delete newdiv;
		delete myScripts;
		alertPanel.command(alertPanel.loader.hide);
  }
}
var G = new G();


/* PACKAGE : DEBUG
 */
function G_Debugger()
{
  this.var_dump = function(obj)
  {
    var o,dump;
    dump='';
    if (typeof(obj)=='object')
    for(o in obj)
    {
      dump+='<b>'+o+'</b>:'+obj[o]+"<br>\n";
    }
    else
      dump=obj;
    debugDiv = document.getElementById('debug');
    if (debugDiv) debugDiv.innerHTML=dump;
    return dump;
  }
}
var oDebug = new G_Debugger();

/* PACKAGE : date field
 */
var datePickerPanel;

function showDatePicker(ev, formId, idName, value, min, max  ) {
	var coor = leimnud.dom.mouse(ev);
	var coorx = ( coor.x - 50 );
	var coory = ( coor.y - 40 );
	datePickerPanel=new leimnud.module.panel();
	datePickerPanel.options={
		size:{w:275,h:240},
		position:{x:coorx,y:coory},
		title:"Date Picker",
		theme:"panel",
		control:{
			close:true,
			drag:true
		},
		fx:{
			modal:true
		}
	};

	datePickerPanel.setStyle={
				containerWindow:{borderWidth:0}
			};
	datePickerPanel.make();
	datePickerPanel.idName = idName;
	datePickerPanel.formId = formId;

	var sUrl = "/controls/calendar.php?v="+value+"&d="+value+"&min="+min+"&max="+max;
	var r = new leimnud.module.rpc.xmlhttp({url: sUrl });
	r.callback=leimnud.closure({Function:function(rpc){
		datePickerPanel.addContent(rpc.xmlhttp.responseText);
	},args:r})
	r.make();

}

function moveDatePicker( n_datetime ) {
	var dtmin_value = document.getElementById ( 'dtmin_value' );
	var dtmax_value = document.getElementById ( 'dtmax_value' );

	var sUrl = "/controls/calendar.php?d="+n_datetime + '&min='+dtmin_value.value + '&max='+dtmax_value.value;
	var r = new leimnud.module.rpc.xmlhttp({url:sUrl });
	r.callback=leimnud.closure({Function:function(rpc){
		datePickerPanel.clearContent();
		datePickerPanel.addContent(rpc.xmlhttp.responseText);
	},args:r})
	r.make();
}

function selectDate(  day ) {
	var obj = document.getElementById ( 'span['+datePickerPanel.formId+'][' + datePickerPanel.idName + ']' );
	getField(datePickerPanel.idName, datePickerPanel.formId ).value = day;
	obj.innerHTML = day;
	datePickerPanel.remove();
}

function set_datetime(n_datetime, b_close) {
	moveDatePicker(n_datetime);
}

/* Functions for show and hide rows of a simple xmlform.
 * @author David Callizaya <davidsantos@colosa.com>
 */
function getRow( element ){
  if (typeof(element)==='string') element = getField(element);
  while ( element.tagName !== 'TR' ) {
    element=element.parentNode;
  }
  return element;
}
var getRowById=getRow;

function hideRow( element ){ //neyek
  var row=getRow(element);
  if (row) row.style.display='none';
  removeRequiredById(element);
  delete row;
}

var hideRowById=hideRow;
function showRow( element ){
  var row=getRow(element);
  requiredFields = [];
  fields = new String(document.getElementById('DynaformRequiredFields').value);
  fields = stripslashes(fields);
  requiredFieldsList = eval(fields);
  
  for(i=0; i<requiredFieldsList.length; i++){
	  requiredFields[i] = requiredFieldsList[i].name;
  }
  
  if ( requiredFields.inArray(element) ) {
	  enableRequiredById(element);
  }
  
  if (row) row.style.display='';
  delete row;
}
var showRowById=showRow;
function hideShowControl(element , name){
  var control;
  if (element) {
      control = element.parentNode.getElementsByTagName("div")[0];
    control.style.display=control.style.display==='none'?'':'none';
    if (control.style.display==='none') getField( name ).value='';
    delete control;
  }
}
/*SHOW/HIDE A SUBTITLE CONTENT*/
function contractSubtitle( subTitle ){
  subTitle=getRow(subTitle);
  var c=subTitle.cells[0].className;
  var a=subTitle.rowIndex;
  var t=subTitle.parentNode;
  for(var i=a+1,m=t.rows.length;i<m;i++){
    if (t.rows[i].cells.length==1) break;
    t.rows[i].style.display='none';
    var aAux = getControlsInTheRow(t.rows[i]);
    for (var j = 0; j < aAux.length; j++) {
      removeRequiredById(aAux[j]);
    }
  }
}
function expandSubtitle( subTitle ){
  subTitle=getRow(subTitle);
  var c=subTitle.cells[0].className;
  var a=subTitle.rowIndex;
  var t=subTitle.parentNode;
  for(var i=a+1,m=t.rows.length;i<m;i++){
    if (t.rows[i].cells.length==1) break;
    t.rows[i].style.display='';
    var aAux = getControlsInTheRow(t.rows[i]);
    for (var j = 0; j < aAux.length; j++) {
      enableRequiredById(aAux[j]);
    }
  }
}
function contractExpandSubtitle(subTitle){
  subTitle=getRow(subTitle);
  var c=subTitle.cells[0].className;
  var a=subTitle.rowIndex;
  var t=subTitle.parentNode;
  var contracted=false;
  for(var i=a+1,m=t.rows.length;i<m;i++){
    if (t.rows[i].cells.length==1) break;
    if (t.rows[i].style.display==='none'){
      contracted=true;
    }
  }
  if (contracted) expandSubtitle(subTitle);
  else contractSubtitle(subTitle);
}

var getControlsInTheRow = function(oRow) {
  var aAux1 = [];
  if (oRow.cells) {
    var i;
    var j;
    var sFieldName;
    for (i = 0; i < oRow.cells.length; i++) {
      var aAux2 = oRow.cells[i].getElementsByTagName('input');
      if (aAux2) {
        for (j = 0; j < aAux2.length; j++) {
          sFieldName = aAux2[j].id.replace('form[', '');
          sFieldName = sFieldName.replace(']', '');
          aAux1.push(sFieldName);
        }
      }
    }
  }
  return aAux1;
};

var notValidateThisFields = [];


var validateForm = function(aRequiredFields) {
	
	var sMessage = '';
	var invalid_fields = Array();
	
	for (var i = 0; i < aRequiredFields.length; i++) {
		aRequiredFields[i].label=(aRequiredFields[i].label=='')?aRequiredFields[i].name:aRequiredFields[i].label;
		 if (!notValidateThisFields.inArray(aRequiredFields[i].name)) {
		 		switch(aRequiredFields[i].type) {
		 			  case 'text':
		 			    var vtext = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){ 
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vtext.failed();
		 			    } else {
		 			    	vtext.passed();
		 			    }
		 			  break;

		 			  case 'dropdown':
		 				var vtext = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vtext.failed();
		 			    } else {
		 			    	vtext.passed();
		 			    }
		 			  break;

		 			  case 'textarea':
		 			    if(getField(aRequiredFields[i].name).value=='')
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			  break;

		 			  case 'password':
		 			    var vpass = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){ 
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vpass.failed();
		 			    } else {
		 			    	vpass.passed();
		 			    }
		 			  break;

		 			  case 'currency':
		 			    var vcurr = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){ 
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vcurr.failed();
		 			    } else {
		 			    	vcurr.passed();
		 			    }
		 			  break;

		 			  case 'percentage':
		 			    var vper = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){ 
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vper.failed();
		 			    } else {
		 			    	vper.passed();
		 			    }
		 			  break;

		 			  case 'yesno':
		 				var vtext = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vtext.failed();
		 			    } else {
		 			    	vtext.passed();
		 			    }
		 			  break;

		 			  case 'date':
		 				var vtext = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    	vtext.failed();
		 			    } else {
		 			    	vtext.passed();
		 			    }
		 			  break;

		 			  case 'file':
		 				var vtext = new input(getField(aRequiredFields[i].name));
		 			    if(getField(aRequiredFields[i].name).value==''){
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			   		vtext.failed();
		 			    } else {
		 			    	vtext.passed();
		 			    }
		 			  break;

		 			  case 'listbox':
		 			    var oAux = getField(aRequiredFields[i].name);
							var bOneSelected = false;
							for (var j = 0; j < oAux.options.length; j++) {
							 	if (oAux.options[j].selected) {
							    bOneSelected = true;
							    j = oAux.options.length;
							  }
							}
							if(bOneSelected == false)
								invalid_fields.push(aRequiredFields[i].label);
		 			  break;

		 			  case 'radiogroup':
		 			  	var x=aRequiredFields[i].name;
		 			  	var oAux = document.getElementsByName('form['+ x +']');
							var bOneChecked = false;
							for (var k = 0; k < oAux.length; k++) {
							    var r = oAux[k];
							    if (r.checked) {
							      bOneChecked = true;
							    	k = oAux.length;
							  	}
							}

							if(bOneChecked == false)
								invalid_fields.push(aRequiredFields[i].label);

		 			  break;

		 			  case 'checkgroup':
		 			    var bOneChecked = false;
		 			    var aAux = document.getElementsByName('form[' + aRequiredFields[i].name + '][]');
		 			    for (var k = 0; k < aAux.length; k++) {
							  if (aAux[k].checked) {
							    bOneChecked = true;
							    k = aAux.length;
							  }
							}
		 			    if(!bOneChecked) {
		 			    	invalid_fields.push(aRequiredFields[i].label);
		 			    }
		 			  break;
		 			}
		 	}
	}

	if (invalid_fields.length > 0) {
		//alert(G_STRINGS.ID_REQUIRED_FIELDS + ": \n\n" + sMessage);
		
		for(j=0; j<invalid_fields.length; j++){
			sMessage += (j > 0)? ', ': '';
			sMessage += invalid_fields[j]; 
		}
		
		new leimnud.module.app.alert().make({
     		label:G_STRINGS.ID_REQUIRED_FIELDS + ": <br/><br/>[ " + sMessage + " ]",
     		width:450,
     		height:140 + (parseInt(invalid_fields.length/10)*10)
    	});
		return false;
	}
	else {
	  return true;
  }
};

var getObject = function(sObject) {
  var i;
  var oAux = null;
  var iLength = __aObjects__.length;
  for (i = 0; i < iLength; i++) {
    oAux = __aObjects__[i].getElementByName(sObject);
    if (oAux) {
      return oAux;
    }
  }
  return oAux;
};

var saveAndRefreshForm = function(oObject) {
  if (oObject) {
    oObject.form.action += '&_REFRESH_=1';
    oObject.form.submit();
  }
  else {
    var oAux = window.document.getElementsByTagName('form');
    if (oAux.length > 0) {
      oAux[0].action += '&_REFRESH_=1';
      oAux[0].submit();
    }
  }
};

var removeRequiredById = function(sFieldName) {
  if (!notValidateThisFields.inArray(sFieldName)) {
	  notValidateThisFields.push(sFieldName);
	  var oAux = document.getElementById('__notValidateThisFields__');
	  if (oAux) {
	    oAux.value = notValidateThisFields.toJSONString();
	  }
  }
};

var enableRequiredById = function(sFieldName) {
  if (notValidateThisFields.inArray(sFieldName)) {
    var i;
    var aAux = [];
	  for(i = 0; i < notValidateThisFields.length; i++) {
      if(notValidateThisFields[i] != sFieldName) {
        aAux.push(notValidateThisFields[i]);
      }
    }
	  notValidateThisFields = aAux;
	  var oAux = document.getElementById('__notValidateThisFields__');
	  if (oAux) {
	    oAux.value = notValidateThisFields.toJSONString();
	  }
	}
};


function dynaformVerifyFieldName(){
	pme_validating = true;
	setTimeout('verifyFieldName1();',0);
	return true;
}

function verifyFieldName1(){
  var newFieldName=fieldName.value;
  var validatedFieldName=getField("PME_VALIDATE_NAME",fieldForm).value;
  var dField = new input(getField('PME_XMLNODE_NAME'));
  
  var valid=(newFieldName!=='')&&(((newFieldName!==savedFieldName)&&(validatedFieldName===''))||((newFieldName===savedFieldName)));
  if (valid){
    dField.passed();
    getField("PME_ACCEPT",fieldForm).disabled=false;
  }else{
    getField("PME_ACCEPT",fieldForm).disabled=true;
    dField.failed();
    new leimnud.module.app.alert().make({label: G_STRINGS.DYNAFIELD_ALREADY_EXIST});
    dField.focus();
  }
  pme_validating=false;
  return valid;
}

/*
function sumElem(s,ans,fs){
 	var sm=0;
 	   for(var j=0;j<fs.length;j++){
 	    sm+=parseInt(getField(fs[i]).value)
 	   }
 		ans.value=sm;
}
 
function isnumberk(texto){
 var numberk="0123456789.";	
 var letters="abcdefghijklmnopqrstuvwxyz";
 var i=0;
 var sw=1;
 
   //for(var i=0; i<texto.length; i++){
   while(i++ < texto.length && sw==1){
      if (numberk.indexOf(texto.charAt(i),0)==-1){
         sw=0;
      }
   }
   return sw;
} 
 
function typeOperation(cade){
 var operators=['+','-','*','/'];
 var sw=1;
 var i=0;

 while(i < operators.length && sw==1){
 	for(var j=0; j< cade.length; j++){
 	    if(cade.charAt(j)==operators[i]){
 	    	aOp=operators[i];sw=0;
 	    }
 		}
 	i++;
 	//alert(operators.indexOf(cade.charAt(i),0));
 	}
	return aOp;
}
function iniAcum(sym){
 if(sym=='+' || sym=='-')
 	return 0;
 else return 1;
 	
}
*/
function sumaformu(ee,fma){
	//copy the formula
  afma=fma;
  var operators=['+','-','*','/','(','[','{','}',']',')'];
  var wos;   
  //replace the operators symbols for empty space
  for(var i=0 ; i < operators.length ; i++) {
   var j=0;
    	while(j < fma.length){
    		nfma=fma.replace(operators[i]," ");
    		nfma=nfma.replace("  "," ");
    		fma=nfma;
    	j++;
    	}
    	
  }
//without spaces in the inicio of the formula
wos=nfma.replace(/^\s+/g,'');
nfma=wos.replace(/\s+$/g,'');
  
 	theelemts=nfma.split(" ");

   for (var i=0; i < theelemts.length; i++){ 
   	leimnud.event.add(getField(theelemts[i]),'keyup',function(){
   				calValue(afma,nfma,ee); 		
   		});
   	
   } 	
}

function calValue(afma,nfma,ans){
	
	theelemts=nfma.split(" ");
//to replace the field for the value and to evaluate the formula
   for (var i=0; i < theelemts.length; i++){ 
   	  if(getField(theelemts[i]).value){	
   	  	nfk=afma.replace(theelemts[i],getField(theelemts[i]).value)
   	  	afma=nfk;
   	  }
   	  
   } 	
	ans.value=eval(nfk);
	
}/* PACKAGE : GULLIVER FORMS
 */
function G_PagedTable( )
{
  this.id='';
  this.name='';
	this.event='';
	this.element = null;
	this.field='';
	this.ajaxUri='';
	this.currentOrder='';
	this.currentFilter='';
	this.currentPage=1;
	this.totalRows=0;
	this.rowsPerPage=25;
	this.onInsertField='';
	this.onDeleteField='';
	this.afterDeleteField='';
	this.onUpdateField='';
	this.form;
	var me = this;
  function loadTable( func, uri )  {
  	var div = document.getElementById('table[' + me.id + ']');
    var newContent=ajax_function(me.ajaxUri,func,uri);
  	if (div.outerHTML) {
  	  div.outerHTML=div.outerHTML.split(div.innerHTML).join(newContent);
  	} else {
  	  div.innerHTML=newContent;
  	}
  	var myScripts = div.getElementsByTagName('SCRIPT');
  	for(var rr=0; rr<myScripts.length ; rr++){
  	  try {
  	    if (myScripts[rr].innerHTML!=='')
  	      if (window.execScript)
  	          window.execScript( myScripts[rr].innerHTML, 'javascript' );
  	        else
  	          window.setTimeout( myScripts[rr].innerHTML, 0 );
  	  } catch (e) {
  	    alert(e.description);
  	  }
  	}
  	eval("if (loadPopupMenu_"+me.id+")loadPopupMenu_"+me.id+"();");
  	delete div;
  	delete myScripts;
  }
	this.showHideField=function(field)
	{
    uri='field='+encodeURIComponent(field);
    var ns=[],showIt=true;
    for(var i=0,j=me.shownFields.length;i<j;i++){
      if (me.shownFields[i]!==field) ns.push(me.shownFields[i]);
      else showIt=false;
    }
    if (showIt) ns.push(field);
    me.shownFields=ns;
    loadTable('showHideField',uri);
	}
	this.updateField=function(field, title, width, height)
	{
	  width = width  || 500;
	  height= height || 200;
		popupWindow(title,this.popupPage + '&field='+ encodeURIComponent(field), width, height);
		//this.form=document.getElementById('xmlPopup');
	}
	this.deleteField=function(field)
	{
  }
  this.doFilter = function ( searchForm )
  {
  	var inputs,r,uri;
  	inputs=searchForm.elements;
  	me.currentFilter='';
  	for(r=0;r<inputs.length;r++)
  	if(inputs[r].value!='')
  	{
  		if (me.currentFilter!='') me.currentFilter+='&';
  		me.currentFilter+=inputs[r].id+'='+encodeURIComponent(inputs[r].value);
  	}
  	uri='order='+encodeURIComponent(me.currentOrder)
  					+'&page='+me.currentPage;
  	if(me.currentFilter!='')
  		uri=uri		+'&filter='+encodeURIComponent(me.currentFilter);
    loadTable('paint',uri);
  	/*var ee = document.getElementById('table[' + me.id + ']');
  	var newContent=ajax_function(me.ajaxUri,'paint',uri);
  	if (ee.outerHTML) {
  	  ee.outerHTML=ee.outerHTML.split(ee.innerHTML).join(newContent);
  	} else {
  	  ee.innerHTML=newContent;
  	}
  	delete ee;
  	delete newContent;*/
  }
  this.doFastSearch = function( criteria )
  {
    uri='fastSearch='+encodeURIComponent(criteria);
  	/*var ee = document.getElementById('table[' + me.id + ']');
  	var newContent=ajax_function(me.ajaxUri,'paint',uri);
  	if (ee.outerHTML) {
  	  ee.outerHTML=ee.outerHTML.split(ee.innerHTML).join(newContent);
  	} else {
  	  ee.innerHTML=newContent;
  	}
  	delete ee;
  	delete newContent;*/
  	loadTable('paint',uri);
  }
  this.doSort = function ( fieldName , orderDirection)
  {
  	var inputs,r,uri;
  	if (orderDirection)
  	  me.currentOrder = fieldName + '=' + orderDirection;
  	else
  	  me.currentOrder = '';
  	uri='order='+encodeURIComponent(me.currentOrder)
  					+'&page='+me.currentPage;
  	if(me.currentFilter!='')
  		uri=uri		+'&filter='+encodeURIComponent(me.currentFilter);
  	loadTable('paint',uri);
  	/*var ee = document.getElementById('table[' + me.id + ']');
  	var newContent=ajax_function(me.ajaxUri,'paint',uri);
  	if (ee.outerHTML)
  	  ee.outerHTML=ee.outerHTML.split(ee.innerHTML).join(newContent);
  	else
  	  ee.innerHTML=newContent;
  	delete ee;
  	delete newContent;*/
  }
  this.refresh = function()
  {
    loadTable('paint','');
  	/*var ee = document.getElementById('table[' + me.id + ']');
  	var newContent=ajax_function(me.ajaxUri,'paint','');
  	if (ee.outerHTML)
  	  ee.outerHTML=ee.outerHTML.split(ee.innerHTML).join(newContent);
  	else
  	  ee.innerHTML=newContent;
  	delete ee;
  	delete newContent;*/
  }
  this.doGoToPage = function( nextCurrentPage )
  {
  	var inputs,r,uri;
  	me.currentPage = nextCurrentPage;
  	uri='order='+encodeURIComponent(me.currentOrder)
  					+'&page='+me.currentPage;
  	if(me.currentFilter!='')
  		uri=uri		+'&filter='+encodeURIComponent(me.currentFilter);
  	var ee = document.getElementById('table[' + me.id + ']');
  	var newContent=ajax_function(me.ajaxUri,'paint',uri);
  	if (ee.outerHTML)
  	  ee.outerHTML=ee.outerHTML.split(ee.innerHTML).join(newContent);
  	else
  	  ee.innerHTML=newContent;
  	delete ee;
  	delete newContent;
  }
  function encodeData(data)
  {
  	var enc;
  	enc='';
  	if (typeof(data)=='object')
  		for (u in data)
  		  enc+='&'+u+'='+encodeURIComponent(data[u]);
  	return encodeURIComponent(enc);
  }
}

function popup(url)
{
	var h;
	lleft=((document.body.clientWidth/2)+document.body.scrollLeft);
	ltop=((document.body.clientHeight/2)+document.body.scrollTop);

	panelPopup=leimnud.panel.create({w:popupWidth,h:popupHeight},{x:lleft,y:ltop,center:true},"popup",9,false,{
	botones:{cerrar:true},
	style:{
		panel:{
			border:"1px solid #000000",
			color:"#000000",
			backgroundColor:"#FEFEFE"
		},
				html:{
			textAlign:"left",
			padding:"5px",
			paddingTop:"12px"
		}
	}
	});

	leimnud.panel.loader.begin(panelPopup);
	uyh=new leimnud.rpc.xmlhttp({
		method    :"GET",
		url				: url,
		callback        :{
			_function	:function($)
			{
				leimnud.panel.loader.end($.arguments.obj);
				dc=$dce("div");
				leimnud.style.set(dc,{textAlign:"justify"});
				dc.innerHTML=$.request.responseText;
				leimnud.panel.html($.arguments.obj,dc);
				leimnud.panel.sombra($.arguments.obj,{sombra:{color:"#000000",opacity:30}});
			},
			arguments:{obj:panelPopup}
		}
	});
}

//global function for paged table
function setRowClass (theRow, thePointerClass)
{
    if (thePointerClass == '' || typeof(theRow.className) == 'undefined') {
        return false;
    }

    if(globalRowSelected == null || globalRowSelected.id != theRow.id){
    	globalRowSelectedClass = theRow.className;
    	theRow.className = thePointerClass;
	}
    return true;
}

var globalRowSelected = null;
var globalRowSelectedClass;

function focusRow(o, className){
	if (className == '' || typeof(o.className) == 'undefined') {
        return false;
    }
	
	/* restore its previous class at the other object*/
	if( globalRowSelected != null ){
		globalRowSelected.className = globalRowSelectedClass;
	}
	
	globalRowSelected = o;
	//globalRowSelectedClass = o.className;
	
	o.className = className;
	
    return true;
}
var G_Grid = function(oForm, sGridName) {
	// G_Field integration - Start
	var oGrid = this;
	this.parent = G_Field;
	this.parent(oForm, '', sGridName);
	// G_Field integration - End
	this.sGridName = sGridName;
	this.sAJAXPage = oForm.ajaxServer || '';
	this.oGrid = document.getElementById(this.sGridName);
	this.aFields = [];
	this.aElements = [];
	this.aFunctions = [];
	this.aFormulas = [];
	this.setFields = function(aFields, iRow) {
		this.aFields = aFields;
		var i, j, k, aAux, oAux, sDependentFields;
		for (i = 0; i < this.aFields.length; i++) {
			j = iRow || 1;
			switch (this.aFields[i].sType) {
			case 'text':
				while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']')) {
					this.aElements.push(new G_Text(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['
							+ this.aFields[i].sFieldName));
					this.aElements[this.aElements.length - 1].validate = this.aFields[i].oProperties.validate;
					if (aFields[i].oProperties) {
						this.aElements[this.aElements.length - 1].mask = aFields[i].oProperties.mask;
					}
					j++;
				}
				break;
			case 'currency':
				while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']')) {
					this.aElements.push(new G_Currency(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['
							+ this.aFields[i].sFieldName));
					if (aFields[i].oProperties) {
						this.aElements[this.aElements.length - 1].mask = aFields[i].oProperties.mask;
					}
					j++;
				}
				break;
			case 'percentage':
				while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']')) {
					this.aElements.push(new G_Percentage(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j
							+ '][' + this.aFields[i].sFieldName));
					if (aFields[i].oProperties) {
						this.aElements[this.aElements.length - 1].mask = aFields[i].oProperties.mask;
					}
					j++;
				}
				break;
			case 'dropdown':
				while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']')) {
					this.aElements.push(new G_DropDown(oForm, document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']'), this.sGridName + '][' + j + ']['
							+ this.aFields[i].sFieldName));
					if (aFields[i].oProperties) {
						this.aElements[this.aElements.length - 1].mask = aFields[i].oProperties.sMask;
					}
					j++;
				}
				break;
			}
		}
		// Set dependent fields
		for (i = 0; i < this.aFields.length; i++) {
			j = iRow || 1;
			while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + this.aFields[i].sFieldName + ']')) {
				if (aFields[i].oProperties.dependentFields != '') {
					this.setDependents(j, this.getElementByName(j, this.aFields[i].sFieldName), aFields[i].oProperties.dependentFields);
				}
				j++;
			}
		}
	};
	this.setDependents = function(iRow, me, theDependentFields) {
		var i;
		var dependentFields = theDependentFields || '';
		dependentFields = dependentFields.split(',');
		for (i = 0; i < dependentFields.length; i++) {
			var oField = this.getElementByName(iRow, dependentFields[i]);
			if (oField) {
				me.dependentFields[i] = oField;
				me.dependentFields[i].addDependencie(me);
			}
		}
	};
	this.unsetFields = function() {
		var i, j = 0, k, l = 0;
		k = this.aElements.length / this.aFields.length;
		for (i = 0; i < this.aFields.length; i++) {
			j += k;
			l++;
			this.aElements.splice(j - l, 1);
		}
		/*
		 * for (i = 0; i < this.aElements.length ;i++) {
		 * alert(this.aElements[i].name); }
		 */
	};
	this.getElementByName = function(iRow, sName) {
		var i;
		for (i = 0; i < this.aElements.length; i++) {
			if (this.aElements[i].name === this.sGridName + '][' + iRow + '][' + sName) {
				return this.aElements[i];
			}
		}
		return null;
	};
	this.getElementValueByName = function(iRow, sName) {
		var oAux = document.getElementById('form[' + this.sGridName + '][' + iRow + '][' + sName + ']');
		if (oAux) {
			return oAux.value;
		} else {
			return 'Object not found!';
		}
	};
	this.getFunctionResult = function(sName) {
		var oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + this.sGridName + '_' + sName + ']');
		if (oAux) {
			return oAux.value;
		} else {
			return 'Object not found!';
		}
	};

	this.addGridRow = function() {
		var i, aObjects;
		var oRow = document.getElementById('firstRow_' + this.sGridName);
		var aCells = oRow.getElementsByTagName('td');
		var oNewRow = this.oGrid.insertRow(this.oGrid.rows.length - 1);
		oNewRow.onmouseover=function(){
			highlightRow(this, '#D9E8FF');
		}
		oNewRow.onmouseout=function(){
			highlightRow(this, '#fff');
		}
		
		for (i = 0; i < aCells.length; i++) {
			oNewRow.appendChild(aCells[i].cloneNode(true));
			if (i == 0) {
				oNewRow.getElementsByTagName('td')[i].innerHTML = this.oGrid.rows.length - 2;
			} else {
				if (i == (aCells.length - 1)) {
					oNewRow.getElementsByTagName('td')[i].innerHTML = oNewRow.getElementsByTagName('td')[i].innerHTML.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
				} else {
					aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a');
					if (aObjects) {
						if (aObjects[0]) {
							if (aObjects[0].onclick) {
								sAux = new String(aObjects[0].onclick);
								eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';');
							}
						}
					}
					
					enodename = aCells[i].innerHTML.substring(aCells[i].innerHTML.indexOf('<')+1, aCells[i].innerHTML.indexOf(' '));
					enodename = enodename.toLowerCase();
					
					switch (enodename) {
					case 'input':
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('input');
						if (aObjects) {
							aObjects[0].name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							if (aObjects[0].type != 'checkbox') {
								aObjects[0].value = '';
							} else {
								aObjects[0].checked = false;
							}
							if (aObjects[1]) {
								if (aObjects[1].onclick) {
									sAux = new String(aObjects[1].onclick);
									eval('aObjects[1].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';');
								}
							}
						}
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('span');
						if (aObjects) {
							if (aObjects[0]) {
								// aObjects[0].name =
								// aObjects[0].name.replace(/\[1\]/g, '\[' +
								// (this.oGrid.rows.length - 2) + '\]');
								aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							}
							aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a');
							if (aObjects) {
								if (aObjects[0]) {
									if (aObjects[0].onclick) {
										sAux = new String(aObjects[0].onclick);
										eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';');
									}
								}
							}
						}
						
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('div');
						
						if (aObjects.length > 0) {
							
							if (aObjects[0]) {
								aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
								aObjects[0].name = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
								if (aObjects[0].onclick) {
									sAux = new String(aObjects[0].onclick);
									eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';');
								}
							}
							aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a');
							if (aObjects) {
								if (aObjects[0]) {
									if (aObjects[0].onclick) {
										sAux = new String(aObjects[0].onclick);
										eval('aObjects[0].onclick = ' + sAux.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]') + ';');
									}
								}
							}
						}
						break;
					case 'select':
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('select');
						if (aObjects) {
							var oAux = document.createElement(aObjects[0].tagName);
							oAux.name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							oAux.id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							for ( var j = 0; j < aObjects[0].options.length; j++) {
								var oOption = document.createElement('OPTION');
								oOption.value = aObjects[0].options[j].value;
								oOption.text = aObjects[0].options[j].text;
								oAux.options.add(oOption);
							}
							aObjects[0].parentNode.replaceChild(oAux, aObjects[0]);
							/*
							 * aObjects[0].name =
							 * aObjects[0].name.replace(/\[1\]/g, '\[' +
							 * (this.oGrid.rows.length - 2) + '\]');
							 * aObjects[0].id = aObjects[0].id.replace(/\[1\]/g,
							 * '\[' + (this.oGrid.rows.length - 2) + '\]');
							 * aObjects[0].selectedIndex = 0;
							 */
						}
						break;
					case 'textarea':
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('textarea');
						if (aObjects) {
							aObjects[0].name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							aObjects[0].value = '';
						}
						break;
						
					case 'a':
						aObjects = oNewRow.getElementsByTagName('td')[i].getElementsByTagName('a');
						if (aObjects) {
							aObjects[0].name = aObjects[0].name.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							aObjects[0].id = aObjects[0].id.replace(/\[1\]/g, '\[' + (this.oGrid.rows.length - 2) + '\]');
							aObjects[0].value = '';
						}
						break;

					default:
						oNewRow.getElementsByTagName('td')[i].innerHTML = '&nbsp;';
						break;
					}
					aObjects = null;
				}
			}
		}
		if (this.aFields.length > 0) {
			this.setFields(this.aFields, this.oGrid.rows.length - 2);
		}
		if (this.aFunctions.length > 0) {
			this.assignFunctions(this.aFunctions, 'change', this.oGrid.rows.length - 2);
		}
		if (this.aFormulas.length > 0) {
			this.assignFormulas(this.aFormulas, 'change', this.oGrid.rows.length - 2);
		}
		if (this.onaddrow) {
			this.onaddrow(this.oGrid.rows.length - 2);
		}
	};

	this.deleteGridRow = function(sRow) {
		var i, iRow, iRowAux, oAux;
		if (this.oGrid.rows.length == 3) {
			new leimnud.module.app.alert().make( {
				label : G_STRINGS.ID_MSG_NODELETE_GRID_ITEM
			});
			return false;
		}
		new leimnud.module.app.confirm().make( {
			label : G_STRINGS.ID_MSG_DELETE_GRID_ITEM,
			action : function() {

				sRow = sRow.replace('[', '');
				sRow = sRow.replace(']', '');
				iRow = Number(sRow);

				/*
				 * delete the respective session row grid variables from
				 * Dynaform - by Nyeke <erik@colosa.com
				 */
				deleteRowOnDybaform(this, iRow);

				iRowAux = iRow + 1;
				while (iRowAux <= (this.oGrid.rows.length - 2)) {
					for (i = 1; i < this.oGrid.rows[iRowAux - 1].cells.length; i++) {
						var oCell1 = this.oGrid.rows[iRowAux - 1].cells[i];
						var oCell2 = this.oGrid.rows[iRowAux].cells[i];
						switch (oCell1.innerHTML.replace(/^\s+|\s+$/g, '').substr(0, 6).toLowerCase()) {
						case '<input':
							aObjects1 = oCell1.getElementsByTagName('input');
							aObjects2 = oCell2.getElementsByTagName('input');
							if (aObjects1 && aObjects2) {
								aObjects1[0].value = aObjects2[0].value;
							}
							break;
						case '<selec':
							aObjects1 = oCell1.getElementsByTagName('select');
							aObjects2 = oCell2.getElementsByTagName('select');
							if (aObjects1 && aObjects2) {
								var vValue = aObjects2[0].value;
								/*
								 * for (var j = (aObjects1[0].options.length-1);
								 * j >= 0; j--) { aObjects1[0].options[j] =
								 * null; }
								 */
								aObjects1[0].options.length = 0;
								for ( var j = 0; j < aObjects2[0].options.length; j++) {
									var optn = $dce("OPTION");
									optn.text = aObjects2[0].options[j].text;
									optn.value = aObjects2[0].options[j].value;
									aObjects1[0].options[j] = optn;
								}
								aObjects1[0].value = vValue;
							}
							break;
						case '<texta':
							aObjects1 = oCell1.getElementsByTagName('textarea');
							aObjects2 = oCell2.getElementsByTagName('textarea');
							if (aObjects1 && aObjects2) {
								aObjects1[0].value = aObjects2[0].value;
							}
							break;
						default:
							if (oCell2.innerHTML.toLowerCase().indexOf('deletegridrow') == -1) {
								oCell1.innerHTML = oCell2.innerHTML;
							}
							break;
						}
					}
					iRowAux++;
				}
				this.oGrid.deleteRow(this.oGrid.rows.length - 2);
				if (this.sAJAXPage != '') {
				}
				if (this.aFields.length > 0) {
					this.unsetFields();
				}
				if (this.aFunctions.length > 0) {
					for (i = 0; i < this.aFunctions.length; i++) {
						oAux = document.getElementById('form[' + this.sGridName + '][1][' + this.aFunctions[i].sFieldName + ']');
						if (oAux) {
							switch (this.aFunctions[i].sFunction) {
							case 'sum':
								this.sum(false, oAux);
								break;
							case 'avg':
								this.avg(false, oAux);
								break;
							}
						}
					}
				}
				if (this.ondeleterow) {
					this.ondeleterow();
				}
			}.extend(this)
		});
	};
	this.assignFunctions = function(aFields, sEvent, iRow) {
		iRow = iRow || 1;
		var i, j, oAux;
		for (i = 0; i < aFields.length; i++) {
			j = iRow;
			while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + aFields[i].sFieldName + ']')) {
				switch (aFields[i].sFunction) {
				case 'sum':
					leimnud.event.add(oAux, sEvent, {
						method : this.sum,
						instance : this,
						event : true
					});
					break;
				case 'avg':
					leimnud.event.add(oAux, sEvent, {
						method : this.avg,
						instance : this,
						event : true
					});
					break;
				default:
					leimnud.event.add(oAux, sEvent, {
						method : aFields[i].sFunction,
						instance : this,
						event : true
					});
					break;
				}
				j++;
			}
		}
	};
	this.setFunctions = function(aFunctions) {
		this.aFunctions = aFunctions;
		this.assignFunctions(this.aFunctions, 'change');
	};
	this.sum = function(oEvent, oDOM) {
		oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement);
		var i, aAux, oAux, fTotal, sMask;
		aAux = oDOM.name.split('][');
		i = 1;
		fTotal = 0;
		aAux[2] = aAux[2].replace(']', '');
		while (oAux = this.getElementByName(i, aAux[2])) {
			fTotal += parseFloat(G.cleanMask(oAux.value() || 0, oAux.mask).result.replace(/,/g, ''));
			sMask = oAux.mask;
			i++;
		}
		fTotal = fTotal.toFixed(2);
		oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']');
		oAux.value = fTotal;
		oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']');
		// oAux.innerHTML = G.toMask(fTotal, sMask).result;
		oAux.innerHTML = fTotal;
	};
	this.avg = function(oEvent, oDOM) {
		oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement);
		var i, aAux, oAux, fTotal, sMask;
		aAux = oDOM.name.split('][');
		i = 1;
		fTotal = 0;
		aAux[2] = aAux[2].replace(']', '');
		while (oAux = this.getElementByName(i, aAux[2])) {
			fTotal += parseFloat(G.cleanMask(oAux.value() || 0, oAux.mask).result.replace(/,/g, ''));
			sMask = oAux.mask;
			i++;
		}
		i--;
		if (fTotal > 0) {
			fTotal = (fTotal / i).toFixed(2);
			oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']');
			oAux.value = fTotal;
			oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']');
			// oAux.innerHTML = G.toMask((fTotal / i), sMask).result;
			oAux.innerHTML = fTotal;
		} else {
			oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '_' + aAux[2] + ']');
			oAux.value = 0;
			oAux = document.getElementById('form[SYS_GRID_AGGREGATE_' + oGrid.sGridName + '__' + aAux[2] + ']');
			// oAux.innerHTML = G.toMask(0, sMask).result;
			oAux.innerHTML = 0;
		}
	};
	this.assignFormulas = function(aFields, sEvent, iRow) {
		iRow = iRow || 1;
		var i, j, oAux;
		for (i = 0; i < aFields.length; i++) {
			j = iRow;
			while (oAux = document.getElementById('form[' + this.sGridName + '][' + j + '][' + aFields[i].sDependentOf + ']')) {
				leimnud.event.add(oAux, sEvent, {
					method : this.evaluateFormula,
					instance : this,
					args : [ oAux, aFields[i] ],
					event : true
				});
				j++;
			}
		}
	};
	this.setFormulas = function(aFormulas) {
		this.aFormulas = aFormulas;
		this.assignFormulas(this.aFormulas, 'change');
	};
	this.evaluateFormula = function(oEvent, oDOM, oField) {
		oDOM = (oDOM ? oDOM : oEvent.target || window.event.srcElement);
		var aAux, sAux, i, oAux;
		var oContinue = true;
		aAux = oDOM.name.split('][');
		sAux = oField.sFormula.replace(/\+|\-|\*|\/|\(|\)|\[|\]|\{|\}|\%|\$/g, ' ');
		sAux = sAux.replace(/^\s+|\s+$/g, '');
		sAux = sAux.replace(/      /g, ' ');
		sAux = sAux.replace(/     /g, ' ');
		sAux = sAux.replace(/    /g, ' ');
		sAux = sAux.replace(/   /g, ' ');
		sAux = sAux.replace(/  /g, ' ');
		aFields = sAux.split(' ');
		aFields = aFields.unique();
		sAux = oField.sFormula;
		for (i = 0; i < aFields.length; i++) {
			if (!isNumber(aFields[i])) {
				oAux = this.getElementByName(aAux[1], aFields[i]);
				sAux = sAux.replace(new RegExp(aFields[i], "g"), "parseFloat(G.cleanMask(this.getElementByName(" + aAux[1] + ", '" + aFields[i] + "').value() || 0, '" + (oAux.sMask ? oAux.sMask : '')
						+ "').result.replace(/,/g, ''))");
				eval("if (!document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + aFields[i] + "]')) { oContinue = false; }");
			}
		}
		eval("if (!document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + "]')) { oContinue = false; }");
		if (oContinue) {
			eval("document.getElementById('" + aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + "]').value = (" + sAux + ').toFixed(2);');
			if (this.aFunctions.length > 0) {
				for (i = 0; i < this.aFunctions.length; i++) {
					oAux = document.getElementById('form[' + this.sGridName + '][' + aAux[1] + '][' + this.aFunctions[i].sFieldName + ']');
					if (oAux) {
						if (oAux.name == aAux[0] + '][' + aAux[1] + '][' + oField.sFieldName + ']') {
							switch (this.aFunctions[i].sFunction) {
							case 'sum':
								this.sum(false, oAux);
								break;
							case 'avg':
								this.avg(false, oAux);
								break;
							}
							if (oAux.fireEvent) {
								oAux.fireEvent('onchange');
							} else {
								var evObj = document.createEvent('HTMLEvents');
								evObj.initEvent('change', true, true);
								oAux.dispatchEvent(evObj);
							}
						}
					}
				}
			}
		} else {
			new leimnud.module.app.alert().make( {
				label : "Check your formula!\n\n" + oField.sFormula
			});
		}
	};
};

/**
 * Delete the respective session row grid variables from Dynaform
 * 
 * @Param grid
 *            [object: grid]
 * @Param sRow
 *            [integer: row index]
 * @author Erik Amaru Ortiz <erik@colosa.com, aortiz.erik@mail.com>
 */
function deleteRowOnDybaform(grid, sRow) {
	// alert(grid.sGridName + ' ' + sRow);
	var oRPC = new leimnud.module.rpc.xmlhttp( {
		url : '../gulliver/genericAjax',
		args : 'request=deleteGridRowOnDynaform&gridname=' + grid.sGridName + '&rowpos=' + sRow
	});
	oRPC.callback = function(rpc) {
		oPanel.loader.hide();
		scs = rpc.xmlhttp.responseText.extractScript();
		scs.evalScript();

		/**
		 * We verify if the debug panel is open, if it is-> update its content
		 */
		if (oDebuggerPanel != null) {
			oDebuggerPanel.clearContent();
			oDebuggerPanel.loader.show();
			var oRPC = new leimnud.module.rpc.xmlhttp( {
				url : 'cases_Ajax',
				args : 'action=showdebug'
			});
			oRPC.callback = function(rpc) {
				oDebuggerPanel.loader.hide();
				var scs = rpc.xmlhttp.responseText.extractScript();
				oDebuggerPanel.addContent(rpc.xmlhttp.responseText);
				scs.evalScript();
			}.extend(this);
			oRPC.make();
		}
	}.extend(this);
	oRPC.make();
}/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
 * -----------------------------------------------------------
 *
 * The DHTML Calendar, version 1.0 "It is happening again"
 *
 * Details and latest version at:
 * www.dynarch.com/projects/calendar
 *
 * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 */

// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $

/** The Calendar object constructor. */

Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
	// member variables
	this.activeDiv = null;
	this.currentDateEl = null;
	this.getDateStatus = null;
	this.getDateToolTip = null;
	this.getDateText = null;
	this.timeout = null;
	this.onSelected = onSelected || null;
	this.onClose = onClose || null;
	this.dragging = false;
	this.hidden = false;
	this.minYear = 1970;
	this.maxYear = 2050;
	this.dateFormat = "%Y/%m/%d"; //Calendar._TT["DEF_DATE_FORMAT"];
	this.ttDateFormat = "%Y/%m/%d"; // Calendar._TT["TT_DATE_FORMAT"];
	this.isPopup = true;
	this.weekNumbers = true;
	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
	this.showsOtherMonths = false;
	this.dateStr = dateStr;
	this.ar_days = null;
	this.showsTime = false;
	this.time24 = true;
	this.yearStep = 2;
	this.hiliteToday = true;
	this.multiple = null;
	// HTML elements
	this.table = null;
	this.element = null;
	this.tbody = null;
	this.firstdayname = null;
	// Combo boxes
	this.monthsCombo = null;
	this.yearsCombo = null;
	this.hilitedMonth = null;
	this.activeMonth = null;
	this.hilitedYear = null;
	this.activeYear = null;
	// Information
	this.dateClicked = false;

	// one-time initializations
	if (typeof Calendar._SDN == "undefined") {
		// table of short day names
		if (typeof Calendar._SDN_len == "undefined")
			Calendar._SDN_len = 3;
		var ar = new Array();

		for (var i = 8; i > 0;) {
			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
		}
		Calendar._SDN = ar;
		// table of short month names
		if (typeof Calendar._SMN_len == "undefined")
			Calendar._SMN_len = 3;
		ar = new Array();
		for (var i = 12; i > 0;) {
			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
		}
		Calendar._SMN = ar;
	}
};

// ** constants

/// "static", needed for event handlers.
Calendar._C = null;

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

Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );

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

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

// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
//        library, at some point.

Calendar.getAbsolutePos = function(el) {
	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(el.tagName);
	if (is_div && el.scrollLeft)
		SL = el.scrollLeft;
	if (is_div && el.scrollTop)
		ST = el.scrollTop;
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};

Calendar.isRelated = function (el, evt) {
	var related = evt.relatedTarget;
	if (!related) {
		var type = evt.type;
		if (type == "mouseover") {
			related = evt.fromElement;
		} else if (type == "mouseout") {
			related = evt.toElement;
		}
	}
	while (related) {
		if (related == el) {
			return true;
		}
		related = related.parentNode;
	}
	return false;
};

Calendar.removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

Calendar.addClass = function(el, className) {
	Calendar.removeClass(el, className);
	el.className += " " + className;
};

// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
Calendar.getElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
		f = f.parentNode;
	return f;
};

Calendar.getTargetElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
	while (f.nodeType != 1)
		f = f.parentNode;
	return f;
};

Calendar.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (Calendar.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

Calendar.addEvent = function(el, evname, func) {
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
};

Calendar.removeEvent = function(el, evname, func) {
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
};

Calendar.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

// END: UTILITY FUNCTIONS

// BEGIN: CALENDAR STATIC FUNCTIONS

/** Internal -- adds a set of events to make some element behave like a button. */
Calendar._add_evs = function(el) {
	with (Calendar) {
		addEvent(el, "mouseover", dayMouseOver);
		addEvent(el, "mousedown", dayMouseDown);
		addEvent(el, "mouseout", dayMouseOut);
		if (is_ie) {
			addEvent(el, "dblclick", dayMouseDblClick);
			el.setAttribute("unselectable", true);
		}
	}
};

Calendar.findMonth = function(el) {
	if (typeof el.month != "undefined") {
		return el;
	} else if (typeof el.parentNode.month != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.findYear = function(el) {
	if (typeof el.year != "undefined") {
		return el;
	} else if (typeof el.parentNode.year != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.showMonthsCombo = function () {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var mc = cal.monthsCombo;
	if (cal.hilitedMonth) {
		Calendar.removeClass(cal.hilitedMonth, "hilite");
	}
	if (cal.activeMonth) {
		Calendar.removeClass(cal.activeMonth, "active");
	}
	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
	Calendar.addClass(mon, "active");
	cal.activeMonth = mon;
	var s = mc.style;
	s.display = "block";
	if (cd.navtype < 0)
		s.left = cd.offsetLeft + "px";
	else {
		var mcw = mc.offsetWidth;
		if (typeof mcw == "undefined")
			// Konqueror brain-dead techniques
			mcw = 50;
		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
	}
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
};

Calendar.showYearsCombo = function (fwd) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var yc = cal.yearsCombo;
	if (cal.hilitedYear) {
		Calendar.removeClass(cal.hilitedYear, "hilite");
	}
	if (cal.activeYear) {
		Calendar.removeClass(cal.activeYear, "active");
	}
	cal.activeYear = null;
	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
	var yr = yc.firstChild;
	var show = false;
	for (var i = 12; i > 0; --i) {
		if (Y >= cal.minYear && Y <= cal.maxYear) {
			yr.innerHTML = Y;
			yr.year = Y;
			yr.style.display = "block";
			show = true;
		} else {
			yr.style.display = "none";
		}
		yr = yr.nextSibling;
		Y += fwd ? cal.yearStep : -cal.yearStep;
	}
	if (show) {
		var s = yc.style;
		s.display = "block";
		if (cd.navtype < 0)
			s.left = cd.offsetLeft + "px";
		else {
			var ycw = yc.offsetWidth;
			if (typeof ycw == "undefined")
				// Konqueror brain-dead techniques
				ycw = 50;
			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
		}
		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	}
};

// event handlers

Calendar.tableMouseUp = function(ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	if (cal.timeout) {
		clearTimeout(cal.timeout);
	}
	var el = cal.activeDiv;
	if (!el) {
		return false;
	}
	var target = Calendar.getTargetElement(ev);
	ev || (ev = window.event);
	Calendar.removeClass(el, "active");
	if (target == el || target.parentNode == el) {
		Calendar.cellClick(el, ev);
	}
	var mon = Calendar.findMonth(target);
	var date = null;
	if (mon) {
		date = new Date(cal.date);
		if (mon.month != date.getMonth()) {
			date.setMonth(mon.month);
			cal.setDate(date);
			cal.dateClicked = false;
			cal.callHandler();
		}
	} else {
		var year = Calendar.findYear(target);
		if (year) {
			date = new Date(cal.date);
			if (year.year != date.getFullYear()) {
				date.setFullYear(year.year);
				cal.setDate(date);
				cal.dateClicked = false;
				cal.callHandler();
			}
		}
	}
	with (Calendar) {
		removeEvent(document, "mouseup", tableMouseUp);
		removeEvent(document, "mouseover", tableMouseOver);
		removeEvent(document, "mousemove", tableMouseOver);
		cal._hideCombos();
		_C = null;
		return stopEvent(ev);
	}
};

Calendar.tableMouseOver = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return;
	}
	var el = cal.activeDiv;
	var target = Calendar.getTargetElement(ev);
	if (target == el || target.parentNode == el) {
		Calendar.addClass(el, "hilite active");
		Calendar.addClass(el.parentNode, "rowhilite");
	} else {
		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
			Calendar.removeClass(el, "active");
		Calendar.removeClass(el, "hilite");
		Calendar.removeClass(el.parentNode, "rowhilite");
	}
	ev || (ev = window.event);
	if (el.navtype == 50 && target != el) {
		var pos = Calendar.getAbsolutePos(el);
		var w = el.offsetWidth;
		var x = ev.clientX;
		var dx;
		var decrease = true;
		if (x > pos.x + w) {
			dx = x - pos.x - w;
			decrease = false;
		} else
			dx = pos.x - x;

		if (dx < 0) dx = 0;
		var range = el._range;
		var current = el._current;
		var count = Math.floor(dx / 10) % range.length;
		for (var i = range.length; --i >= 0;)
			if (range[i] == current)
				break;
		while (count-- > 0)
			if (decrease) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
		var newval = range[i];
		el.innerHTML = newval;

		cal.onUpdateTime();
	}
	var mon = Calendar.findMonth(target);
	if (mon) {
		if (mon.month != cal.date.getMonth()) {
			if (cal.hilitedMonth) {
				Calendar.removeClass(cal.hilitedMonth, "hilite");
			}
			Calendar.addClass(mon, "hilite");
			cal.hilitedMonth = mon;
		} else if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
	} else {
		if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
		var year = Calendar.findYear(target);
		if (year) {
			if (year.year != cal.date.getFullYear()) {
				if (cal.hilitedYear) {
					Calendar.removeClass(cal.hilitedYear, "hilite");
				}
				Calendar.addClass(year, "hilite");
				cal.hilitedYear = year;
			} else if (cal.hilitedYear) {
				Calendar.removeClass(cal.hilitedYear, "hilite");
			}
		} else if (cal.hilitedYear) {
			Calendar.removeClass(cal.hilitedYear, "hilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.tableMouseDown = function (ev) {
	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
		return Calendar.stopEvent(ev);
	}
};

Calendar.calDragIt = function (ev) {
	var cal = Calendar._C;
	if (!(cal && cal.dragging)) {
		return false;
	}
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posX = ev.pageX;
		posY = ev.pageY;
	}
	cal.hideShowCovered();
	var st = cal.element.style;
	st.left = (posX - cal.xOffs) + "px";
	st.top = (posY - cal.yOffs) + "px";
	return Calendar.stopEvent(ev);
};

Calendar.calDragEnd = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	cal.dragging = false;
	with (Calendar) {
		removeEvent(document, "mousemove", calDragIt);
		removeEvent(document, "mouseup", calDragEnd);
		tableMouseUp(ev);
	}
	cal.hideShowCovered();
};

Calendar.dayMouseDown = function(ev) {
	var el = Calendar.getElement(ev);
	if (el.disabled) {
		return false;
	}
	var cal = el.calendar;
	cal.activeDiv = el;
	Calendar._C = cal;
	if (el.navtype != 300) with (Calendar) {
		if (el.navtype == 50) {
			el._current = el.innerHTML;
			addEvent(document, "mousemove", tableMouseOver);
		} else
			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
		addClass(el, "hilite active");
		addEvent(document, "mouseup", tableMouseUp);
	} else if (cal.isPopup) {
		cal._dragStart(ev);
	}
	if (el.navtype == -1 || el.navtype == 1) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
	} else if (el.navtype == -2 || el.navtype == 2) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
	} else {
		cal.timeout = null;
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseDblClick = function(ev) {
	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
	if (Calendar.is_ie) {
		document.selection.empty();
	}
};

Calendar.dayMouseOver = function(ev) {
	var el = Calendar.getElement(ev);
	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
		return false;
	}
	if (el.ttip) {
		if (el.ttip.substr(0, 1) == "_") {
			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
		}
		el.calendar.tooltips.innerHTML = el.ttip;
	}
	if (el.navtype != 300) {
		Calendar.addClass(el, "hilite");
		if (el.caldate) {
			Calendar.addClass(el.parentNode, "rowhilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseOut = function(ev) {
	with (Calendar) {
		var el = getElement(ev);
		if (isRelated(el, ev) || _C || el.disabled)
			return false;
		removeClass(el, "hilite");
		if (el.caldate)
			removeClass(el.parentNode, "rowhilite");
		if (el.calendar)
			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
		return stopEvent(ev);
	}
};

/**
 *  A generic "click" handler :) handles all types of buttons defined in this
 *  calendar.
 */
Calendar.cellClick = function(el, ev) {
	var cal = el.calendar;
	var closing = false;
	var newdate = false;
	var date = null;
	if (typeof el.navtype == "undefined") {
		if (cal.currentDateEl) {
			Calendar.removeClass(cal.currentDateEl, "selected");
			Calendar.addClass(el, "selected");
			closing = (cal.currentDateEl == el);
			if (!closing) {
				cal.currentDateEl = el;
			}
		}
		cal.date.setDateOnly(el.caldate);
		date = cal.date;
		var other_month = !(cal.dateClicked = !el.otherMonth);
		if (!other_month && !cal.currentDateEl)
			cal._toggleMultipleDate(new Date(date));
		else
			newdate = !el.disabled;
		// a date was clicked
		if (other_month)
			cal._init(cal.firstDayOfWeek, date);
	} else {
		if (el.navtype == 200) {
			Calendar.removeClass(el, "hilite");
			cal.callCloseHandler();
			return;
		}
		date = new Date(cal.date);
		if (el.navtype == 0)
			date.setDateOnly(new Date()); // TODAY
		// unless "today" was clicked, we assume no date was clicked so
		// the selected handler will know not to close the calenar when
		// in single-click mode.
		// cal.dateClicked = (el.navtype == 0);
		cal.dateClicked = false;
		var year = date.getFullYear();
		var mon = date.getMonth();
		function setMonth(m) {
			var day = date.getDate();
			var max = date.getMonthDays(m);
			if (day > max) {
				date.setDate(max);
			}
			date.setMonth(m);
		};
		switch (el.navtype) {
		    case 400:
			Calendar.removeClass(el, "hilite");
			var text = Calendar._TT["ABOUT"];
			if (typeof text != "undefined") {
				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
			} else {
				// FIXME: this should be removed as soon as lang files get updated!
				text = "Help and about box text is not translated into this language.\n" +
					"If you know this language and you feel generous please update\n" +
					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
					"Thank you!\n" +
					"http://dynarch.com/mishoo/calendar.epl\n";
			}
			alert(text);
			return;
		    case -2:
			if (year > cal.minYear) {
				date.setFullYear(year - 1);
			}
			break;
		    case -1:
			if (mon > 0) {
				setMonth(mon - 1);
			} else if (year-- > cal.minYear) {
				date.setFullYear(year);
				setMonth(11);
			}
			break;
		    case 1:
			if (mon < 11) {
				setMonth(mon + 1);
			} else if (year < cal.maxYear) {
				date.setFullYear(year + 1);
				setMonth(0);
			}
			break;
		    case 2:
			if (year < cal.maxYear) {
				date.setFullYear(year + 1);
			}
			break;
		    case 100:
			cal.setFirstDayOfWeek(el.fdow);
			return;
		    case 50:
			var range = el._range;
			var current = el.innerHTML;
			for (var i = range.length; --i >= 0;)
				if (range[i] == current)
					break;
			if (ev && ev.shiftKey) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
			var newval = range[i];
			el.innerHTML = newval;
			cal.onUpdateTime();
			return;
		    case 0:
			// TODAY will bring us here
			if ((typeof cal.getDateStatus == "function") &&
			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
				return false;
			}
			break;
		}
		if (!date.equalsTo(cal.date)) {
			cal.setDate(date);
			newdate = true;
		} else if (el.navtype == 0)
			newdate = closing = true;
	}
	if (typeof el.navtype != "undefined") {
	  if (el.navtype >= -2 && el.navtype <= 2) {
	    newdate = false;
	  }
	}
	if (newdate) {
		ev && cal.callHandler();
	}
	if (closing) {
		Calendar.removeClass(el, "hilite");
		ev && cal.callCloseHandler();
	}
};

// END: CALENDAR STATIC FUNCTIONS

// BEGIN: CALENDAR OBJECT FUNCTIONS

/**
 *  This function creates the calendar inside the given parent.  If _par is
 *  null than it creates a popup calendar inside the BODY element.  If _par is
 *  an element, be it BODY, then it creates a non-popup calendar (still
 *  hidden).  Some properties need to be set before calling this function.
 */
Calendar.prototype.create = function (_par) {
	var parent = null;
	if (! _par) {
		// default parent is the document body, in which case we create
		// a popup calendar.
		parent = document.getElementsByTagName("body")[0];
		this.isPopup = true;
	} else {
		parent = _par;
		this.isPopup = false;
	}
	this.date = this.dateStr ? new Date(this.dateStr) : new Date();

	var table = Calendar.createElement("table");
	this.table = table;
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.calendar = this;
	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);

	var div = Calendar.createElement("div");
	this.element = div;
	div.className = "calendar";
	if (this.isPopup) {
		div.style.position = "absolute";
		div.style.display = "none";
	}
	div.appendChild(table);

	var thead = Calendar.createElement("thead", table);
	var cell = null;
	var row = null;

	var cal = this;
	var hh = function (text, cs, navtype) {
		cell = Calendar.createElement("td", row);
		cell.colSpan = cs;
		cell.className = "button";
		if (navtype != 0 && Math.abs(navtype) <= 2)
			cell.className += " nav";
		Calendar._add_evs(cell);
		cell.calendar = cal;
		cell.navtype = navtype;
		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
		return cell;
	};

	row = Calendar.createElement("tr", thead);
	var title_length = 6;
	(this.isPopup) && --title_length;
	(this.weekNumbers) && ++title_length;

	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
	this.title = hh("", title_length, 300);
	this.title.className = "title";
	if (this.isPopup) {
		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
		this.title.style.cursor = "move";
		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
	}

	row = Calendar.createElement("tr", thead);
	row.className = "headrow";

	this._nav_py = hh("&#x00ab;", 1, -2);
	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];

	this._nav_pm = hh("&#x2039;", 1, -1);
	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];

	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
	this._nav_now.ttip = Calendar._TT["GO_TODAY"];

	this._nav_nm = hh("&#x203a;", 1, 1);
	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];

	this._nav_ny = hh("&#x00bb;", 1, 2);
	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];

	// day names
	row = Calendar.createElement("tr", thead);
	row.className = "daynames";
	if (this.weekNumbers) {
		cell = Calendar.createElement("td", row);
		cell.className = "name wn";
		cell.innerHTML = Calendar._TT["WK"];
	}
	for (var i = 7; i > 0; --i) {
		cell = Calendar.createElement("td", row);
		if (!i) {
			cell.navtype = 100;
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}
	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
	this._displayWeekdays();

	var tbody = Calendar.createElement("tbody", table);
	this.tbody = tbody;

	for (i = 6; i > 0; --i) {
		row = Calendar.createElement("tr", tbody);
		if (this.weekNumbers) {
			cell = Calendar.createElement("td", row);
		}
		for (var j = 7; j > 0; --j) {
			cell = Calendar.createElement("td", row);
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}

	if (this.showsTime) {
		row = Calendar.createElement("tr", tbody);
		row.className = "time";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = 2;
		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = this.weekNumbers ? 4 : 3;

		(function(){
			function makeTimePart(className, init, range_start, range_end) {
				var part = Calendar.createElement("span", cell);
				part.className = className;
				part.innerHTML = init;
				part.calendar = cal;
				part.ttip = Calendar._TT["TIME_PART"];
				part.navtype = 50;
				part._range = [];
				if (typeof range_start != "number")
					part._range = range_start;
				else {
					for (var i = range_start; i <= range_end; ++i) {
						var txt;
						if (i < 10 && range_end >= 10) txt = '0' + i;
						else txt = '' + i;
						part._range[part._range.length] = txt;
					}
				}
				Calendar._add_evs(part);
				return part;
			};
			var hrs = cal.date.getHours();
			var mins = cal.date.getMinutes();
			var t12 = !cal.time24;
			var pm = (hrs > 12);
			if (t12 && pm) hrs -= 12;
			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
			var span = Calendar.createElement("span", cell);
			span.innerHTML = ":";
			span.className = "colon";
			var M = makeTimePart("minute", mins, 0, 59);
			var AP = null;
			cell = Calendar.createElement("td", row);
			cell.className = "time";
			cell.colSpan = 2;
			if (t12)
				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
			else
				cell.innerHTML = "&nbsp;";

			cal.onSetTime = function() {
				var pm, hrs = this.date.getHours(),
					mins = this.date.getMinutes();
				if (t12) {
					pm = (hrs >= 12);
					if (pm) hrs -= 12;
					if (hrs == 0) hrs = 12;
					AP.innerHTML = pm ? "pm" : "am";
				}
				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
			};

			cal.onUpdateTime = function() {
				var date = this.date;
				var h = parseInt(H.innerHTML, 10);
				if (t12) {
					if (/pm/i.test(AP.innerHTML) && h < 12)
						h += 12;
					else if (/am/i.test(AP.innerHTML) && h == 12)
						h = 0;
				}
				var d = date.getDate();
				var m = date.getMonth();
				var y = date.getFullYear();
				date.setHours(h);
				date.setMinutes(parseInt(M.innerHTML, 10));
				date.setFullYear(y);
				date.setMonth(m);
				date.setDate(d);
				this.dateClicked = false;
				this.callHandler();
			};
		})();
	} else {
		this.onSetTime = this.onUpdateTime = function() {};
	}

	var tfoot = Calendar.createElement("tfoot", table);

	row = Calendar.createElement("tr", tfoot);
	row.className = "footrow";

	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
	cell.className = "ttip";
	if (this.isPopup) {
		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
		cell.style.cursor = "move";
	}
	this.tooltips = cell;

	div = Calendar.createElement("div", this.element);
	this.monthsCombo = div;
	div.className = "combo";
	for (i = 0; i < Calendar._MN.length; ++i) {
		var mn = Calendar.createElement("div");
		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
		mn.month = i;
		mn.innerHTML = Calendar._SMN[i];
		div.appendChild(mn);
	}

	div = Calendar.createElement("div", this.element);
	this.yearsCombo = div;
	div.className = "combo";
	for (i = 12; i > 0; --i) {
		var yr = Calendar.createElement("div");
		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
		div.appendChild(yr);
	}

	this._init(this.firstDayOfWeek, this.date);
	parent.appendChild(this.element);
};

/** keyboard navigation, only for popup calendars */
Calendar._keyEvent = function(ev) {
	var cal = window._dynarch_popupCalendar;
	if (!cal || cal.multiple)
		return false;
	(Calendar.is_ie) && (ev = window.event);
	var act = (Calendar.is_ie || ev.type == "keypress"),
		K = ev.keyCode;
	if (ev.ctrlKey) {
		switch (K) {
		    case 37: // KEY left
			act && Calendar.cellClick(cal._nav_pm);
			break;
		    case 38: // KEY up
			act && Calendar.cellClick(cal._nav_py);
			break;
		    case 39: // KEY right
			act && Calendar.cellClick(cal._nav_nm);
			break;
		    case 40: // KEY down
			act && Calendar.cellClick(cal._nav_ny);
			break;
		    default:
			return false;
		}
	} else switch (K) {
	    case 32: // KEY space (now)
		Calendar.cellClick(cal._nav_now);
		break;
	    case 27: // KEY esc
		act && cal.callCloseHandler();
		break;
	    case 37: // KEY left
	    case 38: // KEY up
	    case 39: // KEY right
	    case 40: // KEY down
		if (act) {
			var prev, x, y, ne, el, step;
			prev = K == 37 || K == 38;
			step = (K == 37 || K == 39) ? 1 : 7;
			function setVars() {
				el = cal.currentDateEl;
				var p = el.pos;
				x = p & 15;
				y = p >> 4;
				ne = cal.ar_days[y][x];
			};setVars();
			function prevMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() - step);
				cal.setDate(date);
			};
			function nextMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() + step);
				cal.setDate(date);
			};
			while (1) {
				switch (K) {
				    case 37: // KEY left
					if (--x >= 0)
						ne = cal.ar_days[y][x];
					else {
						x = 6;
						K = 38;
						continue;
					}
					break;
				    case 38: // KEY up
					if (--y >= 0)
						ne = cal.ar_days[y][x];
					else {
						prevMonth();
						setVars();
					}
					break;
				    case 39: // KEY right
					if (++x < 7)
						ne = cal.ar_days[y][x];
					else {
						x = 0;
						K = 40;
						continue;
					}
					break;
				    case 40: // KEY down
					if (++y < cal.ar_days.length)
						ne = cal.ar_days[y][x];
					else {
						nextMonth();
						setVars();
					}
					break;
				}
				break;
			}
			if (ne) {
				if (!ne.disabled)
					Calendar.cellClick(ne);
				else if (prev)
					prevMonth();
				else
					nextMonth();
			}
		}
		break;
	    case 13: // KEY enter
		if (act)
			Calendar.cellClick(cal.currentDateEl, ev);
		break;
	    default:
		return false;
	}
	return Calendar.stopEvent(ev);
};

/**
 *  (RE)Initializes the calendar to the given date and firstDayOfWeek
 */
Calendar.prototype._init = function (firstDayOfWeek, date) {
	var today = new Date(),
		TY = today.getFullYear(),
		TM = today.getMonth(),
		TD = today.getDate();
	this.table.style.visibility = "hidden";
	var year = date.getFullYear();
	if (year < this.minYear) {
		year = this.minYear;
		date.setFullYear(year);
	} else if (year > this.maxYear) {
		year = this.maxYear;
		date.setFullYear(year);
	}
	this.firstDayOfWeek = firstDayOfWeek;
	this.date = new Date(date);
	var month = date.getMonth();
	var mday = date.getDate();
	var no_days = date.getMonthDays();

	// calendar voodoo for computing the first day that would actually be
	// displayed in the calendar, even if it's from the previous month.
	// WARNING: this is magic. ;-)
	date.setDate(1);
	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
	if (day1 < 0)
		day1 += 7;
	date.setDate(-day1);
	date.setDate(date.getDate() + 1);

	var row = this.tbody.firstChild;
	var MN = Calendar._SMN[month];
	var ar_days = this.ar_days = new Array();
	var weekend = Calendar._TT["WEEKEND"];
	var dates = this.multiple ? (this.datesCells = {}) : null;
	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
		var cell = row.firstChild;
		if (this.weekNumbers) {
			cell.className = "day wn";
			cell.innerHTML = date.getWeekNumber();
			cell = cell.nextSibling;
		}
		row.className = "daysrow";
		var hasdays = false, iday, dpos = ar_days[i] = [];
		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
			iday = date.getDate();
			var wday = date.getDay();
			cell.className = "day";
			cell.pos = i << 4 | j;
			dpos[j] = cell;
			var current_month = (date.getMonth() == month);
			if (!current_month) {
				if (this.showsOtherMonths) {
					cell.className += " othermonth";
					cell.otherMonth = true;
				} else {
					cell.className = "emptycell";
					cell.innerHTML = "&nbsp;";
					cell.disabled = true;
					continue;
				}
			} else {
				cell.otherMonth = false;
				hasdays = true;
			}
			cell.disabled = false;
			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
			if (dates)
				dates[date.print("%Y%m%d")] = cell;
			if (this.getDateStatus) {
				var status = this.getDateStatus(date, year, month, iday);
				if (this.getDateToolTip) {
					var toolTip = this.getDateToolTip(date, year, month, iday);
					if (toolTip)
						cell.title = toolTip;
				}
				if (status === true) {
					cell.className += " disabled";
					cell.disabled = true;
				} else {
					if (/disabled/i.test(status))
						cell.disabled = true;
					cell.className += " " + status;
				}
			}
			if (!cell.disabled) {
				cell.caldate = new Date(date);
				cell.ttip = "_";
				if (!this.multiple && current_month
				    && iday == mday && this.hiliteToday) {
					cell.className += " selected";
					this.currentDateEl = cell;
				}
				if (date.getFullYear() == TY &&
				    date.getMonth() == TM &&
				    iday == TD) {
					cell.className += " today";
					cell.ttip += Calendar._TT["PART_TODAY"];
				}
				if (weekend.indexOf(wday.toString()) != -1)
					cell.className += cell.otherMonth ? " oweekend" : " weekend";
			}
		}
		if (!(hasdays || this.showsOtherMonths))
			row.className = "emptyrow";
	}
	this.title.innerHTML = Calendar._MN[month] + ", " + year;
	this.onSetTime();
	this.table.style.visibility = "visible";
	this._initMultipleDates();
	// PROFILE
	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};

Calendar.prototype._initMultipleDates = function() {
	if (this.multiple) {
		for (var i in this.multiple) {
			var cell = this.datesCells[i];
			var d = this.multiple[i];
			if (!d)
				continue;
			if (cell)
				cell.className += " selected";
		}
	}
};

Calendar.prototype._toggleMultipleDate = function(date) {
	if (this.multiple) {
		var ds = date.print("%Y%m%d");
		var cell = this.datesCells[ds];
		if (cell) {
			var d = this.multiple[ds];
			if (!d) {
				Calendar.addClass(cell, "selected");
				this.multiple[ds] = date;
			} else {
				Calendar.removeClass(cell, "selected");
				delete this.multiple[ds];
			}
		}
	}
};

Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
	this.getDateToolTip = unaryFunction;
};

/**
 *  Calls _init function above for going to a certain date (but only if the
 *  date is different than the currently selected one).
 */
Calendar.prototype.setDate = function (date) {
	if (!date.equalsTo(this.date)) {
		this._init(this.firstDayOfWeek, date);
	}
};

/**
 *  Refreshes the calendar.  Useful if the "disabledHandler" function is
 *  dynamic, meaning that the list of disabled date can change at runtime.
 *  Just * call this function if you think that the list of disabled dates
 *  should * change.
 */
Calendar.prototype.refresh = function () {
	this._init(this.firstDayOfWeek, this.date);
};

/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
	this._init(firstDayOfWeek, this.date);
	this._displayWeekdays();
};

/**
 *  Allows customization of what dates are enabled.  The "unaryFunction"
 *  parameter must be a function object that receives the date (as a JS Date
 *  object) and returns a boolean value.  If the returned value is true then
 *  the passed date will be marked as disabled.
 */
Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
	this.getDateStatus = unaryFunction;
};

/** Customization of allowed year range for the calendar. */
Calendar.prototype.setRange = function (a, z) {
	this.minYear = a;
	this.maxYear = z;
};

/** Calls the first user handler (selectedHandler). */
Calendar.prototype.callHandler = function () {
	if (this.onSelected) {
		this.onSelected(this, this.date.print(this.dateFormat));
	}
};

/** Calls the second user handler (closeHandler). */
Calendar.prototype.callCloseHandler = function () {
	if (this.onClose) {
		this.onClose(this);
	}
	this.hideShowCovered();
};

/** Removes the calendar object from the DOM tree and destroys it. */
Calendar.prototype.destroy = function () {
	var el = this.element.parentNode;
	el.removeChild(this.element);
	Calendar._C = null;
	window._dynarch_popupCalendar = null;
};

/**
 *  Moves the calendar element to a different section in the DOM tree (changes
 *  its parent).
 */
Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};

// This gets called when the user presses a mouse button anywhere in the
// document, if the calendar is shown.  If the click was outside the open
// calendar this function closes it.
Calendar._checkCalendar = function(ev) {
	var calendar = window._dynarch_popupCalendar;
	if (!calendar) {
		return false;
	}
	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
	for (; el != null && el != calendar.element; el = el.parentNode);
	if (el == null) {
		// calls closeHandler which should hide the calendar.
		window._dynarch_popupCalendar.callCloseHandler();
		return Calendar.stopEvent(ev);
	}
};

/** Shows the calendar. */
Calendar.prototype.show = function () {
	var rows = this.table.getElementsByTagName("tr");
	for (var i = rows.length; i > 0;) {
		var row = rows[--i];
		Calendar.removeClass(row, "rowhilite");
		var cells = row.getElementsByTagName("td");
		for (var j = cells.length; j > 0;) {
			var cell = cells[--j];
			Calendar.removeClass(cell, "hilite");
			Calendar.removeClass(cell, "active");
		}
	}
	this.element.style.display = "block";
	this.hidden = false;
	if (this.isPopup) {
		window._dynarch_popupCalendar = this;
		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.hideShowCovered();
};

/**
 *  Hides the calendar.  Also removes any "hilite" from the class of any TD
 *  element.
 */
Calendar.prototype.hide = function () {
	if (this.isPopup) {
		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.element.style.display = "none";
	this.hidden = true;
	this.hideShowCovered();
};

/**
 *  Shows the calendar at a given absolute position (beware that, depending on
 *  the calendar element style -- position property -- this might be relative
 *  to the parent's containing rectangle).
 */
Calendar.prototype.showAt = function (x, y) {
	var s = this.element.style;
	s.left = x + "px";
	s.top = y + "px";
	this.show();
};

/** Shows the calendar near a given element. */
Calendar.prototype.showAtElement = function (el, opts) {
	var self = this;
	var p = Calendar.getAbsolutePos(el);
	if (!opts || typeof opts != "string") {
		this.showAt(p.x, p.y + el.offsetHeight);
		return true;
	}
	function fixPosition(box) {
		if (box.x < 0)
			box.x = 0;
		if (box.y < 0)
			box.y = 0;
		var cp = document.createElement("div");
		var s = cp.style;
		s.position = "absolute";
		s.right = s.bottom = s.width = s.height = "0px";
		document.body.appendChild(cp);
		var br = Calendar.getAbsolutePos(cp);
		document.body.removeChild(cp);
		if (Calendar.is_ie) {
			br.y += document.body.scrollTop;
			br.x += document.body.scrollLeft;
		} else {
			br.y += window.scrollY;
			br.x += window.scrollX;
		}
		var tmp = box.x + box.width - br.x;
		if (tmp > 0) box.x -= tmp;
		tmp = box.y + box.height - br.y;
		if (tmp > 0) box.y -= tmp;
	};
	this.element.style.display = "block";
	Calendar.continuation_for_the_fucking_khtml_browser = function() {  //@Neyek says: jaja greate property name ,... khtml into konqueror is newbie ;)
		var w = self.element.offsetWidth;                           // overe here  i will modify something for the fucking on event callback
		var h = self.element.offsetHeight;                          // that's something that there is not on this jscalendar ......
		self.element.style.display = "none";
		var valign = opts.substr(0, 1);
		var halign = "l";
		if (opts.length > 1) {
			halign = opts.substr(1, 1);
		}
		// vertical alignment
		switch (valign) {
		    case "T": p.y -= h; break;
		    case "B": p.y += el.offsetHeight; break;
		    case "C": p.y += (el.offsetHeight - h) / 2; break;
		    case "t": p.y += el.offsetHeight - h; break;
		    case "b": break; // already there
		}
		// horizontal alignment
		switch (halign) {
		    case "L": p.x -= w; break;
		    case "R": p.x += el.offsetWidth; break;
		    case "C": p.x += (el.offsetWidth - w) / 2; break;
		    case "l": p.x += el.offsetWidth - w; break;
		    case "r": break; // already there
		}
		p.width = w;
		p.height = h + 40;
		self.monthsCombo.style.display = "none";
		fixPosition(p);
		self.showAt(p.x, p.y);
	};
	if (Calendar.is_khtml)
		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
	else
		Calendar.continuation_for_the_fucking_khtml_browser();
};

/** Customizes the date format. */
Calendar.prototype.setDateFormat = function (str) {
	this.dateFormat = str;
};

/** Customizes the tooltip date format. */
Calendar.prototype.setTtDateFormat = function (str) {
	this.ttDateFormat = str;
};

/**
 *  Tries to identify the date represented in a string.  If successful it also
 *  calls this.setDate which moves the calendar to the given date.
 */
Calendar.prototype.parseDate = function(str, fmt) {
	if (!fmt)
		fmt = this.dateFormat;
	this.setDate(Date.parseDate(str, fmt));
};

Calendar.prototype.hideShowCovered = function () {
	if (!Calendar.is_ie && !Calendar.is_opera)
		return;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				if (!Calendar.is_khtml)
					value = document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
				else
					value = '';
			} else if (obj.currentStyle) { // IE
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};

	var tags = new Array("applet", "iframe", "select");
	var el = this.element;

	var p = Calendar.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;

	for (var k = tags.length; k > 0; ) {
		var ar = document.getElementsByTagName(tags[--k]);
		var cc = null;

		for (var i = ar.length; i > 0;) {
			cc = ar[--i];

			p = Calendar.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;

			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
};

/** Internal function; it displays the bar with the names of the weekday. */
Calendar.prototype._displayWeekdays = function () {
	var fdow = this.firstDayOfWeek;
	var cell = this.firstdayname;
	var weekend = Calendar._TT["WEEKEND"];
	for (var i = 0; i < 7; ++i) {
		cell.className = "day name";
		var realday = (i + fdow) % 7;
		if (i) {
			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
			cell.navtype = 100;
			cell.calendar = this;
			cell.fdow = realday;
			Calendar._add_evs(cell);
		}
		if (weekend.indexOf(realday.toString()) != -1) {
			Calendar.addClass(cell, "weekend");
		}
		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
		cell = cell.nextSibling;
	}
};

/** Internal function.  Hides all combo boxes that might be displayed. */
Calendar.prototype._hideCombos = function () {
	this.monthsCombo.style.display = "none";
	this.yearsCombo.style.display = "none";
};

/** Internal function.  Starts dragging the element. */
Calendar.prototype._dragStart = function (ev) {
	if (this.dragging) {
		return;
	}
	this.dragging = true;
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posY = ev.clientY + window.scrollY;
		posX = ev.clientX + window.scrollX;
	}
	var st = this.element.style;
	this.xOffs = posX - parseInt(st.left);
	this.yOffs = posY - parseInt(st.top);
	with (Calendar) {
		addEvent(document, "mousemove", calDragIt);
		addEvent(document, "mouseup", calDragEnd);
	}
};

// BEGIN: DATE OBJECT PATCHES

/** Adds the number of days array to the Date object. */
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

/** Constants used for time computations */
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

Date.parseDate = function(str, fmt) {
	var today = new Date();
	var y = 0;
	var m = -1;
	var d = 0;
	var a = str.split(/\W+/);
	var b = fmt.match(/%./g);
	var i = 0, j = 0;
	var hr = 0;
	var min = 0;
	for (i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
			d = parseInt(a[i], 10);
			break;

		    case "%m":
			m = parseInt(a[i], 10) - 1;
			break;

		    case "%Y":
		    case "%y":
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
			break;

		    case "%b":
		    case "%B":
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
			}
			break;

		    case "%H":
		    case "%I":
		    case "%k":
		    case "%l":
			hr = parseInt(a[i], 10);
			break;

		    case "%P":
		    case "%p":
			if (/pm/i.test(a[i]) && hr < 12)
				hr += 12;
			else if (/am/i.test(a[i]) && hr >= 12)
				hr -= 12;
			break;

		    case "%M":
			min = parseInt(a[i], 10);
			break;
		}
	}
	if (isNaN(y)) y = today.getFullYear();
	if (isNaN(m)) m = today.getMonth();
	if (isNaN(d)) d = today.getDate();
	if (isNaN(hr)) hr = today.getHours();
	if (isNaN(min)) min = today.getMinutes();
	if (y != 0 && m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	y = 0; m = -1; d = 0;
	for (i = 0; i < a.length; ++i) {
		if (a[i].search(/[a-zA-Z]+/) != -1) {
			var t = -1;
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
			}
			if (t != -1) {
				if (m != -1) {
					d = m+1;
				}
				m = t;
			}
		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
			m = a[i]-1;
		} else if (parseInt(a[i], 10) > 31 && y == 0) {
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
		} else if (d == 0) {
			d = a[i];
		}
	}
	if (y == 0)
		y = today.getFullYear();
	if (m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	return today;
};

/** Returns the number of days in the current month */
Date.prototype.getMonthDays = function(month) {
	var year = this.getFullYear();
	if (typeof month == "undefined") {
		month = this.getMonth();
	}
	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
		return 29;
	} else {
		return Date._MD[month];
	}
};

/** Returns the number of day in the year. */
Date.prototype.getDayOfYear = function() {
	var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
	var time = now - then;
	return Math.floor(time / Date.DAY);
};

/** Returns the number of the week in year, as defined in ISO 8601. */
Date.prototype.getWeekNumber = function() {
	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var DoW = d.getDay();
	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
	var ms = d.valueOf(); // GMT
	d.setMonth(0);
	d.setDate(4); // Thu in Week 1
	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

/** Set only the year, month, date parts (keep existing time) */
Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};

/** Prints the date in a string according to the given format. */
Date.prototype.print = function (str) {
	var m = this.getMonth();
	var d = this.getDate();
	var y = this.getFullYear();
	var wn = this.getWeekNumber();
	var w = this.getDay();
	var s = {};
	var hr = this.getHours();
	var pm = (hr >= 12);
	var ir = (pm) ? (hr - 12) : hr;
	var dy = this.getDayOfYear();
	if (ir == 0)
		ir = 12;
	var min = this.getMinutes();
	var sec = this.getSeconds();
	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
	s["%A"] = Calendar._DN[w]; // full weekday name
	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
	s["%B"] = Calendar._MN[m]; // full month name
	// FIXME: %c : preferred date and time representation for the current locale
	s["%C"] = 1 + Math.floor(y / 100); // the century number
	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
	s["%e"] = d; // the day of the month (range 1 to 31)
	// FIXME: %D : american date style: %m/%d/%y
	// FIXME: %E, %F, %G, %g, %h (man strftime)
	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
	s["%n"] = "\n";		// a newline character
	s["%p"] = pm ? "PM" : "AM";
	s["%P"] = pm ? "pm" : "am";
	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
	// FIXME: %R : the time in 24-hour notation %H:%M
	s["%s"] = Math.floor(this.getTime() / 1000);
	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
	s["%t"] = "\t";		// a tab character
	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
	// FIXME: %x : preferred date representation for the current locale without the time
	// FIXME: %X : preferred time representation for the current locale without the date
	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
	s["%Y"] = y;		// year with the century
	s["%%"] = "%";		// a literal '%' character

	var re = /%./g;
	if (!Calendar.is_ie5 && !Calendar.is_khtml)
		return str.replace(re, function (par) { return s[par] || par; });

	var a = str.match(re);
	for (var i = 0; i < a.length; i++) {
		var tmp = s[a[i]];
		if (tmp) {
			re = new RegExp(a[i], 'g');
			str = str.replace(re, tmp);
		}
	}

	return str;
};

Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
Date.prototype.setFullYear = function(y) {
	var d = new Date(this);
	d.__msh_oldSetFullYear(y);
	if (d.getMonth() != this.getMonth())
		this.setDate(28);
	this.__msh_oldSetFullYear(y);
};

// END: DATE OBJECT PATCHES


// global object that remembers the calendar
window._dynarch_popupCalendar = null;



///////////////////////////////////////////HELPER////////////////////////////////////////////////
//<!-- helper script that uses the calendar -->

var oldLink = null;

// This function gets called when the end-user clicks on some date.
function selected(cal, date) {
  cal.sel.value = date; // just update the date in the input field.
  //if (cal.dateClicked && (cal.sel.id == "idx_1" || cal.sel.id == "idx_2")) this it was for close a same ids only
  if (cal.dateClicked){
    cal.callCloseHandler();

    /* This was added for neyek as Erik Amaru Ortiz <erik@colosa.com> */
    // This is the callback event on trigger.........
    // when the user clicks for to select a date,.. we need execute all posibles events from text widget
    throwCallbackifExists();  //erik's function
  }
}

// And this gets called when the end-user clicks on the _selected_ date,
// or clicks on the "Close" button.  It just hides the calendar without
// destroying it.
function closeHandler(cal) {
  cal.hide();                        // hide the calendar
//  cal.destroy();
  _dynarch_popupCalendar = null;
}



/******************************************************************************************************
*             This functionality was added absolutly by Erik Amaru Ortiz <erik@colosa.com>
*******************************************************************************************************
* This function shows the calendar under the element having the given id.
* It takes care of catching "mousedown" signals on document and hiding the
* calendar if the click was outside.
*******************************************************************************************************/

var startDate;
var endDate;
var jsc_current_id;

/********************************************************************************************************/

function showCalendar(id, format, showsTime, showsOtherMonths, startD, endD) {

	startDateStr = startD;
	endDateStr   = endD;
        jsc_current_id = id;


	var el = document.getElementById(id);
	if (_dynarch_popupCalendar != null) {
		// we already have some calendar created
		_dynarch_popupCalendar.hide();                 // so we hide it first.
	} else {
	// first-time call, create the calendar.
		var cal = new Calendar(1, null, selected, closeHandler);
		// uncomment the following line to hide the week numbers
		// cal.weekNumbers = false;
		if (typeof showsTime == "string") {
			cal.showsTime = false;
			cal.time24 = (showsTime == "24");
		}
		if (showsOtherMonths) {
			cal.showsOtherMonths = true;
		}
		_dynarch_popupCalendar = cal;                  // remember it in the global var
		cal.setRange(1900, 2070);        // min/max year allowed.

		// We want some dates to be disabled; see function isDisabled above

		//for intervar startDate and endDate

		cal.setDisabledHandler(isInIntervalStartEnd);


		cal.create();
	}
	_dynarch_popupCalendar.setDateFormat(format);    // set the specified date format
	_dynarch_popupCalendar.parseDate(el.value);      // try to parse the text in field
	_dynarch_popupCalendar.sel = el;                 // inform it what input field we use

	// the reference element that we pass to showAtElement is the button that
	// triggers the calendar.  In this example we align the calendar bottom-right
	// to the button.
	_dynarch_popupCalendar.showAtElement(el.nextSibling, "Br");        // show the calendar

	return false;
}

var MINUTE = 60 * 1000;
var HOUR = 60 * MINUTE;
var DAY = 24 * HOUR;
var WEEK = 7 * DAY;

// If this handler returns true then the "date" given as
// parameter will be disabled.  In this example we enable
// only days within a range of 10 days from the current
// date.
// You can use the functions date.getFullYear() -- returns the year
// as 4 digit number, date.getMonth() -- returns the month as 0..11,
// and date.getDate() -- returns the date of the month as 1..31, to
// make heavy calculations here.  However, beware that this function
// should be very fast, as it is called for each day in a month when
// the calendar is (re)constructed.
function isDisabled(date) {
  var today = new Date();
  return (Math.abs(date.getTime() - today.getTime()) / DAY) > 10;
}

/*
	By NEYEK As erik <erik@colosa.com> **
*/
function isInIntervalStartEnd(date) {

	aTmp = startDateStr.split('-');
	startDate = new Date(parseInt(aTmp[0], 10), parseInt(aTmp[1], 10)-1, parseInt(aTmp[2], 10) );

	aTmp = endDateStr.split('-');
	endDate = new Date(parseInt(aTmp[0], 10), parseInt(aTmp[1], 10)-1, parseInt(aTmp[2], 10) );

	var time1 = date - startDate;
	var time2 = endDate - date;
	var diff1 = Math.floor(time1 / Date.DAY) + 1;
	var diff2 = Math.floor(time2 / Date.DAY) + 1;

	if( diff1 > 0 && diff2 > 0 ) {
		return false;
	} else {
		return true;
	}
}

/*
	By NEYEK As erik <erik@colosa.com> **
*/
function isInIntervalBeforeAfter(date) {

	aTmp = startDateStr.split('-');
	startDate = new Date(parseInt(aTmp[0], 10), parseInt(aTmp[1], 10)-1, parseInt(aTmp[2], 10) );

	aTmp = endDateStr.split('-');
	endDate = new Date(parseInt(aTmp[0], 10), parseInt(aTmp[1], 10)-1, parseInt(aTmp[2], 10) );

	var time1 = date - startDate;
	var time2 = endDate - date;
	var diff1 = Math.floor(time1 / Date.DAY) + 1;
	var diff2 = Math.floor(time2 / Date.DAY) + 1;
	diff1 = diff1 / Date.HOUR;
	diff2 = diff2 / Date.HOUR;
        if(diff2  > 0){
            diff2 = diff2 *-1;
        }

	if( diff1 > 0 && diff2 > 0 ) {
		return false;
	} else {
		return true;
	}
}

function flatSelected(cal, date) {
  var el = document.getElementById("preview");
  el.innerHTML = date;
}

function showFlatCalendar() {
  var parent = document.getElementById("display");

  // construct a calendar giving only the "selected" handler.
  var cal = new Calendar(0, null, flatSelected);

  // hide week numbers
  cal.weekNumbers = false;

  // We want some dates to be disabled; see function isDisabled above
  cal.setDisabledHandler(isDisabled);
  cal.setDateFormat("%A, %B %e");

  // this call must be the last as it might use data initialized above; if
  // we specify a parent, as opposite to the "showCalendar" function above,
  // then we create a flat calendar -- not popup.  Hidden, though, but...
  cal.create(parent);

  // ... we can show it here.
  cal.show();
}

function throwCallbackifExists(){
  if(document.getElementById(jsc_current_id).onchange != null){
      x = document.getElementById(jsc_current_id).onchange;
      setTimeout(x, 10);

  }
}
/**
 *  author:		Timothy Groves - http://www.brandspankingnew.net
 *	version:	1.2 - 2006-11-17
 *              1.3 - 2006-12-04
 *              2.0 - 2007-02-07
 *              2.1.1 - 2007-04-13
 *              2.1.2 - 2007-07-07
 *              2.1.3 - 2007-07-19
 *
 */


if (typeof(bsn) == "undefined")
	_b = bsn = {};


if (typeof(_b.Autosuggest) == "undefined")
	_b.Autosuggest = {};
else
	alert("Autosuggest is already set!");

_b.AutoSuggest = function (id, param)
{
	// no DOM - give up!
	//
	if (!document.getElementById)
		return 0;
	
	// get field via DOM
	//
	this.fld = _b.DOM.gE(id);

	if (!this.fld)
		return 0;

	// init variables
	//
	this.sInp 	= "";
	this.nInpC 	= 0;
	this.aSug 	= [];
	this.iHigh 	= 0;
	
	// parameters object
	//
	this.oP = param ? param : {};
	
	// defaults	
	//
	var k, def = {minchars:1, meth:"get", varname:"input", className:"autosuggest", timeout:5000, delay:50, offsety:-5, shownoresults: true, noresults: "No results!", maxheight: 250, cache: true, maxentries: 25};
                                                                                      //timeout::2500      //delay was modified of 5000 or 500 by 5, I don't sure.. ;) can't remember... <-erik notes->'
	for (k in def)
	{
		if (typeof(this.oP[k]) != typeof(def[k]))
			this.oP[k] = def[k];
	}
	
	// set keyup handler for field
	// and prevent autocomplete from client
	//
	var p = this;
	
	// NOTE: not using addEventListener because UpArrow fired twice in Safari
	//_b.DOM.addEvent( this.fld, 'keyup', function(ev){ return pointer.onKeyPress(ev); } );
	
	this.fld.onkeypress 	= function(ev){ return p.onKeyPress(ev); };
	this.fld.onkeyup 		= function(ev){ return p.onKeyUp(ev); };
	
	this.fld.setAttribute("autocomplete","off");
};


_b.AutoSuggest.prototype.onKeyPress = function(ev)
{
	
	var key = (window.event) ? window.event.keyCode : ev.keyCode;

	var RETURN = 13;
	var TAB = 9;
	var ESC = 27;
	
	var bubble = 1;

	switch(key)
	{
		case RETURN:
			this.setHighlightedValue();
			bubble = 0;
			break;

		case ESC:
			this.clearSuggestions();
			break;
	}

	return bubble;
};



_b.AutoSuggest.prototype.onKeyUp = function(ev)
{
	var key = (window.event) ? window.event.keyCode : ev.keyCode;

	var ARRUP = 38;
	var ARRDN = 40;
	
	var bubble = 1;

	switch(key)
	{
		case ARRUP:
			this.changeHighlight(key);
                        this.setHighlightedValue2();
			bubble = 0;
			break;


		case ARRDN:
			this.changeHighlight(key);
                        this.setHighlightedValue2();
			bubble = 0;
			break;
		
		
		default:
			this.getSuggestions(this.fld.value);
	}

	return bubble;
	
};








_b.AutoSuggest.prototype.getSuggestions = function (val)
{
	
	// if input stays the same, do nothing
	//
	if (val == this.sInp)
		return 0;
	
	// kill list
	//
	_b.DOM.remE(this.idAs);
	
	
	this.sInp = val;
	
	// input length is less than the min required to trigger a request
	// do nothing
	//
	if (val.length < this.oP.minchars)
	{
		this.aSug = [];
		this.nInpC = val.length;
		return 0;
	}
	
	var ol = this.nInpC; // old length
	this.nInpC = val.length ? val.length : 0;

	// if caching enabled, and user is typing (ie. length of input is increasing)
	// filter results out of aSuggestions from last request
	//
	var l = this.aSug.length;
	if (this.nInpC > ol && l && l<this.oP.maxentries && this.oP.cache)
	{
		var arr = [];
		for (var i=0;i<l;i++)
		{
			if (this.aSug[i].value.substr(0,val.length).toLowerCase() == val.toLowerCase())
				arr.push( this.aSug[i] );
		}
		this.aSug = arr;
		
		this.createList(this.aSug);
		return false;
	}
	else
	// do new request
	//
	{
		var pointer = this;
		var input = this.sInp;
		clearTimeout(this.ajID);
		this.ajID = setTimeout( function() { pointer.doAjaxRequest(input) }, this.oP.delay );
	}

	return false;
};





_b.AutoSuggest.prototype.doAjaxRequest = function (input)
{
	// check that saved input is still the value of the field
	//
	if (input != this.fld.value)
		return false;

	var pointer = this;

	// create ajax request
	//
	if (typeof(this.oP.script) == "function")
		var url = this.oP.script(encodeURIComponent(this.sInp));
	else
		var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp);
	
	if (!url)
		return false;
	
	var meth = this.oP.meth;
	var input = this.sInp;
	
	var onSuccessFunc = function (req) { pointer.setSuggestions(req, input) };
	var onErrorFunc = function (status) { alert("AJAX error: "+status); };

	var myAjax = new _b.Ajax();
	myAjax.makeRequest( url, meth, onSuccessFunc, onErrorFunc );
};

_b.AutoSuggest.prototype.setSuggestions = function (req, input)
{
	// if field input no longer matches what was passed to the request
	// don't show the suggestions
	//
	if (input != this.fld.value)
		return false;

	this.aSug = [];
	
	
	if (this.oP.json)
	{
		var jsondata = eval('(' + req.responseText + ')');
		
		for (var i=0;i<jsondata.results.length;i++)
		{
			this.aSug.push(  { 'id':jsondata.results[i].id, 'value':jsondata.results[i].value, 'info':jsondata.results[i].info }  );
		}
	}
	else
	{

		var xml = req.responseXML;
	
		// traverse xml
		//
		var results = xml.getElementsByTagName('results')[0].childNodes;

		for (var i=0;i<results.length;i++)
		{
			if (results[i].hasChildNodes())
				this.aSug.push(  { 'id':results[i].getAttribute('id'), 'value':results[i].childNodes[0].nodeValue, 'info':results[i].getAttribute('info') }  );
		}
	
	}
	
	this.idAs = "as_"+this.fld.id;
	

	this.createList(this.aSug);

};

_b.AutoSuggest.prototype.createList = function(arr)
{
	var pointer = this;

	_b.DOM.remE(this.idAs);
	this.killTimeout();
	
	
	// if no results, and shownoresults is false, do nothing
	//
	if (arr.length == 0 && !this.oP.shownoresults)
		return false;

	// create holding div
	//
	var div = _b.DOM.cE("div", {id:this.idAs, className:this.oP.className});	
	
	var hcorner = _b.DOM.cE("div", {className:"as_corner"});
	var hbar = _b.DOM.cE("div", {className:"as_bar"});
	var header = _b.DOM.cE("div", {className:"as_header"});
	header.appendChild(hcorner);
	header.appendChild(hbar);
	div.appendChild(header);
	
	// create and populate ul
	//
	var ul = _b.DOM.cE("ul", {id:"as_ul"});

	// loop throught arr of suggestions
	// creating an LI element for each suggestion
	//
	for (var i=0;i<arr.length;i++)
	{
		// format output with the input enclosed in a EM element
		// (as HTML, not DOM)
		//
		var val = arr[i].value;
		var st = val.toLowerCase().indexOf( this.sInp.toLowerCase() );
		var output = val.substring(0,st) + "<em>" + val.substring(st, st+this.sInp.length) + "</em>" + val.substring(st+this.sInp.length);
		
		
		var span 		= _b.DOM.cE("span", {}, output, true);
		if (arr[i].info != "")
		{
			var br			= _b.DOM.cE("br", {});
			span.appendChild(br);
			var small		= _b.DOM.cE("small", {}, arr[i].info);
			span.appendChild(small);
		}
		
		var a 			= _b.DOM.cE("a", { href:"#" });
		
		var tl 		= _b.DOM.cE("span", {className:"tl"}, " ");
		var tr 		= _b.DOM.cE("span", {className:"tr"}, " ");
		a.appendChild(tl);
		a.appendChild(tr);
		
		a.appendChild(span);
		
		a.name = i+1;
		a.onclick = function () { pointer.setHighlightedValue(); return false; };
		a.onmouseover = function () { 
                     pointer.setHighlight(this.name); 
                     pointer.setHighlightedValue2();
                     
                };
		
		var li = _b.DOM.cE(  "li", {}, a  );
		
		ul.appendChild( li );
	}
	
	
	// no results
	//
	if (arr.length == 0 && this.oP.shownoresults)
	{
		var li = _b.DOM.cE(  "li", {className:"as_warning"}, this.oP.noresults  );
		ul.appendChild( li );
	}
	
	
	div.appendChild( ul );
	
	
	var fcorner = _b.DOM.cE("div", {className:"as_corner"});
	var fbar = _b.DOM.cE("div", {className:"as_bar"});
	var footer = _b.DOM.cE("div", {className:"as_footer"});
	footer.appendChild(fcorner);
	footer.appendChild(fbar);
	div.appendChild(footer);

	// get position of target textfield
	// position holding div below it
	// set width of holding div to width of field
	//
	var pos = _b.DOM.getPos(this.fld);
	
	div.style.left 		= pos.x + "px";
	div.style.top 		= ( pos.y + this.fld.offsetHeight + this.oP.offsety ) + "px";
	div.style.width 	= this.fld.offsetWidth + "px";

	// set mouseover functions for div
	// when mouse pointer leaves div, set a timeout to remove the list after an interval
	// when mouse enters div, kill the timeout so the list won't be removed
	//
	div.onmouseover 	= function(){ pointer.killTimeout() };
	div.onmouseout 		= function(){ pointer.resetTimeout() };

	// add DIV to document
	//
	document.getElementsByTagName("body")[0].appendChild(div);

	// currently no item is highlighted
	//
	this.iHigh = 0;
	
	// remove list after an interval
	//
	var pointer = this;
	this.toID = setTimeout(function () { pointer.clearSuggestions() }, this.oP.timeout);
};

_b.AutoSuggest.prototype.changeHighlight = function(key)
{	
	var list = _b.DOM.gE("as_ul");
	if (!list)
		return false;
	
	var n;

	if (key == 40)
		n = this.iHigh + 1;
	else if (key == 38)
		n = this.iHigh - 1;
	
	
	if (n > list.childNodes.length)
		n = list.childNodes.length;
	if (n < 1)
		n = 1;
	
	
	this.setHighlight(n);
};

_b.AutoSuggest.prototype.setHighlight = function(n)
{
	var list = _b.DOM.gE("as_ul");
	if (!list)
		return false;
	
	if (this.iHigh > 0)
		this.clearHighlight();
	
	this.iHigh = Number(n);
	
	list.childNodes[this.iHigh-1].className = "as_highlight";


	this.killTimeout();
};

_b.AutoSuggest.prototype.clearHighlight = function()
{
	var list = _b.DOM.gE("as_ul");
	if (!list)
		return false;
	
	if (this.iHigh > 0)
	{
		list.childNodes[this.iHigh-1].className = "";
		this.iHigh = 0;
	}
};


_b.AutoSuggest.prototype.setHighlightedValue = function ()
{
	if (this.iHigh)
	{
		this.sInp = this.fld.value = this.aSug[ this.iHigh-1 ].value;
		
		// move cursor to end of input (safari)
		//
		this.fld.focus();
		if (this.fld.selectionStart)
			this.fld.setSelectionRange(this.sInp.length, this.sInp.length);
		

		this.clearSuggestions();
		
		// pass selected object to callback function, if exists
		//
		if (typeof(this.oP.callback) == "function")
			this.oP.callback( this.aSug[this.iHigh-1] );
	}
};

_b.AutoSuggest.prototype.setHighlightedValue2 = function ()
{
	if (this.iHigh)
	{
		this.sInp = this.fld.value = this.aSug[ this.iHigh-1 ].value;
		
		// move cursor to end of input (safari)
		//
		/*this.fld.focus();
		if (this.fld.selectionStart)
			this.fld.setSelectionRange(this.sInp.length, this.sInp.length);
		
                        */
		//this.clearSuggestions();
		
		// pass selected object to callback function, if exists
		//
		/*if (typeof(this.oP.callback) == "function")
			this.oP.callback( this.aSug[this.iHigh-1] );*/
	}
};

_b.AutoSuggest.prototype.killTimeout = function()
{
	clearTimeout(this.toID);
};

_b.AutoSuggest.prototype.resetTimeout = function()
{
	clearTimeout(this.toID);
	var pointer = this;
	this.toID = setTimeout(function () { pointer.clearSuggestions() }, 10);  // was modifiend,.. its original value was 1000 by 10  <-erik notes->
};

_b.AutoSuggest.prototype.clearSuggestions = function ()
{
	
	this.killTimeout();
	
	var ele = _b.DOM.gE(this.idAs);
	var pointer = this;
	if (ele)
	{
		var fade = new _b.Fader(ele,1,0,250,function () { _b.DOM.remE(pointer.idAs) });
	}
};

// AJAX PROTOTYPE _____________________________________________


if (typeof(_b.Ajax) == "undefined")
	_b.Ajax = {};

_b.Ajax = function ()
{
	this.req = {};
	this.isIE = false;
};

_b.Ajax.prototype.makeRequest = function (url, meth, onComp, onErr)
{
	
	if (meth != "POST")
		meth = "GET";
	
	this.onComplete = onComp;
	this.onError = onErr;
	
	var pointer = this;
	
	// branch for native XMLHttpRequest object
	if (window.XMLHttpRequest)
	{
		this.req = new XMLHttpRequest();
		this.req.onreadystatechange = function () { pointer.processReqChange() };
		this.req.open("GET", url, true); //
		this.req.send(null);
	// branch for IE/Windows ActiveX version
	}
	else if (window.ActiveXObject)
	{
		this.req = new ActiveXObject("Microsoft.XMLHTTP");
		if (this.req)
		{
			this.req.onreadystatechange = function () { pointer.processReqChange() };
			this.req.open(meth, url, true);
			this.req.send();
		}
	}
};

_b.Ajax.prototype.processReqChange = function()
{
	
	// only if req shows "loaded"
	if (this.req.readyState == 4) {
		// only if "OK"
		if (this.req.status == 200)
		{
			this.onComplete( this.req );
		} else {
			this.onError( this.req.status );
		}
	}
};

// DOM PROTOTYPE _____________________________________________

if (typeof(_b.DOM) == "undefined")
	_b.DOM = {};

/* create element */
_b.DOM.cE = function ( type, attr, cont, html )
{
	var ne = document.createElement( type );
	if (!ne)
		return 0;
		
	for (var a in attr)
		ne[a] = attr[a];
	
	var t = typeof(cont);
	
	if (t == "string" && !html)
		ne.appendChild( document.createTextNode(cont) );
	else if (t == "string" && html)
		ne.innerHTML = cont;
	else if (t == "object")
		ne.appendChild( cont );

	return ne;
};

/* get element */
_b.DOM.gE = function ( e )
{
	var t=typeof(e);
	if (t == "undefined")
		return 0;
	else if (t == "string")
	{
		var re = document.getElementById( e );
		if (!re)
			return 0;
		else if (typeof(re.appendChild) != "undefined" )
			return re;
		else
			return 0;
	}
	else if (typeof(e.appendChild) != "undefined")
		return e;
	else
		return 0;
};

/* remove element */
_b.DOM.remE = function ( ele )
{
	var e = this.gE(ele);
	
	if (!e)
		return 0;
	else if (e.parentNode.removeChild(e))
		return true;
	else
		return 0;
};

/* get position */
_b.DOM.getPos = function ( e )
{
	var e = this.gE(e);

	var obj = e;

	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	
	var obj = e;
	
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;

	return {x:curleft, y:curtop};
};

// FADER PROTOTYPE _____________________________________________

if (typeof(_b.Fader) == "undefined")
	_b.Fader = {};

_b.Fader = function (ele, from, to, fadetime, callback)
{	
	if (!ele)
		return 0;
	
	this.e = ele;
	
	this.from = from;
	this.to = to;
	
	this.cb = callback;
	
	this.nDur = fadetime;
		
	this.nInt = 50;
	this.nTime = 0;
	
	var p = this;
	this.nID = setInterval(function() { p._fade() }, this.nInt);
};

_b.Fader.prototype._fade = function()
{
	this.nTime += this.nInt;
	
	var ieop = Math.round( this._tween(this.nTime, this.from, this.to, this.nDur) * 100 );
	var op = ieop / 100;
	
	if (this.e.filters) // internet explorer
	{
		try
		{
			this.e.filters.item("DXImageTransform.Microsoft.Alpha").opacity = ieop;
		} catch (e) { 
			// If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
			this.e.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+ieop+')';
		}
	}
	else // other browsers
	{
		this.e.style.opacity = op;
	}
	
	
	if (this.nTime == this.nDur)
	{
		clearInterval( this.nID );
		if (this.cb != undefined)
			this.cb();
	}
};

_b.Fader.prototype._tween = function(t,b,c,d)
{
	return b + ( (c-b) * (t/d) );
};/*
 * PM tooltip
 * 
 * @Adapted by Erik Amaru Ortiz <erik@colosa.com>
 * 
 * */

    var pmtooltip = false;
	var pmtooltipShadow = false;
	var pmshadowSize = 4;
	var pmtooltipMaxWidth = 400;
	var pmtooltipMinWidth = 100;
	var pmiframe = false;
	var tooltip_is_msie = (navigator.userAgent.indexOf('MSIE')>=0 && navigator.userAgent.indexOf('opera')==-1 && document.all)?true:false;
	
	function showTooltip(e,tooltipTxt){
		var bodyWidth = Math.max(document.body.clientWidth,document.documentElement.clientWidth) - 20;

		if(!pmtooltip){
			pmtooltip = document.createElement('DIV');
			pmtooltip.id = 'pmtooltip';
			pmtooltipShadow = document.createElement('DIV');
			pmtooltipShadow.id = 'pmtooltipShadow';

			document.body.appendChild(pmtooltip);
			document.body.appendChild(pmtooltipShadow);

			if(tooltip_is_msie){
				pmiframe = document.createElement('IFRAME');
				pmiframe.frameborder='5';
				pmiframe.style.backgroundColor='#FFFFFF';
				pmiframe.src = '#';
				pmiframe.style.zIndex = 100;
				pmiframe.style.position = 'absolute';
				document.body.appendChild(pmiframe);
			}

		}

		pmtooltip.style.display='block';
		pmtooltipShadow.style.display='block';
		if(tooltip_is_msie)pmiframe.style.display='block';

		var st = Math.max(document.body.scrollTop,document.documentElement.scrollTop);
		if(navigator.userAgent.toLowerCase().indexOf('safari')>=0)st=0;
		var leftPos = e.clientX + 10;

		pmtooltip.style.width = null;	// Reset style width if it's set
		pmtooltip.innerHTML = tooltipTxt;
		pmtooltip.style.left = leftPos +10 + 'px';
		pmtooltip.style.top = e.clientY + 10 + st + 'px';

		pmtooltipShadow.style.left =  leftPos + pmshadowSize + 'px';
		pmtooltipShadow.style.top = e.clientY + 10 + st + pmshadowSize + 'px';

		if(pmtooltip.offsetWidth>pmtooltipMaxWidth){	/* Exceeding max width of tooltip ? */
			pmtooltip.style.width = pmtooltipMaxWidth + 'px';
		}

		var tooltipWidth = pmtooltip.offsetWidth;
		if(tooltipWidth<pmtooltipMinWidth)tooltipWidth = pmtooltipMinWidth;


		pmtooltip.style.width = tooltipWidth + 'px';
		pmtooltipShadow.style.width = pmtooltip.offsetWidth + 'px';
		pmtooltipShadow.style.height = pmtooltip.offsetHeight + 'px';

		if((leftPos + tooltipWidth)>bodyWidth){
			pmtooltip.style.left = (pmtooltipShadow.style.left.replace('px','') - ((leftPos + tooltipWidth)-bodyWidth)) + 'px';
			pmtooltipShadow.style.left = (pmtooltipShadow.style.left.replace('px','') - ((leftPos + tooltipWidth)-bodyWidth) + pmshadowSize) + 'px';
		}

		if(tooltip_is_msie){
			pmiframe.style.left = pmtooltip.style.left;
			pmiframe.style.top = pmtooltip.style.top;
			pmiframe.style.width = pmtooltip.offsetWidth + 'px';
			pmiframe.style.height = pmtooltip.offsetHeight + 'px';

		}

	}

	function hideTooltip(){
		pmtooltip.style.display='none';
		pmtooltipShadow.style.display='none';
		if(tooltip_is_msie)pmiframe.style.display='none';
	}
	
	/** JavaScript routines for Krumo
* @version $Id: krumo.js 22 2007-12-02 07:38:18Z Mrasnika $
* @link http://sourceforge.net/projects/krumo
*/

function krumo() {}
krumo.reclass = function(el, className) {
	if (el.className.indexOf(className) < 0) {
		el.className += (' ' + className);
	}
}
krumo.unclass = function(el, className) {
	if (el.className.indexOf(className) > -1) {
		el.className = el.className.replace(className, '');
	}
}
krumo.toggle = function(el) {
	var ul = el.parentNode.getElementsByTagName('ul');
	for (var i=0; i<ul.length; i++) {
		if (ul[i].parentNode.parentNode == el.parentNode) {
			ul[i].parentNode.style.display = (ul[i].parentNode.style.display == 'none')
				? 'block'
				: 'none';
		}
}
if (ul[0].parentNode.style.display == 'block') {
		krumo.reclass(el, 'krumo-opened');
		} else {
		krumo.unclass(el, 'krumo-opened');
		}
}
krumo.over = function(el) {
	krumo.reclass(el, 'krumo-hover');
}
krumo.out = function(el) {
	krumo.unclass(el, 'krumo-hover');
}

