var d=new DateFunctions();
var f=new FormFunctions();
var n=new NumberFunctions();
var s=new StringFunctions();
var dd=new DropdownFunctions();
var cb=new CheckBoxFunctions();
var e=new Effects();
var dl=new DataListFunctions();
var c=new CookieFunctions();




//date functions
function DateFunctions() {

	this.New=function(iDay, iMonth, iYear) {
		return new Date(iYear, iMonth-1, iDay);
	}
	
	this.GetDateOnly=function(dDate) {		
		return d.New(d.Day(dDate),d.Month(dDate),d.Year(dDate));
	}
	
	this.AddDays=function (dDate, iDays) {
		dDate.setDate(dDate.getDate()+iDays);
		return dDate;
	}
	
	this.Year=function (dDate) {
		return dDate.getFullYear();
	}
	
	this.Month=function (dDate) {
		return dDate.getMonth()+1;
	}
	
	this.Day=function(dDate) {
		return dDate.getDate();
	}
	
	this.DayName=function(dDate) {
		return s.Left(dDate+'',3);
	}
	
	this.MonthName=function(dDate) {
		var aMonths=new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
		return aMonths[d.Month(dDate) - 1];
	}
	
	this.MonthEnd=function(dDate) {
	
		//create new date 01/month+1/year
		return d.AddDays(d.New(1, (d.Month(dDate)==12) ? 1 : d.Month(dDate)+1,
			(d.Month(dDate)==12) ? d.Year(dDate)+1 : d.Year(dDate)),-1);
	}
	
	this.Weekend=function(dDate) {
		return (s.Left(dDate+'',1)=='S');
	}
	
	this.IsDate=function(oDate) {
		return !isNaN(new Date(oDate));
	}
	
	this.SafeDate=function(oDate) {
		if (this.IsDate(oDate)) {
			return new Date(oDate);
		}
	}
	
	this.DisplayDate=function(dDate) {
		dDate=new Date(dDate)
		
		var aMonths=new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')
		
		var sDay=dDate.getDate().toString()
		if (sDay.length==1) {
			sDay='0'+sDay;
		}
		return sDay + ' ' +aMonths[dDate.getMonth()] + ' ' +dDate.getFullYear();
	}
	
	this.GetAge=function(dDateOfBirth) {
	    
	    var dNow=new Date();
	    var iAge=-1;
	    
	    while (dNow >= dDateOfBirth) {
	        iAge++;
            dDateOfBirth.setFullYear(dDateOfBirth.getFullYear() + 1);  
	    }
	    
	    return iAge;
	}
	
	this.DateDiff=function(sStartDate,sEndDate) {
		
		var dStartDate=new Date(sStartDate);
		var dEndDate=new Date(sEndDate);
		var iStartYear;
		var iEndYear;
		var iStartDayOfYear;
		var iEndDayOfYear;
		var iDiff;	
		
		//get the years and day of years, if end date is before start date then swap them round
		if (dStartDate<=dEndDate) {
			iStartYear=dStartDate.getYear();
			iEndYear=dEndDate.getYear();
			iStartDayOfYear=this.DayOfYear(dStartDate);
			iEndDayOfYear=this.DayOfYear(dEndDate);
		} else {
			iStartYear=dEndDate.getYear();
			iEndYear=dStartDate.getYear();
			iStartDayOfYear=this.DayOfYear(dEndDate);
			iEndDayOfYear=this.DayOfYear(dStartDate);
		}	
			
		
		//2 possibilities, same year, different years
		if (iStartYear==iEndYear) {
			
			iDiff=iEndDayOfYear-iStartDayOfYear;
		
		} else {
				
			//one or more years apart starts with same calculation
			iDiff=iEndDayOfYear+(365-iStartDayOfYear);
			
			//if it's a leap year and next year is different then add
			if (this.CheckLeapYear(iStartYear)==1 && iEndYear!=iStartYear) {
				iDiff+=1;
			}
			
			//now loop through all (if any years inbetween)
			for (var iLoop=iStartYear+1;iLoop<iEndYear;iLoop++) {			
		
				//add 365 for a normal year, 366 for a leap year
				if (this.CheckLeapYear(iLoop)==1) {
					iDiff+=366;
				} else {
					iDiff+=365;
				}			
			}		
		}
		
		// if start date > end date invert the difference
		if(dStartDate>dEndDate) {
			iDiff=iDiff*(-1);
		}
		
		return iDiff;
	}
	
	this.CheckLeapYear=function(iYear) {
		return (((iYear % 4 == 0) && (iYear % 100 != 0)) || (iYear % 400 == 0)) ? 1 : 0;
	}
	
	this.DayOfYear=function(dDate) {
		
		//start with current day of month and then add on preivous mointh days
		var iDayOfYear=dDate.getDate();
		var iMonth=dDate.getMonth();
		var iYear=dDate.getYear();
		
		//if it's a leap year and we are past Februrary then add 1
		if((this.CheckLeapYear(iYear)==1)&&(iMonth>=2)) {
			iDayOfYear++;
		}
		
		//now do a huge ugly if statement adding the rest on for the months
		if (iMonth==1) {
			iDayOfYear+=31;
		} else if (iMonth==2) {
			iDayOfYear+=59;
		} else if (iMonth==3) {
			iDayOfYear+=90;
		} else if (iMonth==4) {
			iDayOfYear+=120;
		} else if (iMonth==5) {
			iDayOfYear+=151;
		} else if (iMonth==6) {
			iDayOfYear+=181;
		} else if (iMonth==7) {
			iDayOfYear+=212;
		} else if (iMonth==8) {
			iDayOfYear+=243;
		} else if (iMonth==9) {
			iDayOfYear+=273;
		} else if (iMonth==10) {
			iDayOfYear+=304;
		} else if (iMonth==11) {
			iDayOfYear+=334;
		}
		
		return iDayOfYear;
	}
	
}

