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 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.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.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;
                }
            }
        }

        // add one to the datediff as this is an inclusive function
        iDiff += 1;

        // 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, oContainer) {

        if (oContainer == undefined) {
            oContainer = document;
        } else {
            oContainer = f.GetObject(oContainer);
        }

        var aObjects = new Array();

        if (sTagName == undefined) {
            sTagName = 'input';
        }

        var aElements = oContainer.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.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.GetElementsByClassName = function(sElement, sClassName, oContainer) {

        if (oContainer == undefined) {
            oContainer = document;
        } else {
            oContainer = f.GetObject(oContainer);
        }

        var aElements = oContainer.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++) {
            sList += '<li>' + aListItems[i] + '</li>';
        }
        sList += '</ul>';
        return sList;
    }

    this.ShowPopup = function(oObject, sClassName, sHTML, sSourceObjectID) {

        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
        oLinkPosition = e.GetPosition(oObject);
        oHelp.style.top = n.SafeInt(oLinkPosition.Top + 20) + 'px';
        oHelp.style.left = n.SafeInt(oLinkPosition.Left + 20) + 'px';

        //create mask
        if (navigator.appVersion.indexOf('MSIE 6') > 0) {
            var oMask = document.createElement('iframe');
            oMask.setAttribute('id', 'iMask');
            oMask.style.position = 'absolute';
            oMask.src = '';
            f.GetObject('frm').appendChild(oMask);
        }

        f.GetObject('frm').appendChild(oHelp);

        //show mask
        if (f.GetObject('iMask')) { e.SetPosition(oMask, e.GetPosition(oHelp)); }


    }


    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'));
        }
    }


    /* 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.GetMouseCoordsFromEvent = function(oEvent) {

        if (oEvent.pageX || oEvent.pageY) {
            return { Left: oEvent.pageX, Top: oEvent.pageY };
        } else {
            return {
                Left: oEvent.clientX + document.body.scrollLeft - document.body.clientLeft,
                Top: oEvent.clientY + document.body.scrollTop - document.body.clientTop
            };
        }
    }


    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.GetContainerQueryString = function(oContainer) {

        var aElements = f.GetObject(oContainer).getElementsByTagName('*');

        var sQueryString = '';
        for (var i = 0; i < aElements.length; i++) {
            if (aElements[i].name) {
                sQueryString += (sQueryString == '' ? '' : '&') + aElements[i].name + '='

                if (aElements[i].nodeName == 'INPUT' && s.StartsWith(aElements[i].id, 'chk')) {
                    sQueryString += cb.Checked(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);
        return iif(o != null, o.checked, false);
    }
}



//dropdown functions
function DropdownFunctions() {

    this.GetText = function(o) {
        o = f.SafeObject(o);
        if (o == null) { return ''; }
        if (o.selectedIndex < 0) { return ''; }
        return o.options[o.selectedIndex].text;
    }

    this.GetValue = function(o) {
        o = f.SafeObject(o);
        if (o == null) { return ''; }
        if (o.selectedIndex < 0) { return ''; }
        return o.options[o.selectedIndex].value;
    }

    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) {
            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; i++) {

                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() {
        aValidation = this.Validations;
        ClientValidation(this.Button, 'Custom');
    }
}



//formfunctions
var ff = new function() {

    var me = this;

    /* 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.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);
        }
    }

}







//webservice
var oWebService = new WebService();
function WebService() {

    var oRequest, oResponseObject, bResponseTextOnly, oPopulateList;

    //getlist 
    this.PopulateList = function(URL, sNamespace, oList, SourceSQL) {

        // get the data
        aParams = new Array(['SourceSQL', SourceSQL]);
        oPopulateList = f.SafeObject(oList);
        this.RunWebService(URL, sNamespace, 'GetList', aParams, oPopulateList);
    }

    this.FillList = function(oXML) {

        var sValue = dd.GetValue(oPopulateList);
        var bHasAll = iif(oPopulateList.options.length > 0 && oPopulateList.options[0].text == 'All', true, false);
        var iOffsetForAll = 0;

        // clear the list
        dd.Clear(oPopulateList);

        //add all if required
        if (bHasAll) {
            oPopulateList[0] = new Option('All', -1);
            iOffsetForAll = 1;
        }

        var oListItems = oXML.getElementsByTagName('ListItem');
        for (var i = 0; i < oListItems.length; i++) {
            oPopulateList[i + iOffsetForAll] = new Option(this.GetNodeText(oListItems[i].childNodes[0]),
				this.GetNodeText(oListItems[i].childNodes[1]));
        }

        if (sValue != '') {
            dd.SetValue(oPopulateList, sValue);
        }

        if (!bHasAll && oPopulateList.options.length == 2) {
            dd.SetIndex(oPopulateList, 1);
        }

        if (oPopulateList.onchange) {
            oPopulateList.onchange();
        }

    }


    //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);

    }
}



/* 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.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;
                var oFirst = f.GetObject(IDBase + CurrentIndex);
                oFirst.style.zIndex = 50;

            } else {

                var oFadeOut = f.GetObject(IDBase + CurrentIndex);

                CurrentIndex += 1;
                CurrentIndex = CurrentIndex > ItemCount ? 1 : CurrentIndex;

                var oFadeIn = f.GetObject(IDBase + CurrentIndex);

                e.FadeOut(oFadeOut);
                e.FadeIn(oFadeIn);
                oFadeOut.style.zIndex = 0;
                oFadeIn.style.zIndex = 50;
            }

            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 > 0 ? oControl.offsetLeft : 0;
                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';
        oControl.style.height = oPosition.Height + 'px';
    }


    this.Position = function(iLeft, iTop, iWidth, iHeight) {
        this.Left = iLeft;
        this.Top = iTop;
        this.Width = iWidth;
        this.Height = iHeight;
    }


    this.HitTest = function(oPosition, iLeft, iTop) {

        return iLeft >= oPosition.Left && iLeft <= (oPosition.Left + oPosition.Width)
			&& iTop >= oPosition.Top && iTop <= (oPosition.Top + oPosition.Height);

    }


    this.BrowserDimensions = function() {


        var iXScroll, iYScroll, iXScrollPos, iYScrollPos;

        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;
        }

        if (window.pageYOffset && window.pageXOffset) {
            iXScrollPos = window.pageXOffset
            iYScrollPos = window.pageYOffset
        } else if (document.documentElement) {
            iXScrollPos = document.documentElement.scrollLeft;
            iYScrollPos = document.documentElement.scrollTop;
        } else {
            iXScrollPos = document.body.scrollLeft;
            iYScrollPos = document.body.scrollTop;
        }

        if (window.pageYOffset) {
            iYScrollPos = window.pageYOffset
        } else if (document.documentElement) {
            iYScrollPos = document.documentElement.scrollTop;
        } else {
            iYScrollPos = document.body.scrollTop;
        }

        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.ScrollYPos = iYScrollPos;
        this.ScrollXPos = iXScrollPos;
    }

    this.CreateOverlay = function() {

        var oOverlay = document.createElement('div');
        oOverlay.setAttribute('id', 'divOverlay');
        document.body.appendChild(oOverlay);

        var oDimensions = new e.BrowserDimensions();
        oOverlay.style.height = oDimensions.PageHeight + 'px';
        oOverlay.style.left = oDimensions.ScrollXPos + 'px';
        oOverlay.style.width = '100%';
        e.SetOpacity(oOverlay, 60);
    }


    //if ie6, hide/show the dropdowns!
    var ToggleDropdownVisibility = new function() {

        //hide
        this.Hide = function() {
            if (navigator.appName == 'Microsoft Internet Explorer' && parseFloat(navigator.appVersion.split('MSIE')[1]) < 7) {
                var aSelect = document.getElementsByTagName('select');
                for (var i = 0; i < aSelect.length; i++) {
                    aSelect[i].style.visibility = 'hidden';

                }
            }
        }


        //show
        this.Show = function() {
            if (navigator.appName == 'Microsoft Internet Explorer' && parseFloat(navigator.appVersion.split('MSIE')[1]) < 7) {
                var aSelect = document.getElementsByTagName('select');
                for (var i = 0; i < aSelect.length; i++) {
                    aSelect[i].style.visibility = 'visible';

                }
            }
        }


    }

    /* modal popup */
    this.ModalPopup = new function() {

        this.PopupDiv;
        this.EscapeEvent;

        this.Show = function(oDiv) {
            e.ModalPopup.Close();
            ToggleDropdownVisibility.Hide();
            this.PopupDiv = f.SafeObject(oDiv);

            e.CreateOverlay();
            f.Show(this.PopupDiv);
            this.UpdateScreenPosition();

            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'));
                ToggleDropdownVisibility.Show();
            }
        }


        this.UpdateScreenPosition = function() {

            var iControlWidth = this.PopupDiv.offsetWidth;
            var iControlHeight = this.PopupDiv.offsetHeight;

            var oDimensions = new e.BrowserDimensions();
            var iLeft = (oDimensions.ViewportWidth - iControlWidth) / 2 + oDimensions.ScrollXPos;
            var iTop = ((oDimensions.ViewportHeight) / 3) - (iControlHeight / 2);

            //set min top
            iTop = iTop < 50 ? 50 : iTop;
            iTop += oDimensions.ScrollYPos;

            this.PopupDiv.style.left = iLeft + 'px';
            this.PopupDiv.style.top = iTop + 'px';


            this.CheckOverlayIsTallEnough();
        }


        this.CheckOverlayIsTallEnough = function() {

            var oOverlay = f.GetObject('divOverlay');
            var oDimensions = new e.BrowserDimensions();
            var iPopupBottom = this.PopupDiv.offsetTop + this.PopupDiv.offsetHeight;

            if (iPopupBottom + 20 > oDimensions.PageHeight) {
                oOverlay.style.height = iPopupBottom + 20 + 'px';
            }

        }

    }
}


/* 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);
    }

}

