var RE_ALPHANUMERIC=/^[a-zA-Z0-9]+$/;
var RE_EMAIL=/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
var TIME_FORMAT="%H:%M";
var DATE_FORMAT="%d-%m-%Y";
var DATETIME_FORMAT="%d-%m-%Y %H:%M";
var RE_TIME=/^([01]?[0-9]|[2][0-3])(([:.])?([0-5][0-9]))?(([ap])\.?m\.?)?$/i;

var __DEBUG__=false;	
debugAlert=function(v){
	if(__DEBUG__){ alert("DEBUG\n\n"+v); }
}
getBody=function(){
	return $(document.getElementsByTagName("body")[0]);
}

var __LOG_ID__=0;
logToScreen=function(id,data){try{
	if(__DEBUG__){try{
		// Generate unique log id
		id=id+"-"+__LOG_ID__;
		
		var isHtml=false;
		if(data.toLowerCase().indexOf('</script>')>=0){
			isHtml=true;
		}
		
		// We dont want HTML to appear, else it stuffs up
		if(isHtml){
			data="HTML Page";
		}

		// Log the link to debugDiv
		var debugDiv=$("debugDiv");
		if(!debugDiv){return false;}
		var link=createElement("a");
		link.setAttribute("requestId",id);
		link.appendChild(createTextNode("Request "+id));
		link.onclick=function(evt){
			var el=Event.element(evt);
    		var requestId=el.getAttribute("requestId");
    		var request=$("request"+requestId);
    		request.toggle();
		}
		debugDiv.appendChild(link);
		debugDiv.appendChild(createElement("br"));

		// Log the data to debugDiv
		var div=createElement("div");
		div.setAttribute("id","request"+id);
		div.innerHTML=data;
		debugDiv.appendChild(div);
		div.hide();

		// Increment unique log id
		__LOG_ID__+=1;
	}catch(e){debugAlert(e)}}
	return true;
}catch(e){}}
document.observe("dom:loaded", function() {
	var debugDiv=createElement("div");
	debugDiv.id="debugDiv";
	getBody().appendChild(debugDiv);
});

Browser=function(){
	var _t=this;
	_t.ver=navigator.appVersion;
	_t.name=navigator.appName;
	_t.agent=navigator.userAgent;
	_t.dom=document.getElementById?1:0;
	_t.ns=(_t.name=="Netscape")?1:0;
	_t.moz=(_t.ns&&_t.agent.indexOf("Mozilla/")>-1)?1:0;
	_t.ff1=(_t.moz&&_t.agent.indexOf("Firefox/1")>-1)?1:0;
	_t.ff2=(_t.moz&&_t.agent.indexOf("Firefox/2")>-1)?1:0;
	_t.ff3=(_t.moz&&_t.agent.indexOf("Firefox/3")>-1)?1:0;
	_t.ff=_t.ff1||_t.ff2||_t.ff3;
	_t.opera5=_t.agent.indexOf("Opera 5")>-1;
	_t.ie4=(document.all&&!_t.dom&&!_t.opera5)?1:0;
	_t.ie5=(_t.ver.indexOf("MSIE 5")>-1&&_t.dom&&!_t.opera5)?1:0;
	_t.ie6=(_t.ver.indexOf("MSIE 6")>-1&&_t.dom&&!_t.opera5)?1:0;
	_t.ie7=(_t.ver.indexOf("MSIE 7")>-1&&_t.dom&&!_t.opera5)?1:0;
	_t.ie8=(_t.ver.indexOf("MSIE 8")>-1&&_t.dom&&!_t.opera5)?1:0;
	_t.ie=_t.ie4||_t.ie5||_t.ie6||_t.ie7||_t.ie8;
	_t.mac=_t.agent.indexOf("Mac")<-1;
	_t.ns4=(_t.ns&&document.layers&&!_t.dom)?1:0;
	_t.ns6=(_t.ns&&_t.dom&&parseInt(_t.ver)>=5)?1:0;
	_t.bw=(_t.ie6||_t.ie5||_t.ie4||_t.ns4||_t.ns6||_t.opera5);
	_t.valid=_t.ff||_t.ie6||_t.ie7||_t.ie8;
    _t.lt_ie7=_t.ie4||_t.ie5||_t.ie6;
};
Browser.prototype.getWindowWidth=function(){
	return window.innerWidth!=null?window.innerWidth:document.documentElement&&document.documentElement.clientWidth?document.documentElement.clientWidth:document.body!=null?document.body.clientWidth:null;
}
Browser.prototype.getWindowHeight=function(){
	return window.innerHeight!=null?window.innerHeight:document.documentElement&&document.documentElement.clientHeight?document.documentElement.clientHeight:document.body!=null?document.body.clientHeight:null;
}
Browser.prototype.getWindowPositionLeft=function(){
	return typeof window.pageXOffset!='undefined'?window.pageXOffset:document.documentElement&&document.documentElement.scrollLeft?document.documentElement.scrollLeft:document.body.scrollLeft?document.body.scrollLeft:0;
}
Browser.prototype.getWindowPositionTop=function(){
	return typeof window.pageYOffset!='undefined'?window.pageYOffset:document.documentElement&&document.documentElement.scrollTop?document.documentElement.scrollTop:document.body.scrollTop?document.body.scrollTop:0;
}
Browser.prototype.getWindowPositionRight=function(){
	return this.getWindowPositionLeft()+this.getWindowWidth();
}
Browser.prototype.getWindowPositionBottom=function(){
	return this.getWindowPositionTop()+this.getWindowHeight();
}
Browser.prototype.setWindowWidth=function(i){
	if(window.innerWidth!=null){
		window.innerWidth=i;
	}
	else if(document.documentElement&&document.documentElement.clientWidth){
		document.documentElement.clientWidth=i;
	}
	else if(document.body&&document.body.clientWidth){
		document.body.clientWidth=i;
	}
	return;
}
Browser.prototype.setWindowHeight=function(i){
	if(window.innerHeight!=null){
		window.innerHeight=i;
	}
	else if(document.documentElement&&document.documentElement.clientHeight){
		document.documentElement.clientHeight=i;
	}
	else if(document.body&&document.body.clientHeight){
		document.body.clientHeight=i;
	}
	return;
}
browser=new Browser();