//number functions
function NumberFunctions() {

    this.SafeInt = function(sInteger) {
        if ((sInteger == null) || (sInteger == '') || (sInteger == '0')) {
            return 0;
        } else {

            //remove any commas
            sInteger += '';
            var aInt = sInteger.split(",");
            var sTotal = '';
            for (var loop = 0; loop < aInt.length; loop++) {
                sTotal += aInt[loop];
            }
            return parseInt(parseFloat(sTotal));
        }
    }
	
	
	this.SafeNumeric=function(sNumber) {            
        if (sNumber==null || sNumber=='' || sNumber=='0' || isNaN(parseFloat(sNumber))) {
              return 0;
        } else {
        
              //remove any commas
              sNumber+='';
              return parseFloat(sNumber.replace(',',''));
        }
	}

	
	this.Cent=function(nNumber) {
	
		// returns the amount in the .99 format
		return (nNumber == Math.floor(nNumber)) ? nNumber + '.00' : ((nNumber*10== Math.floor(nNumber*10)) ? nNumber + '0' : nNumber);

	}

	this.Round=function(nNumber,X) {

		// rounds number to X decimal places, defaults to 2
		X = (!X ? 2 : X);
		return Math.round(nNumber*Math.pow(10,X))/Math.pow(10,X);

	}
	
	this.FormatMoney=function(nNumber,sCurrency) {
		
		//get the rounded figure
		var nRounded=n.Cent(n.Round(nNumber));
		if (sCurrency!=undefined) {
			
			if (nRounded<0) {
				nRounded=n.Cent(nRounded*(-1));
				return '-'+sCurrency+nRounded;
			} else {
				return sCurrency+nRounded;
			}
		} else {
			return nRounded;
		}
		
	}
	
	this.FormatNumber=function(o,iDecimalPlaces) {

		o=n.SafeNumeric(o);
		return o.toFixed(iDecimalPlaces==undefined ? 2 : iDecimalPlaces);
	}
	
}

//string functions
function StringFunctions() {

	this.Left=function(s,i) {
		return s.substring(0,i);
	}
	
	this.Right=function(s,i) {
		return s.substring(s.length - i);
	}
	
	this.Chop=function(sString,i) {
	    
	    if (i==undefined) {
	        i=1;
	    }
	    
	    return s.Substring(sString,0,sString.length - i);
	}
	
	this.Substring=function(s,iStart,iLength) {

		if (iLength == undefined) {
			return s.substring(iStart);
		} else {
			return s.substring(iStart,iLength);
		}
	}
	
	this.Slice=function(s,iStart,iEnd) {
		if (iEnd==undefined) {
			iEnd=iStart;
		}
		return s.substring(iStart,iStart + (iEnd - iStart) + 1);
	}
	
	this.StartsWith=function(sBase, sCompare) {
		return sBase.indexOf(sCompare)==0;
	}
	
	this.Replace=function(sString, sStringToReplace, sReplacement) {
		while (sString.indexOf(sStringToReplace) != -1) {
			sString=sString.replace(sStringToReplace, sReplacement);
		}
		return sString;
	}
	
	this.Trim=function(sBase) {
		return sBase.replace(/^\s*|\s*$/g,'');
	}
}

