AddNamespace("DSS.Web");

DSS.Web.Toolkit = function()
    {
    var __self = this;
    
    var _oneMinute = 1000 * 60;
    
    var Intervals = new Object();
    Intervals["yyyy_ly"] = { units: 1000 * 60 * 60 * 24 * 366, measure: "year" };
    Intervals["yyyy"] = { units: 1000 * 60 * 60 * 24 * 365, measure: "year" };
    Intervals["M"] = { units: 1000 * 60 * 60 * 24 * 30.333, measure: "month" };
    Intervals["d"] = { units: 1000 * 60 * 60 * 24, measure: "day" };
    Intervals["h"] = { units: _oneMinute * 60, measure: "hour" };
    Intervals["m"] = { units: _oneMinute, measure: "minute" };
    Intervals["s"] = { units: 1000, measure: "second" };
    
    var GeneralFormats = [
        "y-M-d", "MMM d, y", "MMM d,y", "y-MMM-d", "d-MMM-y", "MMM d"];
    var MonthFirst = [
        "M/d/y", "M-d-y", "M.d.y", "MMM-d", "M/d", "M-d", "MMddyyyy", "MMddyy"];
    var DateFirst = [
        "d/M/y", "D-M-y", "d.M.y", "d-MMM", "d/M", "d-M", "ddMMyyyy", "ddMMyy"];
    
    this.FormatNumber = function(num, decimalNum, leadingZero, parens, commas)
        {
        if (isNaN(parseInt(num))) 
            {
            return "NaN";
            }

        var tmpNum = num;
        // Get sign of number
        var iSign = num < 0 ? -1 : 1; 

        // Adjust number so only the specified number of numbers after
        // the decimal point are shown.
        tmpNum *= Math.pow(10, decimalNum);
        tmpNum = Math.round(Math.abs(tmpNum))
        tmpNum /= Math.pow(10, decimalNum);
        // Readjust for sign
        tmpNum *= iSign;					

        // Create a string object to do our formatting on
        var tmpNumStr = new String(tmpNum);
        // apply formatting for whole numbers to add 0 after the decimal to the number specified
        if (tmpNumStr.indexOf(".") == -1)
            {
            tmpNumStr += ".";
            for (var i = 0; i < decimalNum; i++)
                {
                tmpNumStr += "0";
                }
            }
        else
            {
            var afterDec = tmpNumStr.split(".")[1];
            for (var i = afterDec.length; i < decimalNum; i++)
                {
                tmpNumStr += "0";
                }
            }

        // See if we need to strip out the leading zero or not.
        if (!leadingZero && num < 1 && num > -1 && num != 0)
            {
	        if (num > 0)
	            {
		        tmpNumStr = tmpNumStr.substring(1, tmpNumStr.length);
		        }
	        else
	            {
		        tmpNumStr = "-" + tmpNumStr.substring(2, tmpNumStr.length);
		        }
	        }
    	    
        // See if we need to put in the commas
        if (commas && (num >= 1000 || num <= -1000)) 
            {
	        var iStart = tmpNumStr.indexOf(".");
	        if (iStart < 0)
	            {
		        iStart = tmpNumStr.length;
		        }
	        iStart -= 3;
	        while (iStart >= 1) 
	            {
		        tmpNumStr = tmpNumStr.substring(0, iStart) + "," + tmpNumStr.substring(iStart, tmpNumStr.length)
		        iStart -= 3;
	            }
	        }

        // See if we need to use parenthesis
        if (parens && num < 0)
            {
	        tmpNumStr = "(" + tmpNumStr.substring(1, tmpNumStr.length) + ")";
	        }

        // Return our formatted string!
	    return tmpNumStr;		
        };
    this.DateAdd = function(interval, number, date)
        {

        var pDate = ToDate(date, true);
        if (pDate == null)
            {
            return date;
            }
        pDate.getTimezoneOffset() * _oneMinute;
        var pDateTime = pDate.getTime();
        
        if (!Intervals[interval])
            {
            return date;
            }
            
        var i = Intervals[interval].units * number;
        var newDateTime = pDateTime + parseInt(i);
        var newDate = new Date(newDateTime);
        return newDate;
        };
        
    this.DateDiff = function(interval, date1, date2)
        {
        var pDate1 = ToDate(date1, true);
        var pDate2 = ToDate(date2, true);
        
        if (pDate1 == null && pDate2 == null)
            {
            return -1;
            }
        if (pDate1 == null)
            {
            return -1;
            }
        if (pDate2 == null)
            {
            return -1;
            }
            
        var pDateTime1 = pDate1.getTime();
        var pDateTime2 = pDate2.getTime();
        
        var dstAdjust = 0;
        if (pDate2 > pDate1)
            {
            dstAdjust = (pDate2.getTimezoneOffset() - pDate1.getTimezoneOffset()) * _oneMinute;
            }
        else
            {
            dstAdjust = (pDate1.getTimezoneOffset() - pDate2.getTimezoneOffset()) * _oneMinute;
            }
            
        if (Intervals[interval])
            {
            if (!Intervals[interval].units)
                {
                alert("parameter [interval] is not valid.");
                return -1;
                }
                
            var diff = (pDateTime2 - pDateTime1) - dstAdjust;
            var timeDiff = Math.floor(diff / Intervals[interval].units);
            return parseInt(timeDiff);
            }
        return -1;
        };
        
    /// <summary>
    /// Formats a date into the given date format.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Formats a date into the given date format.
    /// </para>
    /// </remarks>
    this.FormatDate = function(date, format, useEuro)
        {
        var pDate = ToDate(date, useEuro);
        if (pDate == null)
            {
            return null;
            }
        var d = new Object();
        d.Year = pDate.getYear() + "";
        d.Month = pDate.getMonth() + 1;
        d.Date = pDate.getDate();
        d.Day = pDate.getDay();
        d.Hours = pDate.getHours();
        d.Minutes = pDate.getMinutes();
        d.Seconds = pDate.getSeconds();
        
        var v = new Object();
        if (d.Year.length < 4)
            {
            d.Year = "" + (d.Year - 0 + 1900);
            }
        v["y"] = "" + d.Year;
        v["yyyy"] = d.Year;
        v["yy"] = d.Year.substr(2, 4);
        v["M"] = d.Month;
        v["MM"] = this.PadLeft(d.Month, 2, "0");
        v["MMM"] = this.GetShortMonthName(d.Month - 1);
        v["MMMM"] = this.GetMonthName(d.Month - 1);
        v["d"] = d.Date;
        v["dd"] = this.PadLeft(d.Date, 2, "0");
        v["ddd"] = this.GetShortDayName(d.Day);
        v["dddd"] = this.GetDayName(d.Day);
        v["H"] = d.Hours;
        v["HH"] = this.PadLeft(d.Hours, 2, "0");
        if (d.Hours == 0)
            {
            v["h"] = 12;
            }
        else if (d.Hours > 12)
            {
            v["h"] = d.Hours - 12;
            }
        else
            {
            v["h"] = d.Hours;
            }
        v["hh"] = this.PadLeft(v["h"], 2, "0");
        if (d.Hour > 11)
            {
            v["a"] = "PM";
            }
        else
            {
            v["a"] = "AM";
            }
        v["m"] = d.Minutes;
        v["mm"] = this.PadLeft(v["m"], 2, "0");
        v["s"] = d.Seconds;
        v["ss"] = this.PadLeft(v["s"], 2, "0");
        
        var pos = 0;
        var ch = "";
        var token;
        var result = "";
        while (pos < format.length)
            {
            ch = format.charAt(pos);
            token = "";
            while ((format.charAt(pos) == ch) && (pos < format.length))
                {
                token += format.charAt(pos++);
                }
            if (v[token] != null)
                {
                result = result + v[token];
                }
            else
                {
                result = result + token;
                }
            }
        return result;
        };
        
    this.PadLeft = function(value, length, ch)
        {
        var str = "" + value;
        while (str.length < length)
            {
            if (ch)
                {
                str = ch + str;
                }
            else
                {
                str = " " + str;
                }
            }
        return str;
        };
        
    this.PadRight = function(value, length, ch)
        {
        var str = "" + value;
        while (str.length < length)
            {
            if (ch)
                {
                str = str + ch;
                }
            else
                {
                str = str + " ";
                }
            }
        return str;
        };
        
    /// <summary>
    /// Takes a date value and returns a Date object, the <paramref name="date"/> value
    /// can be a String, Number, or Date object, this method will parse the value passed
    /// in and return a Date object that represents the value of <paramref name="date"/>.
    /// </summary>
    function ToDate(date, useEuro)
        {
        var pDate = null;
        if (typeof(date) == "undefined")
            {
            return null;
            }
        if (typeof(date) == "string")
            {
            try
                {
                pDate = ParseDateString(date, useEuro);
                }
            catch (e)
                {
                return null;
                }
            }
        else if (typeof(date) == "number")
            {
            pDate = new Date(date);
            }
        else
            {
            pDate = date;
            }
        return pDate;
        };
        
    /// <summary>
    /// Parses a date string and returns a Date object. 
    /// </summary>
    /// <remarks>
    /// <para>
    /// The parsing is done based on the GMT date and time locale 
    /// which means a date string will be parsed as 'dd/MM/yyyy hh:mm:ss'.
    /// </para>
    /// This method will attempt to parse the date string by matching it
    /// to a number of different date time formats.
    /// </remarks>
    function ParseDateString(date, useEuro)
        {
        DSS.Web.Debug(false);
        var checkList = ["GeneralFormats", useEuro ? "DateFirst" : "MonthFirst", useEuro ? "MonthFirst" : "DateFirst"];
        var d = null;
        for (var i = 0; i < checkList.length; i++)
            {
            var item = eval(checkList[i]);
            for (var j = 0; j < item.length; j++)
                {
                d = GetDateFromFormat(date, item[j]);
                if (!isNaN(d))
                    {
                    return new Date(d);
                    }
                }
            }
        return null;
        };
        
    function GetDateFromFormat(date, format)
        {
        var pos = 0;
        var idx = 0;
        var ch = "";
        var token = "";
        var x, y;
        var internalDate = new Object();
        
        internalDate.Now = new Date();
        internalDate.Year = 1900;
        internalDate.Month = 1;
        internalDate.Date = 1;
        internalDate.Hours = 0;
        internalDate.Minutes = 0;
        internalDate.Seconds = 0;
        internalDate.AM = false;
        internalDate.PM = false;
        
        while (pos < format.length)
            {
            // get the next token from the string
            ch = format.charAt(pos);
            token = "";
            while ((format.charAt(pos) == ch) && (pos < format.length))
                {
                token += format.charAt(pos++);
                }
                
            // extract contents of value based on format token
            if (token == "yyyy" || token == "yy" || token == "y")
                {
                if (token == "yyyy")
                    {
                    x = 4;
                    y = 4;
                    }
                if (token == "yy")
                    {
                    x = 2;
                    y = 2;
                    }
                if (token == "y")
                    {
                    x = 2;
                    y = 4;
                    }
                internalDate.Year = _getInt(date, idx, x, y);
                if (internalDate.Year == null)
                    {
                    return NaN;
                    }
                idx += internalDate.Year.length;
                if (internalDate.Year.length == 2)
                    {
                    var _x = internalDate.Year % 100;
                    if (_x < 38)
                        {
                        internalDate.Year = 2000 + (internalDate.Year - 0);
                        }
                    else
                        {
                        internalDate.Year = 1900 + (internalDate.Year - 0);
                        }
                    }
                }
            else if (token == "MMMM" || token == "MMM")
                {
                internalDate.Month = 0;
                for (var i = 0; i < 12; i++)
                    {
                    var monthName = (token == "MMMM") ? __self.GetMonthName(i) : __self.GetShortMonthName(i);
                    if (date.substr(idx, idx + monthName.length).toLowerCase() == monthName.toLowerCase())
                        {
                        if (token == "MMMM" || token == "MMM")
                            {
                            internalDate.Month = i + 1;
                            if (internalDate.Month > 12)
                                {
                                internalDate.Month -= 12;
                                }
                            idx += monthName.length;
                            break;
                            }
                        }
                    }
                if ((internalDate.Month < 1) || (internalDate.Month > 12))
                    {
                    return NaN;
                    }
                }
            else if (token == "dddd" || token == "ddd")
                {
                for (var i = 0; i < 7; i++)
                    {
                    var dayName = (token == "dddd") ? __self.GetDayName(i) : __self.GetShortDayName(i);
                    if (date.substr(idx, idx + dayName.length).toLowerCase() == dayName.toLowerCase())
                        {
                        idx += dayName.length;
                        break;
                        }
                    }
                }
            else if (token == "MM" || token == "M")
                {
                internalDate.Month = _getInt(date, idx, token.length, 2);
                if (internalDate.Month == null || (internalDate.Month < 1) || (internalDate.Month > 12))
                    {
                    return NaN;
                    }
                idx += internalDate.Month.length;
                }
            else if (token == "dd" || token == "d") 
                {
			    internalDate.Date = _getInt(date, idx, token.length, 2);
			    if (internalDate.Date == null || (internalDate.Date < 1) || (internalDate.Date > 31))
			        {
			        return NaN;
			        }
			    idx += internalDate.Date.length;
			    }
            else if (token == "hh" || token == "h") 
                {
			    internalDate.Hour = _getInt(date, idx, token.length, 2);
			    if (internalDate.Hour == null || (internalDate.Hour < 1) || (internalDate.Hour > 12))
			        {
			        return NaN;
			        }
			    idx += internalDate.Hour.length;
			    }
		    else if (token=="HH"||token=="H") 
		        {
			    internalDate.Hour = _getInt(date, idx, token.length, 2);
			    if (internalDate.Hour == null || (internalDate.Hour < 0) || (internalDate.Hour > 23))
			        {
			        return NaN;
			        }
			    idx += internalDate.Hour.length;
			    }
		    else if (token == "mm" || token == "m") 
		        {
			    internalDate.Minute = _getInt(date, idx, token.length, 2);
			    if (internalDate.Minute == null || (internalDate.Minute < 0) || (internalDate.Minute > 59))
			        {
			        return NaN;
			        }
			    idx += internalDate.Minute.length;
			    }
		    else if (token == "ss" || token == "s") 
		        {
			    internalDate.Second = _getInt(date, idx, token.length, 2);
			    if (internalDate.Second == null || (internalDate.Second < 0) || (internalDate.Second > 59))
			        {
			        return NaN;
			        }
			    idx += internalDate.Second.length;
			    }
		    else if (token == "a") 
		        {
			    if (date.substring(idx, idx + 2).toLowerCase() == "am") 
			        {
			        internalDate.AM = true;
			        }
			    else if (date.substring(idx, idx + 2).toLowerCase() == "pm") 
			        {
			        internalDate.PM = true;
			        }
			    else 
			        {
			        return NaN;
			        }
			    idx += 2;
			    }
		    else 
		        {
			    if (date.substring(idx, idx + token.length) != token) 
			        {
			        return NaN;
			        }
			    else 
			        {
			        idx += token.length;
			        }
			    }
			}
			
		if (idx != date.length)
		    {
		    return NaN;
		    }
		    
		// is the date valid for the month
		internalDate.Month = internalDate.Month - 0;
		internalDate.Hours = internalDate.Hours - 0;
		if (internalDate.Month == 2)
		    {
		    if (__self.IsLeapYear(internalDate.Year))
		        {
		        if (internalDate.Date > 29)
		            {
		            return NaN;
		            }
		        }
	        else
	            {
	            if (internalDate.Date > 28)
	                {
	                return NaN;
	                }
	            }
		    }
		if ((internalDate.Month == 4) || (internalDate.Month == 6) || (internalDate.Month == 9) || (internalDate.Month == 11))
		    {
		    if (internalDate.Date > 30)
		        {
		        return NaN;
		        }
		    }
		    
		if (internalDate.Hours < 12 && internalDate.PM)
		    {
		    internalDate.Hours += 12;
		    }
		else if (internalDate.Hours > 11 && internalDate.AM)
		    {
		    internalDate.Hours -= 12;
		    }
		    
		var newDate = new Date(internalDate.Year, internalDate.Month - 1, internalDate.Date, internalDate.Hours, internalDate.Minutes, internalDate.Seconds);
		return newDate.getTime();
        };
        
    function _getInt(str, i, min, max)
        {
        for (var x = max; x >= min; x--)
            {
            var token = str.substring(i, i + x);
            if (token.length < min)
                {
                return null;
                }
            if (_isInteger(token))
                {
                return token;
                }
            }
        return null;
        };
        
    function _isInteger(val)
        {
        var digits = "1234567890"
        for (var i = 0; i < val.length; i++)
            {
            if (digits.indexOf(val.charAt(i)) == -1)
                {
                return false;
                }
            }
        return true;
        };
        
    /// <summary>
    /// Gets the index position of <paramref name="elt"/> in the
    /// <paramref name="array"/>.
    /// </summary>
    this.IndexOfItem = function(array, elt)
        {
        for (var i = 0; i < array.length; i++)
            {
            if (array[i] == elt)
                {
                return i;
                }
            }
        return -1;
        };
        
    /// <summary>
    /// Gets the full name of the day specified in <paramref cref="date"/>.
    /// </summary>
    /// <seealso cref="GetShortDayName"/>
    this.GetDayName = function(date)
        {
        if (typeof(date) == "number")
            {
            switch (date)
                {
                case 0:
                    return "Sunday";
                case 1:
                    return "Monday";
                case 2:
                    return "Tuesday";
                case 3:
                    return "Wednesday";
                case 4:
                    return "Thursday";
                case 5:
                    return "Friday";
                case 6:
                    return "Saturday";
                }
            }
        else
            {
            switch (date.getDay())
                {
                case 0:
                    return "Sunday";
                case 1:
                    return "Monday";
                case 2:
                    return "Tuesday";
                case 3:
                    return "Wednesday";
                case 4:
                    return "Thursday";
                case 5:
                    return "Friday";
                case 6:
                    return "Saturday";
                }
            }
        };
        
    /// <summary>
    /// Gets the short abbreviated day name of the day specified in <paramref cref="date"/>.
    /// </summary>
    /// <seealso cref="GetDayName"/>
    this.GetShortDayName = function(date)
        {
        return this.GetDayName(date).substring(0, 2);
        };
        
    /// <summary>
    /// Gets the full name of the month specified in <paramref cref="date"/>
    /// </summary>
    /// <seealso cref="GetMonthName"/>
    this.GetMonthName = function(date)
        {
        if (typeof(date) == "number")
            {
            switch (date)
                {
                case 0:
                    return "January";
                case 1:
                    return "February";
                case 2:
                    return "March";
                case 3:
                    return "April";
                case 4:
                    return "May";
                case 5:
                    return "June";
                case 6:
                    return "July";
                case 7:
                    return "August";
                case 8:
                    return "September";
                case 9:
                    return "October";
                case 10:
                    return "November";
                case 11:
                    return "December";
                }
            }
        else
            {
            switch (date.getMonth())
                {
                case 0:
                    return "January";
                case 1:
                    return "February";
                case 2:
                    return "March";
                case 3:
                    return "April";
                case 4:
                    return "May";
                case 5:
                    return "June";
                case 6:
                    return "July";
                case 7:
                    return "August";
                case 8:
                    return "September";
                case 9:
                    return "October";
                case 10:
                    return "November";
                case 11:
                    return "December";
                }
            }
        };
        
    this.GetShortMonthName = function(date)
        {
        return this.GetMonthName(date).substring(0, 3);
        };
        
    this.IsLeapYear = function(date)
        {
        var inYear;
        if (typeof(date) == "number" || typeof(date) == "string")
            {
            inYear = date;
            if (inYear % 4 == 0)
                {
                if (inYear % 100 == 0)
                    {
                    return (inYear % 400 == 0);
                    }
                else
                    {
                    return true;
                    }
                }
            return false;
            }
        else
            {
            inYear = date.getFullYear();
            if (inYear % 4 == 0)
                {
                if (inYear % 100 == 0)
                    {
                    return (inYear % 400 == 0);
                    }
                else
                    {
                    return true;
                    }
                }
            return false;
            }
        };
        
    this.GetMonthDays = function(date)
        {
        switch (date.getMonth())
            {
            case 0:
            case 2:
            case 4:
            case 6:
            case 7:
            case 9:
            case 11:
                return 31;
            case 1:
                if (this.IsLeapYear(date))
                    {
                    return 29;
                    }
                return 28;
            case 3:
            case 5:
            case 8:
            case 10:
                return 30;
            }
        };
        
    this.PixelToPercentage = function(pixel, baseWidth)
        {
        return (100 / baseWidth) * pixel;
        };
        
    this.PercentageToPixel = function(percent, baseWidth)
        {
        return (baseWidth / 100) * percent;
        };
        
    this.GetWeekInYear = function(date)
        {
        x = date.getYear();
        var y = x % 100;
        y += (y < 38) ? 2000 : 1900;
        
        Year = y;
        Month = date.getMonth();
        Day = date.getDate();
        
        now = Date.UTC(Year, Month, Day + 1, 0, 0, 0);
        
        var FirstDay = new Date();
        FirstDay.setYear(Year);
        FirstDay.setMonth(0);
        FirstDay.setDate(1);
        then = Date.UTC(Year, 0, 1, 0, 0, 0);
        
        var compensation = FirstDay.getDay();
        if (compensation > 3)
            {
            compensation -=4;
            }
        else
            {
            compensation += 3;
            }
            
        return Math.round((((now - then) / 86400000) + compensation) / 7);
        };
        
    function takeYear(date)
        {
        x = date.getYear();
        var y = x % 100;
        x += (y < 38) ? 2000 : 1900;
        return y;
        };
        
    this.GetMouseXY = function(evt)
        {
        DSS.Web.Debug(false);
        e = evt || window.event;
        
        if (!e)
            {
            return null;
            }
            
        var coords = new Object();
        if (document.layers)
            {
            coords.PosX = e.pageX;
            coords.PosY = e.pageY;
            }
        else if (window.opera)
            {
            coords.PosX = e.clientX;
            coords.PosY = e.clientY;
            }
        else if (document.all)
            {
            coords.PosX = (e.clientX + document.body.scrollLeft);
            coords.PosY = (e.clientY + document.body.scrollTop);
            }
        else if (document.getElementById)
            {
            coords.PosX = e.pageX;
            coords.PosY = e.pageY;
            }
        return coords;
        };
        
    this.CopyArrayItems = function(arr, startItem)
        {
        var i = (startItem = null) ? 0 : startItem;
        var res = new Array();
        
        for (; i < arr.length; i++)
            {
            res.push(arr[i]);
            }
        return res;
        };
        
    this.GetPosX = function(obj)
        {
        var curLeft = 0;
        if (obj.offsetParent)
            {
            while (obj.offsetParent)
                {
                curLeft += obj.offsetLeft;
                obj = obj.offsetParent;
                }
            }
        else if (obj.x)
            {
            curLeft += obj.x;
            }
        return curLeft;
        };
        
    this.GetPosY = function(obj)
        {
        var curTop = 0;
        if (obj.offsetParent)
            {
            while (obj.offsetParent)
                {
                curTop += obj.offsetTop;
                obj = obj.offsetParent;
                }
            }
        else if (obj.y)
            {
            curTop += obj.y;
            }
        return curTop;
        };
        
    /// <summary>
    /// Creates a 'shim', a transparent IFrame that can be used for overlaying IE windowed controls.
    /// </summary>
    this.CreateShim = function(shimid)
        {
        var tempDiv = document.createElement("div");
        
        tempDiv.innerHTML = "<iframe id=\"" + shimid + "\" scrolling=\"no\" frameborder=\"0\" style=\"position: absolute; _top: 0px; _left: 0px; display: none\">";
        document.body.appendChild(tempDiv);
        
        var shim = document.getElementById(shimid);
        shim.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0, opacity=0)";
        document.body.removeChild(tempDiv);
        return shim;
        };
            
    this.GetElementPosition = function(obj)
        {
        var res = new Object();
        res.PosX = this.GetPosX(obj);
        res.PosY = this.GetPosY(obj);
        return res;
        };
        
    //#region Event Handling Methods
    this.AddEvent = function(eventTarget, eventType, dest, capture)
        {
        var capt = (capture == null) ? false : capture;
        
        if (eventTarget.attachEvent)
            {
            eventTarget.attachEvent("on" + eventType, dest);
            }
        else if (eventTarget.addEventListener)
            {
            eventTarget.addEventListener(eventType, dest, capt);
            }
        else if (typeof(eventTarget[eventType]) == "function")
            {
            var old = eventTarget[eventType];
            eventTarget[eventType] = function(e)
                {
                old(e); dest(e);
                };
            }
        else
            {
            eventTarget[eventType] = dest;
            }
        EventCache.add(eventTarget, eventType, dest, capt);
        };
        
    this.RemoveEvent = function(eventTarget, eventType, dest, capture)
        {
        var capt = (capture == null) ? false : capture;
        
        EventCache.remove(eventTarget, eventType, dest, capt);
        
        if (eventTarget.removeEventListener)
            {
            eventTarget.removeEventListener(eventTarget, dest, capt);
            return true;
            }
        else if (eventTarget.detachEvent)
            {
            var r = eventTarget.detachEvent("on" + eventType, dest);
            return r;
            }
        return false;
        };
        
    this.AddLoadEvent = function(func)
        {
        var oldonload = window.onload;
        if (typeof(window.onload) != "function")
            {
            window.onload = func;
            }
        else
            {
            window.onload = function()
                {
                oldonload();
                func();
                };
            }
        };
        
    this.GetEvent = function(ev)
        {
        if (!event)
            {
            event = window.event;
            }
            
        if (event.target)
            {
            if (event.target.nodeType == 3)
                {
                event.target = event.target.parentNode;
                }
            }
        else if (event.srcElement)
            {
            event.target = event.srcElement;
            }
        return event;
        }
        
    /// <summary>
    /// Make window.event behave similar to the W3C Event object
    /// Curretnly fixing the target Attribute.
    /// </summary>
    /// <remarks>
    /// <example>
    /// Use in Event handlers like:
    /// function OnEvent(e)
    ///     {
    ///     e = new DSS.Web.Toolkit().FixEvent(e);
    ///     var targetElem = e.target;
    ///     ...
    ///     }
    /// </example>
    /// </remarks>
    this.FixEvent = function(e)
        {
        var ev;
        if (this.GetBrowser() == "IE")
            {
            ev = window.event;
            ev.target = window.event.srcElement;
            ev.relatedTarget = window.event.fromElement;
            ev.relatedTarget = window.event.toElement;
            ev.stopPropogation = function()
                {
                cancelBubble = true;
                }
            }
        else
            {
            ev = e;
            if (e.target)
                {
                if (e.target.nodeType == 3)
                    {
                    e.target = e.target.parentNode;
                    }
                }
            }
        return ev;
        };
    //#endregion

    this.GetBrowser = function()
        {
        var agt = navigator.userAgent.toLowerCase();
	    if (agt.indexOf("opera") != -1)
	        {
	        return 'Opera';
	        }
	    if (agt.indexOf("staroffice") != -1)
	        {
	        return 'Star Office';
	        }
	    if (agt.indexOf("beonex") != -1)
	        {
	        return 'Beonex';
	        }
	    if (agt.indexOf("chimera") != -1)
            {
            return 'Chimera';
            }
	    if (agt.indexOf("netpositive") != -1)
	        {
	        return 'NetPositive';
	        }
	    if (agt.indexOf("phoenix") != -1)
	        {
	        return 'Phoenix';
	        }
	    if (agt.indexOf("firefox") != -1)
	        {
	        return 'Firefox';
	        }
	    if (agt.indexOf("safari") != -1)
	        {
	        return 'Safari';
	        }
	    if (agt.indexOf("skipstone") != -1)
	        {
	        return 'SkipStone';
	        }
	    if (agt.indexOf("msie") != -1)
	        {
	        return 'IE';
	        }
	    if (agt.indexOf("netscape") != -1)
	        {
	        return 'Netscape';
	        }
	    if (agt.indexOf("mozilla/5.0") != -1)
	        {
	        return 'Mozilla';
	        }
	    if (agt.indexOf('\/') != -1)
	        {
    	    if (agt.substr(0,agt.indexOf('\/')) != 'mozilla')
    	        {
	            return navigator.userAgent.substr(0,agt.indexOf('\/'));
	            }
	        else
	            {
	            return 'Netscape';
	            }
	        }
	    else if (agt.indexOf(' ') != -1)
	        {
	        return navigator.userAgent.substr(0,agt.indexOf(' '));
	        }
	    else
	        {
	        return navigator.userAgent;
	        }
        };
        
    this.Encode64 = function (input)
        {
	    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        do 
            {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) 
                {
                enc3 = enc4 = 64;
                } 
            else if (isNaN(chr3)) 
                {
                enc4 = 64;
                }
            output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
            } while (i < input.length);
        return output;
        };

    this.Decode64 = function(input) 
        {
        var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
       
        // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        do 
            {
            enc1 = keyStr.indexOf(input.charAt(i++));
            enc2 = keyStr.indexOf(input.charAt(i++));
            enc3 = keyStr.indexOf(input.charAt(i++));
            enc4 = keyStr.indexOf(input.charAt(i++));

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output = output + String.fromCharCode(chr1);

            if (enc3 != 64) 
                {
                output = output + String.fromCharCode(chr2);
                }
            if (enc4 != 64) 
                {
                output = output + String.fromCharCode(chr3);
                }
            } while (i < input.length);
        return output;
        };

    this.AddOption = function(selectElem, text, value, className, backgroundColor, color)  
        {
	    var opt = document.createElement("option");
	    opt.value = value;
	    opt.selected = true;
	    if (className)
	        {
	        opt.className = className;
	        }
	    if (backgroundColor)
	        {
	        opt.style.backgroundColor = backgroundColor;
	        }
	    opt.style.color = "#003366";
	    if (color)
	        {
	        opt.style.color = color;
	        }
	    opt.text = text;
	    selectElem.add(opt);
        };

    this.GetElement = function(event)
        {
        if (!event)
            {
            return null;
            }
        if (event.srcElement)
            {
            return event.srcElement;
            }
        try
            {
            return (event.target && event.target.nodeType == 3) ? event.target.parentNode : event.target;
            }
        catch (ex)
            {
            return event.target;
            }
        };
        
    this.GetToElement = function(event)
        {
        if (!event)
            {
            return null;
            }
        if (event.toElement)
            {
            return event.toElement;
            }
		try 
		    {
			return (event.relatedTarget && event.relatedTarget.nodeType == 3) ? event.relatedTarget.parentNode : event.relatedTarget;
			}
		catch(e)
		    {
			return event.relatedTarget;
		    }
        };
        
    this.SetReturnValue = function(event, value)
        {
        event.returnValue = value;
        try
            {
		    if (!value) 
		        {
		        event.preventDefault();
		        }
		    }
		catch (ex)
		    {
		    }
        };
        
    this.GetElementAttribute = function(elt, name, bParent)
        {
        if (bParent)
            {
            if (elt.parentElement)
                {
                elt = elt.parentElement;
                }
            else
                {
                elt = elt.parentNode;
                }
            }
        return elt.getAttribute(name);
        };
    
    this.ClearSelect = function (object){
		for (var i=(object.options.length-1); i>=0; i--) { 
			object.options[i] = null; 
		} 
		object.selectedIndex = -1; 
     };
   };
window.DSS_Web_Toolkit__loaded = true;