var toXml=function(node){
	if(browser.ie){ return node.xml; }
	var o=new XMLSerializer;
	return o.serializeToString(node);
}
function _Node_getXml(){ return toXml(this); }
if(!browser.ie){ Node.prototype.__defineGetter__("xml",_Node_getXml); };

if(!browser.ie){ 
    function _Node_getChildNodeByName(name){
    	if(this.hasChildNodes()){
    		for(var i=0;i<n.childNodes.length;i++){
    			var childNode=this.childNodes[i];
    			if(childNode.nodeType==1){
    				if(childNode.nodeName==name){
    					return childNode;
    				}
    			}
    		}
    	}
    	return null;
    }
	Node.prototype.__defineGetter__("getChildNodeByName",_Node_getChildNodeByName); 
}
else {
    Element.addMethods({
    	getChildNodeByName: function(el, name){
        	if(el.hasChildNodes()){
        		for(var i=0;i<n.childNodes.length;i++){
        			var childNode=el.childNodes[i];
        			if(childNode.nodeType==1){
        				if(childNode.nodeName==name){
        					return childNode;
        				}
        			}
        		}
        	}
        }
    });
}


clearNode=function(n){
	n=$(n);
	while(n.childNodes.length>0){
		var cn=n.childNodes[0];
		clearNode(cn);
		n.removeChild(cn);
		cn=null;
		delete cn;
	}
	return;
}	

clearInputErrors=function(fObj){
	fObj=$(fObj);
    fObj.select(".inputError").each(function(el){
		clearInputError(el);
    });
};
clearInputError=function(el){
	el=$(el);
	if(el.parentNode){
    	$(el.parentNode).removeClassName("inputError");
    }
};

fillInputError=function(el){
	el=$(el);
	if(el){
		if(el.parentNode){
        	$(el.parentNode).addClassName("inputError");
		}
		el.observe("change",function(ev){
			var v=this.isEmpty();
			if(!this.isEmpty()){
				clearInputError(this);
			}
		});
	}
}