//form functions
function FormFunctions() {

	this.GetObject=function(sID) {
		return document.getElementById(sID);
	}
	
	this.GetObjectsByIDPrefix=function(sPrefix,sTagName) {
	
		var aObjects=new Array();		
		
		if (sTagName==undefined) {
			sTagName='input';
		}
		
		var aElements=document.getElementsByTagName(sTagName);		
		for (var i=0;i<aElements.length;i++) {
			if (s.StartsWith(aElements[i].id,sPrefix)) {
				aObjects.length=aObjects.length+1;
				aObjects[aObjects.length-1]=aElements[i];
			}
		}
		
		return aObjects;		
	}
	
	
	this.GetValue=function(o) {
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			return oControl.value;
		} else {
			return '';
		}
	}
	
	this.GetIntValue=function(o) {
	    var oControl=this.SafeObject(o);
		if (oControl!=null) {
			return n.SafeInt(oControl.value);
		} else {
			return 0;
		}
	}
	
	this.GetNumericValue=function(o) {
	    var oControl=this.SafeObject(o);
		if (oControl!=null) {
			return n.SafeNumeric(oControl.value);
		} else {
			return 0;
		}
	}
	
	this.SetValue=function(o, sValue) {
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			oControl.value=sValue;
		}
	}

	this.GetHTML = function(o) {
	    var oControl = this.SafeObject(o);
	    if (oControl != null) {
	        return oControl.innerHTML;
	    }
	    return '';
	}

	this.SetHTML = function(o, sValue) {
	    var oControl = this.SafeObject(o);
	    if (oControl != null) {
	        oControl.innerHTML = sValue;
	    }
	}
		
	this.SafeObject=function(o) {
		if (typeof(o)=='object') {
			return o;
		} else if (typeof(o)=='string') {
			return this.GetObject(o);
		} else {
			return null;
		}
	}
	
	this.Toggle=function(o) {
		var oControl=this.SafeObject(o);
		oControl.style.display=oControl.style.display=='none' ? 'block' : 'none';
	}
	
	this.Show=function(o) {
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			oControl.style.display=oControl.style.display='';
		}
	}
	
	this.Hide=function(o) {
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			oControl.style.display=oControl.style.display='none';
		}
	}
	
	this.Visible = function(o) {
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			return oControl.style.display!='none';
		} else {
			return false;
		}
	}
	
	this.SetClass = function(o,s) {
		var oControl=this.SafeObject(o);
		oControl.className=s;
	}
	
	this.GetClass = function(o) {
		var oControl=this.SafeObject(o);
		return oControl.className;
	}


	this.SetClassIf = function(o, ClassName, bCondition) {

	    if (bCondition) {
	        f.AddClass(o, ClassName);
	    } else {
	        f.RemoveClass(o, ClassName);
	    }
	}	

	
	this.AddClass=function(o,s) {
	
		var aClassNames = f.GetClass(o).split(' ');
		var bExist = false;
		
		// check whether the class already exist
		for (var i=0;i<aClassNames.length;i++) {
			if (aClassNames[i]==s) {
				bExist=true;
				break;
			}
		}
		
		// add class if the class not exists
		if (!bExist) {
			f.SetClass(o, f.GetClass(o)+' '+s)
		}						
	}
	
	
	this.RemoveClass=function(o,s) {
	
		var sClassName='';
		var aClassNames = f.GetClass(o).split(' ');
		
		// 
		for (var i=0;i<aClassNames.length;i++) {
			if (aClassNames[i]!=s) {
				sClassName=sClassName+aClassNames[i]+' ';
			}
		}
		
		f.SetClass(o,sClassName);				
	}
	
	
	this.GetElementsByClassName=function(sElement, sClassName) {
		
		var aElements=document.getElementsByTagName(sElement);
		var aReturn=new Array();
		for (var i=0;i<aElements.length;i++) {
		
			if (aElements[i].className.indexOf(sClassName)>-1) {
				aReturn[aReturn.length]=aElements[i];
			}
		}
		
		return aReturn;		
	}

	this.ShowIf = function(o, bCondition) {

	    if (o.constructor != Array) {
	        var oControl = this.SafeObject(o);
	        if (bCondition) {
	            this.Show(o);
	        } else {
	            this.Hide(o);
	        }
	    } else {
	        for (var i = 0; i < o.length; i++) {
	            f.ShowIf(o[i], bCondition);
	        }
	    }
	}

	this.BuildList = function(aListItems) {

	    var sList = '<ul>';
	    for (var i = 0; i < aListItems.length; i++) {
	        if (!aListItems[i] == '') {
	            sList += '<li>' + aListItems[i] + '</li>';
	        }
	    }
	    sList += '</ul>';
	    return sList;
	}
	
	this.Disable=function(o) {
		
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			oControl.readOnly=true;
		}
	}
	
	this.Enable=function(o) {
		
		var oControl=this.SafeObject(o);
		if (oControl!=null) {
			oControl.readOnly=false;
		}
	}
	
	this.ClearFileUpload=function(o) {
	    
	    var oControl=this.SafeObject(o);
	    if (oControl!=null) {
			oControl.outerHTML=oControl.outerHTML;
		}   
	}
	
	
	/* event handling */
	this.AttachEvent=function(oObject, sEventName, oFunction) {
	
		oObject=this.SafeObject(oObject);
		
		var oListenerFunction = oFunction;
		
		if (oObject.addEventListener) {
			oObject.addEventListener(sEventName, oListenerFunction, false);
		} else if (oObject.attachEvent) {
			oListenerFunction = function() {
				oFunction(window.event);
			}
			oObject.attachEvent("on" + sEventName, oListenerFunction);
		} else {
			throw new Error("Event registration not supported");
		}
		
		
		var oEvent = {Instance: oObject, EventName: sEventName, Listener: oListenerFunction};
		return oEvent;
	}

	
	this.DetachEvent=function(oEvent) {
	
		var oObject=oEvent.Instance;
		
		if (oObject.removeEventListener) {
			oObject.removeEventListener(oEvent.EventName, oEvent.Listener, false);
		} else if (oObject.detachEvent) {
			oObject.detachEvent("on" + oEvent.EventName, oEvent.Listener);
		}
	}

	this.GetObjectFromEvent=function(oEvent) {
		return oEvent.srcElement ? oEvent.srcElement : oEvent.target;
	}
	
	this.GetKeyCodeFromEvent=function(oEvent) {
		return oEvent.keyCode ? oEvent.keyCode : oEvent.which;
	}

	this.ShowPopup = function(oObject, sClassName, sHTML, sSourceObjectID, bRightAlign, iYOffset, iXOffset) {

	    if (iYOffset == undefined) { iYOffset = 0; }
	    if (iXOffset == undefined) { iXOffset = 0; }

	    if (sSourceObjectID != undefined && f.GetObject(sSourceObjectID)) {
	        sHTML = f.GetObject(sSourceObjectID).innerHTML;
	    }
	    
	    //create container			
	    var oHelp = document.createElement('div');
	    oHelp.setAttribute('id', 'divPopup');
	    f.SetClass(oHelp, sClassName);
	    oHelp.style.position = 'absolute';
	    oHelp.innerHTML = sHTML;

	    //set position
	    var oDimensions = new e.BrowserDimensions();
	    var oLinkPosition;
	    if (!oObject.Left) {
	        oLinkPosition = e.GetPosition(oObject);
	    } else {
	        oLinkPosition = new e.Position();
	        oLinkPosition.Left = oObject.Left;
	        oLinkPosition.Top = oObject.Top;
	    }

	    oHelp.style.top = n.SafeInt(oLinkPosition.Top + 20 + iYOffset) + 'px';
	    oHelp.style.left = n.SafeInt(oLinkPosition.Left + iXOffset) + 'px';



	    //create mask
	    if (navigator.appVersion.indexOf('MSIE 6') > 0) {
	        var oMask = document.createElement('iframe');
	        oMask.setAttribute('id', 'iMask');
	        oMask.src = '';
	        e.SetPosition(oMask, e.GetPosition(oHelp));
	        f.GetObject('frm').appendChild(oMask);
	    }

	    f.GetObject('frm').appendChild(oHelp);

	    //move it if it's too low
	    oHelpPosition = e.GetPosition(oHelp);
	    if (oHelpPosition.Top + oHelpPosition.Height > oDimensions.ViewportHeight + f.ScrollPosition()) {
	        oHelp.style.top = oDimensions.ViewportHeight + f.ScrollPosition() - oHelp.offsetHeight - 10 + 'px';
	    }


	    //if we're right aligning then shift over now
	    if (bRightAlign != undefined) {
	        oHelp.style.left = oLinkPosition.Left - oHelp.clientWidth + iXOffset + 'px';
	    }
	}
	

	this.HidePopup=function() {
		if (navigator.appVersion.indexOf('MSIE 6')>0 && f.GetObject('iMask')) {
			f.GetObject('frm').removeChild(f.GetObject('iMask'));
		} 
		
		if (f.GetObject('divPopup')) {
			f.GetObject('frm').removeChild(f.GetObject('divPopup'));
		}
	}	
	
	this.ScrollPosition=function() {
		return (window.pageYOffset) ? 
					window.pageYOffset
					:(document.documentElement && document.documentElement.scrollTop)
						? document.documentElement.scrollTop : document.body.scrollTop;
	}



	this.GetContainerQueryString = function(oContainer) {

	    var aElements = f.SafeObject(oContainer).getElementsByTagName('*');

	    var sQueryString = '';
	    for (var i = 0; i < aElements.length; i++) {
	        if (aElements[i].name) {
                if (!s.StartsWith(aElements[i].id, 'rad')) {
	                sQueryString += (sQueryString == '' ? '' : '&') + aElements[i].name + '='
	            }

	            if (aElements[i].nodeName == 'INPUT' && s.StartsWith(aElements[i].id, 'chk')) {
	                sQueryString += aElements[i].checked;
	            } else if (aElements[i].nodeName == 'INPUT' && s.StartsWith(aElements[i].id, 'rad')) {
	                if (aElements[i].checked) {
	                    sQueryString += aElements[i].name + '=' + f.GetValue(aElements[i]);
	                }
	            } else if (aElements[i].nodeName == 'INPUT') {
	                sQueryString += encodeURI(f.GetValue(aElements[i]));
	            } else if (aElements[i].nodeName == 'SELECT') {
	                sQueryString += encodeURI(f.GetValue(aElements[i]) != '' ? dd.GetValue(aElements[i]) : dd.GetText(aElements[i]));
	            }
	        }
	    }

	    return sQueryString;

	}


	

	
}

