	//[ EI Base Class v20090221
	//[ Copyright (c) 2002-09 Extiris, All rights reserved.
	//[ Extiris - Success by design.
	
	var Cookie =
	{
		set: function(name, value, daysToExpire)
		{
			var expire = '';

			if (daysToExpire != undefined)
			{
				var d = new Date();

				d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));

				expire = '; Path=/; Expires=' + d.toGMTString();
			}

			return (document.cookie = escape(name) + '=' + escape(value || '') + expire);
		},
		get: function(name)
		{
			//var cookie = document.cookie.match(new RegExp('(^|;)\s*' + escape(name) + '=([^;\s]*)'));
			var cookie = document.cookie.match ( '(^|;) ?' + escape(name) + '=([^;]*)(;|$)' );

			return (cookie ? unescape(cookie[2]) : null);
		},
		unset: function(name)
		{
			var cookie = Cookie.get(name) || true;

			Cookie.set(name, '', -1);

			return cookie;
		},
		accept: function()
		{
			if (typeof navigator.cookieEnabled == 'boolean')
				return navigator.cookieEnabled;

			Cookie.set('can_accept', '1');

			return (Cookie.unset('can_accept') === '1');
		}
	};	
	
	/**
	* Base64 encode / decode  http://www.webtoolkit.info/
	**/
	var Base64 = {

	    // private property
	    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	    // public method for encoding
	    encode : function (input) {
	        var output = "";
	        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
	        var i = 0;

	        input = Base64._utf8_encode(input);

	        while (i < input.length) {

	            chr1 = input.charCodeAt(i++);
	            chr2 = input.charCodeAt(i++);
	            chr3 = input.charCodeAt(i++);

	            enc1 = chr1 >> 2;
	            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
	            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
	            enc4 = chr3 & 63;

	            if (isNaN(chr2)) {
	                enc3 = enc4 = 64;
	            } else if (isNaN(chr3)) {
	                enc4 = 64;
	            }

	            output = output +
	            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
	            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

	        }

	        return output;
	    },

	    // public method for decoding
	    decode : function (input) {
	        var output = "";
	        var chr1, chr2, chr3;
	        var enc1, enc2, enc3, enc4;
	        var i = 0;

	        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

	        while (i < input.length) {

	            enc1 = this._keyStr.indexOf(input.charAt(i++));
	            enc2 = this._keyStr.indexOf(input.charAt(i++));
	            enc3 = this._keyStr.indexOf(input.charAt(i++));
	            enc4 = this._keyStr.indexOf(input.charAt(i++));

	            chr1 = (enc1 << 2) | (enc2 >> 4);
	            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
	            chr3 = ((enc3 & 3) << 6) | enc4;

	            output = output + String.fromCharCode(chr1);

	            if (enc3 != 64) {
	                output = output + String.fromCharCode(chr2);
	            }
	            if (enc4 != 64) {
	                output = output + String.fromCharCode(chr3);
	            }

	        }

	        output = Base64._utf8_decode(output);

	        return output;

	    },

	    // private method for UTF-8 encoding
	    _utf8_encode : function (string) {
	        string = string.replace(/\r\n/g,"\n");
	        var utftext = "";

	        for (var n = 0; n < string.length; n++) {

	            var c = string.charCodeAt(n);

	            if (c < 128) {
	                utftext += String.fromCharCode(c);
	            }
	            else if((c > 127) && (c < 2048)) {
	                utftext += String.fromCharCode((c >> 6) | 192);
	                utftext += String.fromCharCode((c & 63) | 128);
	            }
	            else {
	                utftext += String.fromCharCode((c >> 12) | 224);
	                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
	                utftext += String.fromCharCode((c & 63) | 128);
	            }

	        }

	        return utftext;
	    },

	    // private method for UTF-8 decoding
	    _utf8_decode : function (utftext) {
	        var string = "";
	        var i = 0;
	        var c = c1 = c2 = 0;

	        while ( i < utftext.length ) {

	            c = utftext.charCodeAt(i);

	            if (c < 128) {
	                string += String.fromCharCode(c);
	                i++;
	            }
	            else if((c > 191) && (c < 224)) {
	                c2 = utftext.charCodeAt(i+1);
	                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
	                i += 2;
	            }
	            else {
	                c2 = utftext.charCodeAt(i+1);
	                c3 = utftext.charCodeAt(i+2);
	                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
	                i += 3;
	            }

	        }

	        return string;
	    }

	};
		
	function InnerHTML(_1,_2,_3){function Load(_4){var _5;if(typeof DOMParser!="undefined"){_5=(new DOMParser()).parseFromString(_4,"application/xml");}else{var _6=["MSXML2.DOMDocument","MSXML.DOMDocument","Microsoft.XMLDOM"];for(var i=0;i<_6.length&&!_5;i++){try{_5=new ActiveXObject(_6[i]);_5.loadXML(_4);}catch(e){}}}return _5;}function Copy(_8,_9,_a){if(typeof _a=="undefined"){_a=1;}if(_a>1){if(_9.nodeType==1){var _b=document.createElement(_9.nodeName);for(var a=0,attr=_9.attributes.length;a<attr;a++){var _d=_9.attributes[a].name,aValue=_9.attributes[a].value,evt=(_d.substr(0,2)=="on");if(!evt){switch(_d){case "class":_b.className=aValue;break;case "for":_b.htmlFor=aValue;break;default:_b.setAttribute(_d,aValue);}}}_8=_8.appendChild(_b);if(evt){_8[_d]=function(){eval(aValue);};}}else{if(_9.nodeType==3){var _e=(_9.nodeValue?_9.nodeValue:"");var _f=_e.replace(/^\s*|\s*$/g,"");if(_f.length<7||(_f.indexOf("<!--")!=0&&_f.indexOf("-->")!=(_f.length-3))){_8.appendChild(document.createTextNode(_e));}}}}for(var i=0,j=_9.childNodes.length;i<j;i++){Copy(_8,_9.childNodes[i],_a+1);}}_2="<root>"+_2+"</root>";var _11=Load(_2);if(_1&&_11){if(_3!=false){while(_1.lastChild){_1.removeChild(_1.lastChild);}}Copy(_1,_11.documentElement);}}
	
	var HtmlTable = Class.create();
	HtmlTable.prototype =
	{
		table_id: '',
		class_off: '',
		class_on: '',
		
		//////////////////////////////////////////////////	
		initialize: function(table_id, class_off, class_on)
		{
			this.table_id = (table_id != undefined) ? table_id : '';
			
			this.class_off = (class_off != undefined) ? class_off : 'resultrowoff';
			this.class_on = (class_on != undefined) ? class_on : 'resultrowon';
		},
		//////////////////////////////////////////////////
		//USAGE: table.AddRowRaw('<tr><td colspan="5">#{name}</td></tr>', {name: 'ABC'} );	
		AddRow: function(html, params)
		{
			var table = document.getElementById(this.table_id);
			var thead = table.getElementsByTagName('thead');
			var tbody = table.getElementsByTagName('tbody');
			
			if( tbody )
			{
				params = ( params != undefined ) ? params : {};
				
				var row = new Template(html).evaluate(params);	
				
				try
				{
					tbody[0].insert(row);	
				}
				catch(e)
				{
					//---[ IE7 ]---
					var tr    = document.createElement('tr');
					var tr_id = '_tr_row_' + tbody[0].childNodes.length;
					
					tr.id = tr_id;
					
					tbody[0].appendChild(tr);
				
					InnerHTML( $(tr_id), row);
				}
			}
			else
			{
				//[ missing tbody
				alert('HtmlTable.AddRow: Missing tbody');
			}
		},
		//////////////////////////////////////////////////
		//
		AddRowCells: function()
		{
			var table 	= document.getElementById(this.table_id);
			var newRow 	= table.insertRow(table.rows.length);
			var newCell;
	
			for( nCell=0; nCell < arguments.length;nCell++)
			{
				var sClass = this.class_on;
	
				if( table.rows.length % 2 == 0 )
					sClass = this.class_off;
	
				newCell = newRow.insertCell(nCell -1);
				newCell.className = sClass;
				newCell.innerHTML = arguments[nCell];
			}
		},
		//////////////////////////////////////////////////
		GetRowCount: function()
		{
			var table = document.getElementById(this.table_id);
			var tbody = table.getElementsByTagName('tbody');
			
			if( tbody )
			{
				return tbody[0].childNodes.length;
			}
			else
			{
				alert('Missing TBODY');
			}			
			
			
			return 0;
		},
		//////////////////////////////////////////////////
		RemoveRow: function(row)
		{
			var table = document.getElementById(this.table_id);
			
			table.deleteRow(row);
		},
		//////////////////////////////////////////////////
		//
		Clear: function(count)
		{
			if( this.GetRowCount() > 0 )
				this.Trim( this.GetRowCount() -1 );
		},
		//////////////////////////////////////////////////
		Trim: function(trim_by)
		{
			trim_by  = (trim_by != undefined && trim_by > 0 ) ? trim_by : 1;
			
			var table = document.getElementById(this.table_id);
			var tbody = table.getElementsByTagName('tbody');
			
			if( tbody )
			{
				var start = this.GetRowCount() -1;
				var stop  = start - trim_by;
			
				//alert('trim by: ' + trim_by + '\nstart: ' + start + '\nstop: ' +  stop);	
			
				if( Prototype.Browser.IE )
				{
					//[ IE7 remove rows
					for( nRow = start; nRow > stop; nRow-- )
					{
						tbody[0].removeChild( tbody[0].childNodes[nRow] );
					}	
				}
				else
				{
					for( nRow = start; nRow > stop; nRow-- )
					{
						tbody[0].deleteRow(nRow);
					}	
				}				
			}
			else
			{
				//[ missing tbody
				alert('HtmlTable.AddRow: Missing tbody');
			}
		}
	};
	
	
	var FormValidation = Class.create();
	FormValidation.prototype =
	{
		form_id: '',
		fields: '',
		required_class: 'mandatoryfield',
		error_class: 'errorfield',
		validate_event: null,
		trace_id: 'trace',
		enable_trace: false,
			
		initialize: function(form_id, fields, validate_event)
		{
			this.form_id = (form_id != undefined) ? form_id : this.form_id;
			this.fields = (fields != undefined) ? fields : this.fields;
			this.validate_event = (validate_event != undefined) ? validate_event : this.validate_event;
		},
		
		//////////////////////////////////////////////////
		Validate: function()
		{
			//this.Log('Validate');
			
			var fields = this.fields.split(",");
			var field_errors = 0;
		
			for(c=0; c < fields.length; c++)
			{
				var field_name = fields[c];
			
				if( $(field_name).hasClassName(this.required_class) )
				{
					if( $(field_name).value.blank() )
					{
						Element.addClassName(field_name, this.error_class);
						
						field_errors++;
					}
					else
					{
						Element.removeClassName(field_name, this.error_class);	
					}
				}
			}
			
			//this.Log('Before Validate Event');
			
			if( this.validate_event != null )
				field_errors += this.validate_event();
			
			if( field_errors == 0 )
				return true;
			else 
				return false;
		},
		Trace: function(msg)
		{
			if( this.enable_trace && $(this.trace_id) )
				$(this.trace_id).innerHTML += msg + '<br/>';
		}
	};	

	var SoapClient = Class.create();
	SoapClient.prototype =
	{
		wsdl: '',
		proxy: '',
		params: null,
		asynchronous: false,
		method: 'post',
				
		initialize: function(wsdl, proxy)
		{
			this.Reset();
			
			this.wsdl 	= wsdl;
			this.proxy 	= (proxy != null) ? proxy : '/ws/';
		}, 
		Reset: function()
		{
			this.wsdl = "";
			this.proxy = "";
			this.asynchronous = false;
			this.method = "post";
			this.params = new Hash();			
		},
		Call: function(soap_call, params)
		{
			var p = this.params;
		
			if( params )
			{
				var o = "p = new Hash({";
	
				for( key in params )
				{
					if( !Object.isFunction(params[key]) )
						o += key + ":'" + params[key] + "',";
				}
	
				//---[ strip last comma ]---
				eval(o.substring(0, o.length -1) + "});");
			}
			else
			{
				p = this.params;
			}

			//---[ add call to stack parsed by ws proxy ]---
			p.set('call', soap_call);
			p.set('wsdl', this.wsdl);
			
			/**/
			var results = null;
			
			new Ajax.Request(this.proxy,
			{
				method: this.method,
				asynchronous: this.asynchronous,
				parameters: p.toQueryString(),
				onSuccess: function(transport, json)
				{
					var response = transport.responseText || "";
					
					
					
					results = transport.responseText.evalJSON(true);
					
					//alert('soap response: ' + json);
					
					//results = (json) ? json : response;
				},
				onFailure: function(){ alert('Something went wrong...') }
			});
	
			return results;	
			/**/		
		},
		AddParam: function(name, value)
		{
			this.params.set(name, value);
		}, 
		serialize: function()
		{
			/**/
			var o = "var p = new Hash({";

			for( property in this )
			{
				if( !Object.isFunction(eval("this." + property)) )
					o += property + ":" + eval("Object.toJSON(this." + property + ");") + ",";
			}

			//---[ strip last comma ]---
			eval(o.substring(0, o.length -1) + "});");	
			
			return p.toJSON();	
			/**/	
		}, 
		SetVar: function(name,value)
		{
			eval("this." + name + "= value;");		
		},		
		unserialize: function(data)
		{
			this.Reset();

			eval("var p = new Hash(" + data + " );");
			
			var keys = p.keys();
			
			for( i=0; i < keys.length; i++)
			{
				var obj = p.get(keys[i]);
			
				if( !(Object.isString(obj) || Object.isNumber(obj)) )
					eval("obj = new Hash(" + Object.toJSON(obj) + ");");
				
				this.SetVar(keys[i], obj );
			}
		}
	};		
	
	//////////////////////////////////////////////////
	//
	function onAjaxWorking(on, image_id)
	{
		image_id = (image_id != undefined) ? image_id : 'ajax_working';
		
		if( $(image_id) )
		{
			if( on )
				$(image_id).show();
			else
				$(image_id).hide();
		}	
	}	
	
	function IsValidEmail(email)
	{
		var pattern = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;

		return pattern.test(email);	
	}
	
	//////////////////////////////////////////////////
	//	
	function mysqlDate (timestamp)
	{
		var regex=/^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
		var parts=timestamp.replace(regex,"$1 $2 $3 $4 $5 $6").split(' ');
		
		return new Date(parts[0],parts[1]-1,parts[2],parts[3],parts[4],parts[5]);
	}	

	Date.prototype.format = function(format) {
	    var result = "";
	    for (var i = 0; i < format.length; ++i) {
	        result += this.dateToString(format.charAt(i));
	    }
	    return result;
	}
	
	Date.prototype.dateToString = function(character) 
	{
		//---[ TODO: determine if upper or lower case and add 0 ]---
		
	    switch (character) 
	    {
		    case "Y": return this.getFullYear(); break;
		    case 'm': return this.getMonth() + 1; break;
		    case 'd':return this.getDate(); break;
			case 'H':return this.getHours(); break;
			case 'i':return this.getMinutes(); break;
			case 's':return this.getSeconds(); break;
	    	default: return character; break;
	    }
	}
	

	