Element.addMethods({
	isTagNameEqualTo: function(el, tagName){
    	if (getType(el)!="string"){
    		if (el.tagname){
    			if (el.tagname.toLowerCase().indexOf(tagName)>=0) {
    				return true;
    			}
    		}
    	}
    	return false;
    }
});

Element.addMethods({
    isSelect: function(el){
    	return el.isTagNameEqualTo("select");
    }
});

Element.addMethods({
    isRadio: function(el){
    	if (el.type){
    		if (el.type.toLowerCase() == "radio"){
                return true;
    		}
    	}
    	return false;
    }
});

Element.addMethods({
    isCheckbox: function(el){
    	if (el.type){
    		if (el.type.toLowerCase() == "checkbox"){
                return true;
    		}
    	}
    	return false;
    }
});

Element.addMethods({
    isInteger: function(el){
        if(el.value){ return (el.value.toString().strip().search(/^-?[0-9]+$/)==0); }
        else { return false; }
    }
});

Element.addMethods({
    isUnsignedInteger: function(el){
        if(el.value){ return (el.value.toString().strip().search(/^[0-9]+$/)==0); }
        else { return false; }
    }
});

Element.addMethods({
    isEmail: function(el){
    	if(el.value){ return RE_EMAIL.test(el.value); }
    	else { return false; }
    }
});

Element.addMethods({
    isEmpty: function(el){
    	if(el.isSelect()){
    		return el.options[el.options.selectedIndex].value=="";
    	}
    	else if(el.isRadio()) {
    		// We are given a radio button within the radio group
    		// Grab the radio group instead
    		var radioGroup = el.name;
    		var fObj = $(el.form);
    		var isChecked = false;
    		fObj.getInputs('radio',radioGroup).find(
    	        function(radio) {
    	        	if (radio.checked) {
    	        		isChecked = true;
    	        	}
    	        }
			)
			return !isChecked;
    	}
		else if (el.isCheckbox()) {
			// With checkboxes, get the grouping
			var checkboxGroup = el.name;
    		var fObj = $(el.form);
    		var isChecked = false;
    		fObj.getInputs('checkbox',checkboxGroup).find(
    		    function(checkbox) {
                	if (checkbox.checked){
                	    isChecked = true;
                	}
                }
		    )
            return !isChecked;
    	}
    	else {
			var v=el.getValue();
			if(v==null){
				return true;
			}
			if(v.length==0){
				return true;
			}
			if(v==""){
				return true;
			}
        	return false;
    	}
    	// All other objects return false, as we dont know anything about them
    	return false;
    }
});

Element.addMethods("form",  {
    setControllerAction: function(fObj, action) {
        addFormElement(fObj,"_action_",action);
    }
});

Element.addMethods("form",  {
    isValid: function(fObj) {
        fObj=$(fObj);
        clearInputErrors(fObj);
        var flag=true;
        fObj.select(".mandatory").each(function(input){
            if(input.isEmpty()){
                fillInputError(input);
                flag=false;
            }
        });
        fObj.select(".email").each(function(input){
            if(!input.isEmpty()){
                if(!input.isEmail()){
                    fillInputError(input);
                    flag=false;
                }
            }
        });
        fObj.select(".integer").each(function(input){
            if(!input.isEmpty()){
                if(!input.isInteger()){
                    fillInputError(input);
                    flag=false;
                }
            }
        });
        if(!flag){
            alert("Some of your fields are invalid.  Please try again.");
        }
        return flag;
    }
});
Element.addMethods({
    setInvalidInput: function(fObj, input, error){
        fObj=$(fObj);
        clearInputErrors(fObj);
        fillInputError(input);
        alert(error);
    }
});

Element.addMethods("table",  
	{
        addRow: function(tObj) {
	        var r = tObj.insertRow(tObj.rows.length);
	        return r;
        }
    }
);

createTextNode=function(s){
	return document.createTextNode(s);
}
createText=createTextNode;

createElement=function(n){
	return new Element(n);
}

createInput=function(n){
	var el=createElement("input");
	el.setAttribute("type","text");
	el.setAttribute("name",n);
	el.setAttribute("id",n);
	el.addClassName("text");
	return el;
}

createInteger=function(n){
	var el=createInput(n);
	el.setAttribute("size", "8");
	el.setAttribute("maxlength", "8");
	el.addClassName("integer");
	return el;
}