//checkbox functions 
function CheckBoxFunctions() {

	this.Checked=function(o) {
		o=f.SafeObject(o);
		if (o!=null) {
			return o.checked;
		} else {
			return false;
		}
	}
	
	this.SetValue=function(o,sBoolean) {
		o=f.SafeObject(o);
		if (o!=null) {
			if ((sBoolean+'').toLowerCase()=='false') {
				o.checked=false;
			} else {
				o.checked=true;
			}
		} else {
			return false;
		}	
	}
}



//dropdown functions
function DropdownFunctions() {

	this.GetText=function(o) {
        o=f.SafeObject(o);
        if (o!=null && o.options.length>0 && o.selectedIndex > -1) {
              return o.options[o.selectedIndex].text;
        } else {
              return '';
        }
	}

	this.GetIntText = function(o) {
		return n.SafeInt(dd.GetText(o));
	}


	this.GetValue = function(o) {
	    o = f.SafeObject(o);
	    if (o != null && o.selectedIndex >= 0) {
	        return o.options[o.selectedIndex].value;
	    } else {
	        return '';
	    }
	}

	this.GetIntValue = function(o) {
		return n.SafeInt(dd.GetValue(0));
	}
	
	this.GetIndex=function(o) {
		o=f.SafeObject(o);
		if (o!=null) {return o.selectedIndex;}
    }

    this.ListCount = function(o) {
        o = f.SafeObject(o);
        if (o != null) { return o.options.length; }
    }
    	
	this.SetIndex=function(o,iIndex) {
		o=f.SafeObject(o);
		if (o!=null) {o.selectedIndex=iIndex;}
	}
	
	this.SetValue=function(o,iValue) {
		o=f.SafeObject(o);
		if (o!=null && o.options) {
			for (var i=0;i<=o.options.length-1;i++) {
				if (o.options[i].value==iValue) {
					o.selectedIndex=i;
					break;
				}	
			}
		}
	}
	
	this.SetText=function(o,sText) {
		var o=f.SafeObject(o);
		if (o!=null) {
			for (var i=0;i<=o.options.length-1;i++) {
				if (o.options[i].text!=null) {
					if (o.options[i].text==sText) {
					    o.selectedIndex=i;
					    break;
				    }
				}	
			}
		}
	}
	
	this.Clear=function(o,sText) {
		var o=f.SafeObject(o);
		if (o!=null) {
			o.options.length=0;		
		}
	}
	
	this.AddOption=function(o,sText,iValue,sClass) {
		var o=f.SafeObject(o);
		if (o!=null) {
			o.options[o.length] = new Option(sText,iValue);
			if (sClass!=undefined) {
				o.options[o.length - 1].className=sClass;
			}
		}
	}
}