createCheckbox=function(n,v){
    if(!v){ v=1; }
	var el=createInput(n);
	el.setAttribute("type", "checkbox");
	el.setAttribute("class", "checkbox");
	el.setAttribute("value", "1");
	return el;
}

createSpacerImage=function(h,w){
	return createImage("/images/spacer.gif",h,w);
}

createImage=function(src,h,w){
	var img=createElement("img");
	img.setAttribute("src",src);
	img.setAttribute("border","0");
	img.setAttribute("hspace","0");
	img.setAttribute("vspace","0");
	if(h){img.setAttribute("height",h);}
	if(w){img.setAttribute("width",w);}
	return img;
}
openWindow = function(u,n,h,w){
    if(!h)h=500;
    if(!w)w=700;
    if(!n)n="_blank";
    var o="toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width="+w+",height="+h+",screenX=20,screenY=0,copyhistory=no";
    var wi=window.open(u,n,o);
    if(wi.focus){wi.focus();}
    return wi;
}


LoadBar=function(id,text,size,buffer){
	if(!text){text="Loading...";}
	if(!size){size=60;}
	if(!buffer){buffer=20;} // Make it wider... to cover scrollbars
	var o=createElement("div");
	this.div=o;
	this.size=size;
	this.buffer=buffer;
	this.id=id;
	this.text=text;
	this.state=0;
	this.pid=-1;

	o.setAttribute("id",this.id);
	o.appendChild(createTextNode(this.text));
	o.style.backgroundColor="#ff0000";
	o.style.color="#ffffff";
	o.style.padding="3px";
	var z=this.size;
	o.style.width=z+"px"; 
	o.style.position="absolute";
	o.style.zIndex="89";

	// Append to body, hide it to begin with
	var body=getBody();
	body.appendChild(o);
	this.div.hide();
}
LoadBar.prototype.show=function(text){
	if(text){
		clearNode(this.div);
		this.div.appendChild(createTextNode(text));
	}
	var h=browser.getWindowPositionTop();
	var w=browser.getWindowPositionRight();
	var z=w-this.size-this.buffer-6;
	this.div.style.left=z+"px";
	this.div.style.top=h+"px";
	this.div.style.zIndex="89";
	if (this.state==0){
		this.state=1;
		//new Effect.BlindDown(this.id,{duration:0.2});
		this.div.style.display="";
	}
	return;
}
LoadBar.prototype.reposition=function(){
	if(this.state==1){ this.show(); }
}
LoadBar.prototype.setTimeout=function(cmd,ms){
	this.clearTimeout();
	this.pid=setTimeout(cmd,ms);
}
LoadBar.prototype.clearTimeout=function(){
	if(this.pid>0){
		clearTimeout(this.pid);
		this.pid=-1;
	}
}
LoadBar.prototype.hide=function(){
	clearNode(this.div);
	this.clearTimeout();
	this.div.appendChild(createTextNode(this.text));
	this.div.style.left="-10000px";
	this.div.style.top="-10000px";
	this.div.style.zIndex="-1000";
	this.div.style.display="none";
	if (this.state==1){
		this.state=0;
		//new Effect.BlindUp(this.id,{duration:0.2});
		this.div.hide();
	}
	return;
}
loadBar=null;
document.observe("dom:loaded", function() {
	loadBar=new LoadBar("loadBar","Loading...",60,10);
	loadBar.hide();
	setInterval("loadBar.reposition();", 100);
});

var __AJAXFUNC__=new Object();
var __RPC__=1;
var __XML__=2;
var __JSON__=3;

__callWorker__=function(u,ol,as,te,po,ta,es,olpa){try{
	var id=new Date().getTime();
	if(u.indexOf("?")<0){u+="?";}
	u+="&requestId="+id;
	var me=po?'post':'get';
	var pa='';
	var isXml=te==__XML__;
	var isJson=te==__JSON__;
	var isText=te==__RPC__;
	if(!isXml&!isJson&!isText){isText=true;}
	if(me=='post'){
		var arr=u.split("?");
		u=arr[0];
		pa=arr[1];
	}
	var options={};
	ta=$(ta);
	options["method"]=me;
	options["parameters"]=pa;
	if((ta)&&(es)){
		options["evalScripts"]=true;
	}
	if(as){
		try{ loadBar.show(); }
		catch(e){}
		__AJAXFUNC__[id]=0;
		options["onSuccess"] = function(transport){
			var re=!isXml?transport.responseText:transport.responseXML;
			logToScreen(id,re);
			if(isJson){
				try{
					re=re.evalJSON(true);
				} catch(e) {
					debugAlert("JSON eval failed for :'"+re+"'.");
				}
			}
			if(ol){
				if(re){
					var fn;
					try{
						if(typeof ol=="function"){
							fn=ol;
						}
						else{
							fn=eval(ol);
						}
					}
					catch(e){ debugAlert(e); }
					if(fn){
						if(olpa){fn(re,olpa);}
						else{fn(re);}
					}
				}
			}
			if(id in __AJAXFUNC__){
				__AJAXFUNC__[id]=1;
			}
			try{ loadBar.hide(); }
			catch(e){}
		};
		options["onFailure"]=function(){
			debugAlert("Ajax call failed for: '"+u+"'.");
			try{ loadBar.hide(); }
			catch(e){}
		};
		var asReq;
		if (ta){ 
			logToScreen(u+" (UPDATE)","")
			logToScreen(ta.id,'');
			logToScreen(u,'');
			logToScreen(options,'');
			asReq=new Ajax.Updater(ta.id,u,options); 
		}
		else{ 
			logToScreen(u+" (NORM)","")
			asReq=new Ajax.Request(u,options); 
		}
	}
	else{
		options["asynchronous"]=false;
		var snReq;
		if (ta){ snReq=new Ajax.Updater(ta,u,options); }
		else{ snReq=new Ajax.Request(u,options); }
		if(ol){
			var fn;
			try{
				if(typeof ol=="function"){
					fn=ol;
				}
				else{
					fn=eval(ol);
				}
			}
			catch(e){ debugAlert(e); }
			if(olpa){return fn(olpa);}
			else{return fn();}
		}
		else{
			var re=!isXml?snReq.transport.responseText:snReq.transport.responseXML;
			if(isJson){
				try{
					re=re.evalJSON(true);
				} catch(e) {
					debugAlert("JSON eval failed for :'"+re+"'.");
				}
			}
			return re;
		}
	}
	return;
}catch(e){debugAlert(e)}}
callAjaxXml=function(u,ol,olpa){
	return __callWorker__(u,ol,true,__XML__,true,null,false,olpa);
}
callAjaxJson=function(u,ol,olpa){
	return __callWorker__(u,ol,true,__JSON__,true,null,false,olpa);
}
callAjaxRpc=function(u,ol,olpa){
	return __callWorker__(u,ol,true,__RPC__,true,null,false,olpa);
}
callAjaxUpdater=function(ta,u,ol,olpa){
	return __callWorker__(u,ol,true,__RPC__,true,ta,true,olpa);
}

toFixed=function(v,p){
	var d,c;
    if(isNaN(v)){
    	d="",c="";
    }
    else{    
    	var a=v+"";
        var b="1";
        for(var i=0;i<p;i++){b+="0";}
        b=parseInt(b);
        var ra=Math.round(a*b)/b;
        var sa=ra.toString().split(".");
        d=sa[0],c=sa[1];
        if(!(c)){c="";}
        if(c==null){c="";}
        d=d.toString();
        c=c.toString();
    }
    if(d.length==0){d="0";}
    while(c.length<p){c+="0";}
    var n=d+"."+c;
    return n;
}
Number.prototype.toFixed=function(p){
	return toFixed(this,p);
}
String.prototype.toFixed=function(p){
	return toFixed(this,p);
}


Element.addMethods({
    runEvent: function(el, eventType){
    	if(document.createEvent){
    		var evObj=document.createEvent('MouseEvents');
    		evObj.initEvent(eventType,true,true);
    		el.dispatchEvent(evObj);
    	}
    	else if(document.createEventObject){
    		el.fireEvent('on'+eventType);
    	}
    	else{
    		//el.click();
    	}
    }
});
clickObject = function(obj){
	obj.runEvent("click");
}

// Global Functions
getType = function(obj) {
	return typeof(obj);
}

getObject = function(name){
	return $(name);
}