// checked data list
function CheckedDatalist(o) {

	this.List=f.SafeObject(o);

	this.HasCheckedItems=function() {
		
		var aCheckboxes=f.GetObjectsByIDPrefix(this.List.id+'chk');
		
		for (var i=0;i<aCheckboxes.length;i++) {
			if (f.SafeObject(aCheckboxes[i]).checked==true) {
				return true;
			}
		}
		
		return false;
		
	}

}

// validator
function Validator(oButton) {

	this.Validations=new Array();
	this.Button=f.SafeObject(oButton);

	
	this.AddValidation=function(Control, FieldName, ValidationType) {
		this.Validations[this.Validations.length]=['Custom',Control,FieldName,ValidationType];
	}

	this.AddCustomValidation=function(Condition, Control, Message) {
		this.Validations[this.Validations.length]=['Custom',Control, Message,'CustomValidation',Condition]
	}

	this.Validate = function(bShowWarnings) {
	    aValidation = this.Validations;

	    if (bShowWarnings == undefined) {
	        bShowWarnings = true;
	    }

	    if (this.Button) {
	        ClientValidation(this.Button, 'Custom', undefined, bShowWarnings);
	    } else {
	        return ClientValidation(null, 'Custom', undefined, bShowWarnings);
	    }
	}
}



//webservice
var oWebService=new WebService();
function WebService() {

	var oRequest, oResponseObject, bResponseTextOnly, oPopulateList, oHideDiv;

	//getlist 
	this.PopulateList=function(URL, sNamespace, oList, SourceSQL, oDiv) { 
	
		oHideDiv=oDiv;
		
		// get the data
		aParams=new Array(['SourceSQL',SourceSQL]);
		oPopulateList=f.SafeObject(oList);
		this.RunWebService(URL, sNamespace, 'GetList', aParams, oPopulateList);
	}

	this.FillList=function(oXML) {
	
	
		var bHasAll=iif(oPopulateList.options.length>0 && oPopulateList.options[0].text=='All', true, false);
		var iOffset=1;
		
		// clear the list
		dd.Clear(oPopulateList);
		
		//add all if required
		if (bHasAll) {
			oPopulateList[0]=new Option('All',-1);
		} else {
			oPopulateList[0]=new Option('',0);
		}
		
		var oListItems=oXML.getElementsByTagName('ListItem'); 
		var sLastGroup='alanpartridge';
		var sValue;
		var iID;
		for (var i=0;i<oListItems.length;i++) {
		
			sValue=this.GetNodeText(oListItems[i].childNodes[0]);
			iID=this.GetNodeText(oListItems[i].childNodes[1]);
			
			
			//if we're grouping 
			if (sValue.indexOf('~')>-1) {
				if (sValue.split('~')[0]!=sLastGroup) {
					oPopulateList[i+iOffset]=new Option(sValue.split('~')[0],0);
					oPopulateList.options[i+iOffset].className='dropdowngroup';
					iOffset+=1;
				}
				
				oPopulateList[i+iOffset] = new Option(sValue.split('~')[1], iID);
				sLastGroup=sValue.split('~')[0];
			} else {			
			
				oPopulateList[i+iOffset] = new Option(sValue,iID);
			}
		}
		
		if (oHideDiv!=undefined) {
			f.ShowIf(oHideDiv,oListItems.length > 0);
		}
	}
	

	//support functions
	this.GetTagValue=function(oLocalXML, sTag) {
		var aItems=oLocalXML.getElementsByTagName(sTag);
		if (aItems.length==1 && aItems[0].childNodes[0]) {
			if (aItems[0].textContent) {
				return aItems[0].textContent;
			} else {
				return aItems[0].childNodes[0].data;
			}
		} else {
			return '';
		}
	}	
	
	
	this.GetNodeText=function(oNode) {
		return oNode.text ? oNode.text : oNode.textContent;
	}
	
	this.SafeParam=function(sParam) {
		if (sParam.replace) {
			return sParam.replace(/&/g,'&amp;');
		} else {
			return sParam;
		}
	}	
	
	
	this.RunWebService=function(sUrl, sNamespace, sFunction, aParameters, oCallingObject, bTextOnly) {
		
		var sRequest=
			'<?xml version="1.0" encoding="utf-8"?>'+
			'<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '+
			'xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'+
			'<soap:Body>'+
			'	<'+sFunction+' xmlns="'+sNamespace+'">'
			
		for (var i=0;i<aParameters.length;i++) {
			sRequest=sRequest+'<'+aParameters[i][0]+'>'+
				this.SafeParam(aParameters[i][1])+'</'+aParameters[i][0]+'>';
		}
		
		sRequest=sRequest+'	</'+sFunction+'>'+'</soap:Body>'+'</soap:Envelope>';
		
		
		// branch for native XMLHttpRequest object
		if (window.XMLHttpRequest) {
			oRequest = new XMLHttpRequest();
			oRequest.open("POST", sUrl,true);
		} else {
			oRequest = new ActiveXObject("Microsoft.XMLHTTP");
			oRequest.open("POST", sUrl,true);	
		}
		
		oResponseObject=oCallingObject;
		bResponseTextOnly=bTextOnly==undefined ? false : bTextOnly;
		
		oRequest.onreadystatechange=function() {
			if (oRequest.readyState==4) {
			
			    if (oRequest.status!=200 && window.location.toString().indexOf('localhost')>-1) {
					alert(oRequest.responseText);
					return;
				}	
			
				if (oResponseObject==oPopulateList) {
					oWebService.FillList(oRequest.responseXML);
				} else if (bResponseTextOnly==false) {
					oResponseObject.Done(oRequest.responseXML); 
				} else {
					oResponseObject.Done(oRequest.responseText);
				}
			}
		}
		
		oRequest.setRequestHeader("Content-Type", "text/xml")
		oRequest.setRequestHeader("MessageType", "CALL")
		oRequest.setRequestHeader('SOAPAction',sNamespace+'/'+sFunction)
		oRequest.send(sRequest);
		
	}	
}	


function ListPopulater(oList) {
		
	var me=this;
	this.List=f.SafeObject(oList);
	this.Query=new WebService();
	this.SelectedID=0;
	
	this.Populate=function(sURL, sNamespace, sFunctionName, sSourceSQL, iSelectedID) {
		dd.Clear(me.List);
		aParams=new Array(['SourceSQL', sSourceSQL]);
		
		
		if (iSelectedID!=undefined) {
			me.SelectedID=iSelectedID;
		} else {
			me.SelectedID=0;
		}
		
		me.Query.RunWebService(sURL, sNamespace, sFunctionName, aParams, this.Query, false);
	}
	

	this.Query.Done=function(oXML) {
		var sOptions=me.Query.GetTagValue(oXML, 'BuildOptionsResult');
		
		dd.AddOption(me.List, '', 0);
		
		if (sOptions.length > 0) {
			var sLastGroup='Partridge';
			var aOptions=sOptions.split('#');
			for (var i=0;i<aOptions.length;i++) {	
					
				var aOption=aOptions[i].split('|');
				if (aOption[0].indexOf('~') > -1) {
					if (aOption[0].split('~')[0]!=sLastGroup) {
						dd.AddOption(me.List, aOption[0].split('~')[0], 0, 'dropdowngroup');	
					}
					dd.AddOption(me.List, aOption[0].split('~')[1], aOption[1]);
					sLastGroup=aOption[0].split('~')[0];				
				} else {
					dd.AddOption(me.List, aOption[0], aOption[1]);				
				}		
				
			}
		}
		
		if (me.SelectedID > 0) {
			dd.SetValue(me.List,me.SelectedID);
		}
		
		if (me.Populated) {
			me.Populated();
		}
	}
	
}