setElementValue = function(iObj, value, text) {
	iObj = $(iObj);
	if (getType(iObj)!="string"){
		if(iObj.isSelect()){
			setSelectValue(iObj, value, text);
		}
		else{
			// Just a normal field
			iObj.value = value;
		}
	}
}

getElementValue = function(iObj){
	return $(iObj).getValue();
}

addSelectOption = function(sObj, value, text, isSelected) {
	sObj = $(sObj);
	if (!text){ text = value; }
	if (!isSelected){ isSelected = false; }
	var length = sObj.length;
	var oObj = new Option(text, value, false, isSelected)
    sObj.length += 1;
	sObj.options[length] = oObj;
}

setSelectValue = function(sObj, value, text, isSelected){
	sObj = $(sObj);
	value += "";
	var isSet = false;
	for(var i=0;i<sObj.options.length;i++){
		var optionValue = sObj.options[i].value;
		if (optionValue == value) {
			sObj.options.selectedIndex = i;
			isSet = true;
		}
	}
	if(!isSet){
		addSelectOption(sObj, value, text, isSelected);
	}
	return;
}

createFormElement = function(fObj,name,value) {
	var iObj = new Element("input")
	iObj.setAttribute("type","hidden");
	iObj.setAttribute("id",name);
	iObj.setAttribute("name",name);
	iObj.setAttribute("value",value);
	fObj.appendChild(iObj);
	return iObj;
}

addFormElement = function(fObj, name, value){
	var iObj = eval("fObj."+name);
	if(iObj == null){
		iObj = createFormElement(fObj, name, value);
	}
	else {
		iObj=$(iObj);
		setElementValue(iObj, value);
	}
	return iObj;
}

convertToCode=function(v,allowableChars){
    var s="";	
    if(!allowableChars){
    	allowableChars="";
    }
    for(var i=0;i<v.length;i++){
    	var c=v.substr(i,1);
    	if(RE_ALPHANUMERIC.test(c)){
    		s+=c;
    	}
    	else if(allowableChars.indexOf(c)>=0){
    		s+=c;
    	}
    	else{
    		s+="-";
    	}
    }
    while(s.indexOf("--")>=0){
        s=s.replace(/--/g,"-");
    }
    return s.toLowerCase();
}

convertToInt=function(v){
	try{
    	return parseInt(v);
	}
	catch(e){
        debugAlert(e);
	}
    return null;
}

quote=function(v){
	return escape(v);
}

unquote=function(v){
	return unescape(v);
}

validateTimeValues=function(h,m,s){
	with(new Date(0,0,0,h,m,s)){
		return((getHours()==h)&&(getMinutes()==m));
	}
}

convertToTime=function(value){
	var T=RE_TIME.exec(value);
	if(T==null){return "";}
	var hours=T[1];
	if((hours.length>1)&&(hours.charAt(0)=="0")){
		hours=parseInt(hours.charAt(1));
	}
	else{
		hours=parseInt(T[1]);
	}
	var minutes=T[4];
	if(minutes){
		minutes=parseInt(minutes);
	}
	else{
		minutes=0;
	}
	var aorp=T[6];
	if(aorp!=""){
		if(hours<12){
			hours=hours%12+12*/p/i.test(aorp);
		}
	}
	//isValid=validateTimeValues(hours,minutes,0);
	var h="", m="";
	isValid=true;
	if(isValid){
		if(hours<10){ h += "0"; }
		h+=hours.toString();
		if(minutes<10){ m += "0"; }
		m+=minutes.toString();
	}
	return h+":"+m;
}

convertToDate=function(value){
    var D=Date.parse(value);
    var R="";
    if(D){
    	R=D.strftime(DATE_FORMAT);
    }
	return R;
}

PRELOADED_IMAGES=new Array();
preloadImage=function(url){
	var img=new Image();
	img.src=url;
	PRELOADED_IMAGES[PRELOADED_IMAGES.length]=img;
}

showOverlayWaiting=function(html){
	$('overlay_waiting').show();
	$('overlay_waiting_html').show();
	$('overlay_waiting_html').innerHTML=html;
}
hideOverlayWaiting=function(){
	$('overlay_waiting_html').hide();
	$('overlay_waiting').hide();
}