/* effects */
function Effects() {
		
	this.SetOpacity=function(o,iOpacity) {
		var oControl=f.SafeObject(o);
		oControl.style.opacity = iOpacity/100;		
		oControl.style.filter = 'alpha(opacity=' + iOpacity + ')';
	}



	this.SlideOpen=function(oObject, SlideTime, FinalHeight, EndTime) {
		
		oObject=f.SafeObject(oObject);
		SlideTime=SlideTime==undefined ? 0.75 : SlideTime;
		
		if (EndTime==undefined) {
			oObject.style.overflow='hidden';
			oObject.style.display='block';
			oObject.style.height='1px';
			oObject.style.height='auto';
			FinalHeight=oObject.scrollHeight;
			var dStart=new Date();
			EndTime=new Date(dStart.getTime()+(SlideTime*1000));
		} else {
			EndTime=new Date(EndTime);
		}
		
		if (new Date()<EndTime) {
			oObject.style.height=Math.round(Math.sin(Math.PI/2*(1-(EndTime-new Date())/1000/SlideTime))*FinalHeight)+'px'
			setTimeout('e.SlideOpen(\''+oObject.id+'\','+SlideTime+','+FinalHeight+',\''+EndTime+'\')',10);
		} else {
			oObject.style.height=FinalHeight+'px';
		}
	}
	
	this.SlideClose=function(oObject, SlideTime, FinalHeight, EndTime) {
		
		oObject=f.SafeObject(oObject);
		SlideTime=SlideTime==undefined ? 0.75 : SlideTime;
		
		if (EndTime==undefined) {
			FinalHeight=oObject.scrollHeight;
			var dStart=new Date();
			EndTime=new Date(dStart.getTime()+(SlideTime*1000));
		} else {
			EndTime=new Date(EndTime);
		}
		
		if (new Date()<EndTime) {
			oObject.style.height=Math.round(Math.sin(Math.PI/2*((EndTime-new Date())/1000/SlideTime))*FinalHeight)+'px'
			setTimeout('e.SlideClose(\''+oObject.id+'\','+SlideTime+','+FinalHeight+',\''+EndTime+'\')',10);
		} else {
			oObject.style.height=0;
			oObject.style.display='none';
		}
	}


	this.FadeOut=function(oObject, FadeTime, Opacity) {
		this.FadeOutObject=f.SafeObject(oObject);
		FadeTime=FadeTime==undefined ? 1 : FadeTime;
		this.FadeInterval=FadeTime/20*800;
		this.Opacity=Opacity==undefined ? 100 : Opacity;

		this.Opacity-=5;
			
		if (this.Opacity<0) {
			e.SetOpacity(this.FadeOutObject,0);
		} else {
			e.SetOpacity(this.FadeOutObject,this.Opacity);
			setTimeout('e.FadeOut(\''+this.FadeOutObject.id +'\','+FadeTime+','+this.Opacity+')',
				this.FadeInterval);
		}
	}
	
	this.FadeIn=function(oObject, FadeTime, Opacity) {
		this.FadeInObject=f.SafeObject(oObject);
		FadeTime=FadeTime==undefined ? 1 : FadeTime;
		this.FadeInterval=FadeTime/20*800;
		this.Opacity=Opacity==undefined ? 0 : Opacity;

		this.Opacity+=5;
			
		if (this.Opacity>100) {
			e.SetOpacity(this.FadeInObject,100);
		} else {
			e.SetOpacity(this.FadeInObject,this.Opacity);
			setTimeout('e.FadeIn(\''+this.FadeInObject.id +'\','+FadeTime+','+this.Opacity+')',
				this.FadeInterval);
		}
	}
	
	
	this.ImageRotator=function(IDBase, ItemCount, RotateTime, CurrentIndex) {

		if (ItemCount>1) {
			RotateTime = RotateTime == undefined ? 2 : parseInt(RotateTime);
			CurrentIndex = CurrentIndex == undefined ? 0 : CurrentIndex;

			if (CurrentIndex==0) {
			
				CurrentIndex=1;
				
			} else { 
				
				var oFadeOut=f.GetObject(IDBase+CurrentIndex);
				if (oFadeOut==null) {
					return false;
				}

				CurrentIndex+=1;
				CurrentIndex= CurrentIndex>ItemCount ? 1 : CurrentIndex;
			
				var oFadeIn=f.GetObject(IDBase+CurrentIndex);
			
				e.FadeOut(oFadeOut);
				e.FadeIn(oFadeIn);
			
			}

			setTimeout('e.ImageRotator(\''+IDBase+'\','+ItemCount+','+RotateTime+','+CurrentIndex+')', RotateTime*1000);
		}
		
	}	


	this.GetPosition=function(o) {
		var oControl=f.SafeObject(o);
		
		var s=oControl.id;
		
		var iLeft=0, iTop=0, iWidth, iHeight;
		iWidth=oControl.offsetWidth;
		iHeight=oControl.offsetHeight;
		
		if (oControl.offsetParent) {
			iLeft = oControl.offsetLeft;
			iTop = oControl.offsetTop;
			while (oControl = oControl.offsetParent) {
				iLeft += oControl.offsetLeft;
				iTop += oControl.offsetTop;
			}
		}

		return new this.Position(iLeft, iTop, iWidth, iHeight);
	}

	this.SetPosition=function(o,oPosition) {
		oControl=f.SafeObject(o);
		oControl.style.top=oPosition.Top+'px';
		oControl.style.left=oPosition.Left+'px';
		oControl.style.width=oPosition.Width+'px';
		if (oPosition.Height > 0) {
			oControl.style.height=oPosition.Height+'px';
		}
	}

	this.SetTopLeft = function(o, iTop, iLeft) {
	    oControl = f.SafeObject(o);
	    oControl.style.top = iTop + 'px';
	    oControl.style.left = iLeft + 'px';
	}
	
	this.Position=function(iLeft,iTop,iWidth,iHeight) {
		this.Left=iLeft;
		this.Top=iTop;
		this.Width=iWidth;
		this.Height=iHeight;
	}	


	this.BrowserDimensions=function() {
			

		var iXScroll, iYScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			iXScroll = window.innerWidth + window.scrollMaxX;
			iYScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight) { 
			iXScroll = document.body.scrollWidth;
			iYScroll = document.body.scrollHeight;
		} else { 
			iXScroll = document.body.offsetWidth;
			iYScroll = document.body.offsetHeight;
		}
		
		var iWindowWidth, iWindowHeight;
		
		if (self.innerHeight) {	
			if(document.documentElement.clientWidth){
				iWindowWidth = document.documentElement.clientWidth; 
			} else {
				iWindowWidth = self.innerWidth;
			}
			iWindowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			iWindowWidth = document.documentElement.clientWidth;
			iWindowHeight = document.documentElement.clientHeight;
		} else if (document.body) {
			iWindowWidth = document.body.clientWidth;
			iWindowHeight = document.body.clientHeight;
		}	
		
		var iPageHeight, iPageWidth
		var iPageHeight= iYScroll < iWindowHeight ? iWindowHeight : iYScroll;
		var iPageWidth= iXScroll < iWindowWidth ? iXScroll : iWindowWidth;
		
		
		this.ViewportWidth=iWindowWidth;
		this.ViewportHeight=iWindowHeight;
		this.PageWidth=iPageWidth;
		this.PageHeight=iPageHeight;
		this.PageScrollTop=iYScroll;
			
	}



	this.CreateOverlay=function() {
		
		var oOverlay = document.createElement('div');
		oOverlay.setAttribute('id','divOverlay');			
		document.body.appendChild(oOverlay);			
	
		var oDimensions=new e.BrowserDimensions();

		oOverlay.style.height=400+oDimensions.PageHeight+'px';
		oOverlay.style.width='100%';
		e.SetOpacity(oOverlay,60);
	}



	/* modal popup */
	this.ModalPopup=new function() {
		
		this.PopupDiv;
		this.EscapeEvent;	
	
		this.Show=function(oDiv) {
		
			this.PopupDiv = f.SafeObject(oDiv);
			
			e.CreateOverlay();
			f.Show(this.PopupDiv);
			
			var iControlWidth = this.PopupDiv.offsetWidth;
			var iControlHeight = this.PopupDiv.offsetHeight;
			
			var oDimensions=new e.BrowserDimensions();
			
			var iLeft=(oDimensions.ViewportWidth-iControlWidth)/2;
			var iTop=(oDimensions.ViewportHeight/4)-(iControlHeight/2);
			
			
			//set min top
			iTop=iTop < 50 ? 50 : iTop;
					
			this.PopupDiv.style.left=iLeft+'px';
			this.PopupDiv.style.top=iTop+'px';
			
			e.ModalPopup.EscapeEvent=f.AttachEvent(document, 'keypress', 
				function(oEvent) {
					if (f.GetKeyCodeFromEvent(oEvent)==27) {
						e.ModalPopup.Close();
					}
				});
		}
		
		
		this.Close=function() {
			if (f.Visible(e.ModalPopup.PopupDiv)) {				
				f.Hide(e.ModalPopup.PopupDiv);
				f.DetachEvent(e.ModalPopup.EscapeEvent);
				document.body.removeChild(f.GetObject('divOverlay'));	
			}
		}
	}	
}





/* datalist functions */
function DataListFunctions() {

	this.SetSelected=function(ListID, ID) {
		//work out the id prefix
		var oHolder=f.GetObject(ListID+'Scroll');
		var sBaseID=oHolder.childNodes[0].nodeName=='#text' ? oHolder.childNodes[1].id : oHolder.childNodes[0].id;
		
		var oRows=f.GetObjectsByIDPrefix(sBaseID,'tr');
		for (var i=0;i<oRows.length;i++) {
			f.SetClass(oRows[i], oRows[i].id==sBaseID+'_'+ID ? 'selected' : '');
		}
	}
}





/* cookie functions */
function CookieFunctions() {

      this.Set=function(sName,sValue,iDays) {
      
            var sExpires;
            if (iDays) {
                  var dDate = new Date();
                  dDate.setTime(dDate.getTime()+(iDays*24*60*60*1000));
                  sExpires = '; expires='+dDate.toGMTString();
            } else {
                  sExpires = '';
            } 
            document.cookie = sName+'='+sValue+sExpires+'; path=/';
      }

      this.Get=function(sName) {
            var sNameEQ = sName + '=';
            var aCookies = document.cookie.split(';');
            for(var i=0;i < aCookies.length;i++) {
                  var sCookie = aCookies[i];
                  while (sCookie.charAt(0)==' ') sCookie = sCookie.substring(1,sCookie.length);
                  if (sCookie.indexOf(sNameEQ) == 0) {
                        return sCookie.substring(sNameEQ.length,sCookie.length);
                  }
            }
            return '';
      }

      this.Delete=function(sName) {
            c.Set(sName,'',-1);
      }

}



//formfunctions
var ff = new function() {

	var me = this;

	/* safe param */
	this.SafeParam = function(sParam) {
		if (sParam.replace) {
			return sParam.replace(/&/g, '&amp;').replace(/\|/g, '/\\pipe\\/');
		} else if (sParam.getDate && sParam.getUTCFullYear && sParam.toDateString) { // attempt to find out whether sParam is a Date object
			return d.ToSQLDate(sParam);
		} else {
			return sParam;
		}
	}

	/* call */
	this.Call = function(FunctionName, CallBack) {

		//work out the params
		var sParams = '';
		for (var i = 2; i <= this.Call.arguments.length - 1; i++) {
			sParams += this.SafeParam(this.Call.arguments[i]) + '|'
		}
		if (sParams != '') { sParams = s.Chop(sParams); }

		//build up the url
		var sURL = window.location.href;
		if (s.Right(sURL, 1) == '#') {
			sURL = s.Chop(sURL);
		}
		sURL += '?executeformfunction';
		sURL += '&function=' + FunctionName;
		sURL += '&params=' + sParams;

		//request
		var oRequest;
		
		if (window.XMLHttpRequest) {
			oRequest = new XMLHttpRequest();
			oRequest.open("POST", sURL, true);
		} else {
			oRequest = new ActiveXObject("Microsoft.XMLHTTP");
			oRequest.open("POST", sURL, true);
		}

		oRequest.onreadystatechange = function() {
			if (oRequest.readyState == 4) {
				if (oRequest.status != 200 && window.location.toString().indexOf('localhost') > -1) {
					alert(oRequest.responseText);
					return;
				}
				ff.Response(oRequest.responseText, CallBack);
			}
		}

		oRequest.send();
	}



	/* response */
	this.Response = function(sResponse, oCallBack) {

		if (typeof (oCallBack) == 'string') {
			eval(oCallBack + '(\'' + s.Replace(sResponse, '\'', '\\\'') + '\')');
		} else if (typeof (oCallBack == 'function')) {
			oCallBack(sResponse);
		}
	}

}

