Object.extend = function(destination, source) 
{
    for (property in source) destination[property] = source[property];
    return destination;
}

Freedom = new oFreedom();

function oFreedom() {}
Object.extend(oFreedom.prototype, 
{
    Ajax: new oAjax(),
    Xml: new oXml(),
	Popup: new oPopup,
	UserAgent: new oUserAgent,
	Opacity: new oOpacity
});

function oAjax() {}
Object.extend(oAjax.prototype,
{
    Version: '1.0',
    XMLHTTP_ActiveX: '',
    Method: 'GET',
    URL: '/ServerRequest.ashx',
    Data: '',
    Async: true,
    DoSend: true,
    Process: null,

    Get: function(assembly, object, action, params, clientID)
    {
        this.ShowMessage();
        this.SendRequest(assembly, object, action, params, clientID);
    },

    Post: function(formName, assembly, object, action, params, clientID)
    {
        this.ShowMessage();
        this.Method = 'POST';
        this.Data = getFormValues(formName);
        this.SendRequest(assembly, object, action, params, clientID);
    },

    SendRequest: function(assembly, object, action, params, clientID)
    {
        var self = this;

        self.ShowProgressBar(false);
        if (self.Process == null) self.Process = self.DisplayResponse;

        self.XmlHttp = this.GetXmlHttp();
        self.XmlHttp.onreadystatechange = function()
        {
            if (self.XmlHttp.readyState == 4)
            {
                if (self.XmlHttp.status == 200)
                {
                    //debugWindow(self.XmlHttp.responseText);
                    self.ProcessResponse(self.XmlHttp.responseText, self.Process);
                }
                else
                {
                    debugWindow(self.XmlHttp.responseText);
                }
                self.ShowProgressBar(true);
            }
        }

        var requestUrl = this.URL + "?assembly=" + assembly + "&class=" + object + "&method=" + action + '&clientid=' + clientID;
        if (!isUndefined(params)) requestUrl += "&params=" + params.join();

        this.Method = this.Method.toUpperCase();
        self.XmlHttp.open(this.Method, requestUrl, this.Async);

        if (this.Method == "POST")
        {
            self.XmlHttp.setRequestHeader("Connection", "close");
            self.XmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            self.XmlHttp.setRequestHeader("Method", "POST " + this.URL + "HTTP/1.1");
        }

        // false to set special request headers
        if (this.DoSend == true) self.XmlHttp.send(this.Data);
    },

    ProcessResponse: function(responseText, process)
    {
        if (responseText)
        {
            //alert(responseText);
            var xmlDoc = Freedom.Xml.Load(responseText);

            if (xmlDoc.documentElement.nodeName == "error")
                debugWindow(responseText);
            else
            {
                var xmlResponses = xmlDoc.documentElement.selectNodes("response");
                for (nIndex = 0; nIndex < xmlResponses.length; nIndex++)
                {
                    this.target = "";
                    this.type = "";
                    this.title = "";
                    this.content = "";
                    this.fade = 0;

                    for (i = 0; i < xmlResponses[nIndex].childNodes.length; i++)
                    {
                        this[xmlResponses[nIndex].childNodes[i].nodeName] = Freedom.Xml.GetXml(xmlResponses[nIndex].childNodes[i]);
                    }

                    process(this);
                }
            }
        }
    },

    DisplayResponse: function(oResponse)
    {
        //alert(oResponse.target + "|" + oResponse.type + "|" + oResponse.content);

        //Freedom.Ajax.ShowPopup();
        if (oResponse.fade > 0) Freedom.Opacity.Hide(oResponse.target);
        
        switch (oResponse.type)
        {
            case "value":
                $(oResponse.target).value = htmlEntityDecode(oResponse.content);
                break;

            case "defaultvalue":
                if ($(oResponse.target).value == "")
                    $(oResponse.target).value = htmlEntityDecode(oResponse.content);
                break;

            case "display":
                $(oResponse.target).style.display = oResponse.content;
                break;

            case "checked":
                $(oResponse.target).checked = oResponse.content;
                break;

            case "options":
                if (document.all)
                {
                    $(oResponse.target).innerHTML = "<option>.</option>" + oResponse.content; //fix for browsers that truncate first item (mostly opera)
                    $(oResponse.target).outerHTML = $(oResponse.target).outerHTML;
                }
                else
                    $(oResponse.target).innerHTML = oResponse.content;
                break;

            case "script":
                eval(oResponse.content);
                break;

            case "popup":
                Freedom.Popup.Open(oResponse.content, oResponse.title, oResponse.width, oResponse.height);
                runScripts(oResponse.content)
                break;

            case "append":
                $(oResponse.target).innerHTML += htmlEntityDecode(oResponse.content);
                runScripts(oResponse.content)
                break;

            default:
                $(oResponse.target).innerHTML = htmlEntityDecode(oResponse.content);
                runScripts(oResponse.content)
                break;
        }

        if (oResponse.fade > 0) Freedom.Opacity.FadeIn(oResponse.target, oResponse.fade);
    },

    GetXmlHttp: function()
    {
        var xmlHttp;
        if (window.XMLHttpRequest)
        { // Not IE
            xmlHttp = new XMLHttpRequest();
        }
        else if (window.ActiveXObject)
        { // IE!
            if (this.XMLHTTP_ActiveX)
            {
                xmlHttp = new ActiveXObject(this.XMLHTTP_ActiveX);
            }
            else
            {
                var versions = ["Msxml2.XMLHTTP.7.0", "Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];

                for (var i = 0; i < versions.length; i++)
                {
                    try
                    {
                        xmlHttp = new ActiveXObject(versions[i]);
                        if (xmlHttp)
                        {
                            this.XMLHTTP_ActiveX = versions[i];
                            break;
                        }
                    }
                    catch (ex) { };
                }
            }
        }
        return xmlHttp;
    },

    ProgressBarDiv: "progressbar",

    ShowProgressBar: function(complete)
    {
        if (complete)
        {
            if (document.body) document.body.style.cursor = 'default';
            if (!isNull($(this.ProgressBarDiv)))
                $(this.ProgressBarDiv).style.display = "none";
        }
        else
        {
            if (document.body) document.body.style.cursor = 'wait';
            if (!isNull($(this.ProgressBarDiv)))
                $(this.ProgressBarDiv).style.display = "block";
        }
    },

    MessageDiv: "statusmessage",

    ShowMessage: function(message, type)
    {
        if (!isNull($(this.MessageDiv)))
        {
            if (isUndefined(message))
            {
                $(this.MessageDiv).style.display = "none";
                $(this.MessageDiv).innerHTML = "";
            }
            else
            {
                $(this.MessageDiv).style.display = "block";
                $(this.MessageDiv).className = "message" + type;
                $(this.MessageDiv).innerHTML = message;
            }
        }
    },

    ShowPopup: function(title, message, type)
    {
        if (isUndefined(message))
        {
            Freedom.Popup.Close();
        }
        else
        {
            Freedom.Popup.Open("<div class='statusicon " + type + "'><div class='statusmessage'>" + message + "</div></div>", title, 250, 70, false);
        } 
    }
});

function oXml() { }
Object.extend(oXml.prototype, 
{

    Load: function(xml) 
    {
        if (isUndefined(xml)) xml = "<xml/>";
        if (window.ActiveXObject) 
        {
            var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = "false";
            xmlDoc.loadXML(xml);
        }
        else 
        {
            var domParser = new DOMParser();
            var xmlDoc = domParser.parseFromString(xml, "text/xml");
        }
        return xmlDoc;
    },

    AddNode: function(xmlParent, name, value) 
    {
        var xmlNode = xmlParent.ownerDocument.createElement(name);
        if ((value != "" && !isUndefined(value)) || value == 0) 
        {
            var xmlText = xmlParent.ownerDocument.createCDATASection(value);
            xmlNode.appendChild(xmlText);
        }
        xmlParent.appendChild(xmlNode);
        return xmlNode;
    },

    GetNodeValue: function(xmlNode, name) 
    {
        return xmlNode.selectSingleNode(name).childNodes[0].nodeValue;
    },

    GetXml: function(xmlNode) 
    {
        value = "";
        if (!isUndefined(xmlNode)) 
        {
            if (xmlNode.childNodes.length == 0)
                value = "";
            else 
            {
                for (var i = 0; i < xmlNode.childNodes.length; i++) 
                {
                    if (isUndefined(xmlNode.childNodes[i].xml))
                        value = value + (new XMLSerializer()).serializeToString(xmlNode.childNodes[i]);
                    else
                        value = value + xmlNode.childNodes[i].xml;
                }
            }
        }
        return value;
    },

    AdoptNode: function(xmlParent, xmlChild) 
    {
        if (Freedom.UserAgent.browser() != "Safari") 
        {
            xmlParent.appendChild(xmlChild);
        }
        else 
        {
            var xmlNode = xmlParent.ownerDocument.adoptNode(xmlChild);
            xmlParent.appendChild(xmlNode);
        }
    }
});

function $() 
{
    var elements = new Array();

    for (var i = 0; i < arguments.length; i++) 
    {
        var element = arguments[i];
        if (typeof element == 'string')
            element = document.getElementById(element);

        if (arguments.length == 1)
	        return element;

        elements.push(element);
    }

    return elements;
}

function $f(sForm, sField) 
{
    return document.forms[sForm].elements[sField];
}

function getElementsByClass(searchClass, node, tag) 
{
	var classElements = new Array();
	if (node == null) node = document;
	if (tag == null) tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) 
	{
	    if (pattern.test(els[i].className)) 
	  	{
	    	classElements[j] = els[i];
	    	j++;
	  	}
	}
	return classElements;
}

function getFormValues(formName) 
{
    var form = "";
    var field = "";
    var value = "";
    var valueString = "";

    if (formName == "")
        form = document.forms[0];
    else
        form = $(formName);

    for (var i = 0; i < form.elements.length; i++) 
    {
        var field = form.elements[i];

        if (!field.disabled) 
        {
            var addField = true;
            
            if (field.type == 'select-one') 
            {
                if (field.selectedIndex > -1) 
                {
                    value = field.options[field.selectedIndex].value;
                }
            } 
            else if (field.type == 'textarea') 
            {
				if (!(typeof FCKeditorAPI == 'undefined')) 
				{
					oFCK = FCKeditorAPI.GetInstance(field.id);
					if (!isUndefined(oFCK)) field.value = FCKeditorAPI.GetInstance(field.id).GetXHTML();
				}
                value = field.value;
            } 
            else if (field.type == 'radio') 
            {
                if (field.checked) 
                    value = field.value;
                else
                    var addField = false;
            }
            else if (field.type == 'checkbox') 
            {
                if (field.checked)
                    value = '1';
                else
                    value = '0';
            }
            else if (field.type == 'application/x-shockwave-flash')
            {
                addField = false;
            } 
            else
            {
                value = field.value;
            }
            if (addField) valueString += ((i) ? '&' : '') + field.name.encode() + '=' + value.encode();
        }
    }

    return valueString
}

function htmlEntityDecode(data) 
{
    var ta = document.createElement("textarea");
    data = fixTextAreas(data);
    ta.innerHTML = data.replace(/</g, "&lt;").replace(/>/g, "&gt;");
    return ta.value;
}

function fixTextAreas(data) 
{
    data = data.replace(/(<textarea[^>]*?)\/>/g, "$1></textarea>")
    return data;
}

function runScripts(data)
{
    var regex = new RegExp(/<script[^>]*>([\s\S]*?)<\/script>/g);
    var match = null;
    while (match = regex.exec(data))
    {
        eval(match[1]);
    }
}

Object.extend(String.prototype, 
{
    encode: function() 
	{
	    if (encodeURIComponent)
	        return encodeURIComponent(this);
	        
	    if (escape) 
	        return escape(this);
	},
	decode: function() {
	    this.replace(/\+/g, ' ');
	    if (decodeURIComponent) 
	        return decodeURIComponent(this);
	    
	    if (unescape) 
	        return unescape(this);
	    
	    return this;
	}
});

function isUndefined(vValue) 
{
    return typeof vValue == 'undefined';
}

function isNull(vValue) 
{
   	return typeof vValue == 'object' && !vValue;
}

function showItem(oItem) 
{
	oItem.style.position = "static";
	oItem.style.visibility = "visible";
}

function hideItem(oItem) 
{
	oItem.style.position = "absolute";
	oItem.style.visibility = "hidden";
}

var nCount =0;
function debugWindow(sText) 
{
   oElement = document.createElement("div");
   oElement.id = "debug" + nCount++;
   oElement.style.border = "1px red solid";
   oElement.style.backgroundColor = "white";
   oElement.style.color = "black";
   oElement.style.position = "absolute";
   oElement.style.left = "200px";
   oElement.style.top = "200px";
   oElement.style.width = "600px";
   oElement.style.padding = "10px";
   oElement.style.textAlign = "left";
   oElement.innerHTML = "<h3 style='color:red'>Error</h3>";
   oElement.innerHTML += sText.replace(/</g,"&lt;"); 
   oElement.innerHTML += "<br><br><br><div onclick='document.body.removeChild($(\"" + oElement.id + "\"));' style='color:red; cursor:pointer;'>close</div>";
   document.body.appendChild(oElement);
}

function oPopup () {}
Object.extend(oPopup.prototype,
{
    hWndIndex: 1,
    zIndex: 20000,
    currentDragWindow: '',
    mouseDown: false,
    showCloseButton: true,
    dragOffsetX: 0,
    dragOffsetY: 0,
    windows: new Array(),
    window: function(key)
    {
        return this.windows[this.windowindex(key)];
    },
    windowindex: function(key)
    {
        for (nIndex = 0; nIndex < this.windows.length; nIndex++)
        {
            if (this.windows[nIndex].key == key) return nIndex;
        }
    },
    Open: function(html, title, width, height, showCloseButton)
    {
        if (isUndefined(title)) title = "";
        if (isUndefined(width)) width = 500;
        if (isUndefined(height)) height = 250;

        this.showCloseButton = true;
        if (!isUndefined(showCloseButton)) this.showCloseButton = showCloseButton;

        popup = this;

        var oWindow = new Object;
        popup.windows.push(oWindow);

        oWindow.hWnd = popup.hWndIndex++;
        oWindow.key = "popup" + oWindow.hWnd;
        oWindow.title = title;
        oWindow.status = "";

        oWindow.background = MakeLayer(oWindow.key + "_bg")
        oWindow.background.className = "background";
        oWindow.background.style.zIndex = popup.zIndex++;

        oWindow.element = MakeLayer(oWindow.key)
        oWindow.element.className = "popup panel";
        oWindow.element.style.width = width + "px";
        oWindow.element.style.zIndex = popup.zIndex++;

        oWindow.element.titlebar = document.createElement("div");
        oWindow.element.titlebar.className = "titlebar";
        oWindow.element.titlebar.innerHTML = popup.titlebar(oWindow.key, oWindow.title);
        oWindow.element.appendChild(oWindow.element.titlebar);

        oWindow.element.contentpanel = document.createElement("div");
        oWindow.element.contentpanel.className = "bg topborder";
        oWindow.element.contentpanel.style.minHeight = height + "px";
        oWindow.element.contentpanel.innerHTML = html;
        oWindow.element.appendChild(oWindow.element.contentpanel);

        oWindow.element.statusbar = document.createElement("div");
        oWindow.element.statusbar.className = "";
        oWindow.element.statusbar.innerHTML = popup.statusbar(oWindow.key, oWindow.status);
        oWindow.element.contentpanel.appendChild(oWindow.element.statusbar);

        oWindow.element.bottom = document.createElement("div");
        oWindow.element.bottom.className = "bottom";
        oWindow.element.appendChild(oWindow.element.bottom);

        CenterElement(oWindow.background, 0, true, true);
        CenterElement(oWindow.element, 0, false, true);

        document.body.onmousedown = function(event) { popup.onMouseDown(event); }
        document.body.onmousemove = function(event) { popup.onMouseMove(event); }
        document.body.onmouseup = function(event) { popup.onMouseUp(event); }

        oWindow.element.onclick = function(event) { popup.onClick(event, oWindow.key); }
        oWindow.element.ondblclick = function(event) { popup.onDblClick(event, oWindow.key); }
        oWindow.element.onmousedown = function(event) { popup.onMouseDownWindow(event, oWindow.key); }

        oWindow.element.onmouseover = function(event) { popup.onMouseOver(event, oWindow.key); }
        oWindow.element.onmouseout = function(event) { popup.onMouseOut(event, oWindow.key); }

        oWindow.element.titlebar.onmouseover = function(event) { popup.onMouseOverTitle(event, oWindow.key); }
        oWindow.element.titlebar.onmouseout = function(event) { popup.onMouseOutTitle(event, oWindow.key); }

        this.UpdateWindows(oWindow.key);

        return oWindow.key;
    },
    Close: function(key)
    {
        if (this.windows.length > 0)
        {
            if (isUndefined(key)) key = this.GetTopWindow();

            document.body.removeChild(this.window(key).background);
            document.body.removeChild(this.window(key).element);

            this.windows.splice(this.windowindex(key), 1);
            this.currentDragWindow = "";
            this.UpdateWindows(this.GetTopWindow());
        }
    },
    UpdateWindows: function(key)
    {
        for (nIndex = 0; nIndex < this.windows.length; nIndex++)
        {
            //if (this.windows[nIndex].key == key)
               // this.windows[nIndex].element.titlebar.className = 'inactive';

        }
    },
    GetTopWindow: function()
    {
        sKey = '';
        nZIndex = -1;
        for (nIndex = 0; nIndex < this.windows.length; nIndex++)
        {
            if (this.windows[nIndex].element.style.zIndex > nZIndex)
            {
                nZIndex = this.windows[nIndex].element.style.zIndex;
                sKey = this.windows[nIndex].key;
            }
        }
        return sKey;
    },
    titlebar: function(key, title)
    {
        popup = this;
        var value = "";
        //value += "<div class='header' style='width:100%'><div class='left' style='width:100%'><div class='right' style='width:100%'><div class='face'>";

        if (this.showCloseButton)
        {
            value += "<div class='buttons'>"
	               + "<a onClick='popup.Close(\"" + key + "\");' style='cursor:pointer;'><img src='/Images/UI/Icons/Window/Close.png' alt='close' width='16' height='14' border='0'></a>"
	               + "</div>";
        }

        value += "<h2 style='text-align:left;'>" + title + "&nbsp;</h2>";
        //value += "</div></div></div></div>";

        return value;

    },
    statusbar: function(sKey, sStatus)
    {
        popup = this;
        return sStatus;
    },
    setTitle: function(sKey, sTitle)
    {
        if (!isUndefined(this.window(sKey))) this.window(sKey).element.titlebar.innerHTML = this.titlebar(sKey, sTitle);
    },
    setContent: function(sKey, sHTML)
    {
        if (!isUndefined(this.window(sKey))) this.window(sKey).element.contentpanel.innerHTML = sHTML;
    },
    setStatus: function(sKey, sStatus)
    {
        //if (!isUndefined(this.window(sKey))) this.window(sKey).element.statusbar.innerHTML = this.statusbar(sKey, sStatus);
    },
    setCursor: function(sKey, sCursor)
    {
        if (!isUndefined(this.window(sKey))) this.window(sKey).element.style.cursor = sCursor;
    },
    onClick: function(event, sKey)
    {
        this.setStatus(sKey, 'onClick');
    },
    onDblClick: function(event, sKey)
    {
        this.setStatus(sKey, 'onDblClick');
    },
    onMouseOver: function(event, sKey)
    {
        this.setStatus(sKey, 'onMouseOver');
    },
    onMouseOut: function(event, sKey)
    {
        if (!this.mouseDown)
        {
            this.mouseDown = false;
            this.currentDragWindow = "";
            this.setCursor(sKey, 'default');
            this.setStatus(sKey, 'onMouseOut');
        }
    },
    onMouseOverTitle: function(event, sKey)
    {
        if (this.currentDragWindow == "") this.currentDragWindow = sKey;
        this.setStatus(sKey, 'onMouseOver');
    },
    onMouseOutTitle: function(event, sKey)
    {
        if (!this.mouseDown)
        {
            this.currentDragWindow = "";
            this.setStatus(sKey, 'onMouseOut');
        }
    },
    onMouseDownWindow: function(event, sKey)
    {
        this.window(sKey).element.style.zIndex = this.zIndex++;
        this.UpdateWindows(sKey);
        this.setStatus(sKey, 'onMouseDown');
    },
    onMouseDown: function(event)
    {
        if (this.currentDragWindow)
        {
            this.mouseDown = true;
            var IE = document.all ? true : false;
            if (IE)
            {
                this.dragOffsetX = window.event.x - parseInt(this.window(this.currentDragWindow).element.style.left);
                this.dragOffsetY = window.event.y - parseInt(this.window(this.currentDragWindow).element.style.top);
            }
            else
            {
                this.dragOffsetX = event.pageX - parseInt(this.window(this.currentDragWindow).element.style.left);
                this.dragOffsetY = event.pageY - parseInt(this.window(this.currentDragWindow).element.style.top);
            }
            this.window(this.currentDragWindow).element.style.zIndex = this.zIndex++;
            this.setStatus(this.currentDragWindow, 'onMouseDown');
        }
    },
    onMouseMove: function(event)
    {
        if (this.currentDragWindow)
        {
            if (this.mouseDown)
            {
                var IE = document.all ? true : false;
                this.setCursor(this.currentDragWindow, 'move');
                if (IE)
                {
                    if (window.event.x > 0) this.window(this.currentDragWindow).element.style.left = window.event.x - this.dragOffsetX;
                    if (window.event.y > 0) this.window(this.currentDragWindow).element.style.top = window.event.y - this.dragOffsetY;
                }
                else
                {
                    if (event.pageX > 0) this.window(this.currentDragWindow).element.style.left = (event.pageX - this.dragOffsetX) + "px";
                    if (event.pageY > 0) this.window(this.currentDragWindow).element.style.top = (event.pageY - this.dragOffsetY) + "px";
                }
                this.setStatus(this.currentDragWindow, 'onDrag');
            }
            else
                this.setStatus(this.currentDragWindow, 'onMouseMove');
        }
    },
    onMouseUp: function(event)
    {
        if (this.currentDragWindow)
        {
            this.setCursor(this.currentDragWindow, 'default');
            this.setStatus(this.currentDragWindow, 'onMouseUp');
            this.mouseDown = false;
        }
    }
});


/*-------------------------------------------------------------------------------------------*/
//	oUserAgent: browser detection object
/*-------------------------------------------------------------------------------------------*/
function oUserAgent() {}
Object.extend(oUserAgent.prototype, 
{
    browser: function() 
	{
		return this.searchString(this.dataBrowser) || "An unknown browser";
	},
	version: function() 
	{
		return this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "an unknown version";
	},
	OS: function() 
	{
		return this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function(data) 
	{
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) 
			{
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function(dataString) 
	{
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]
});

//-------------------------------------------------------------------------------------

function oOpacity() { }
Object.extend(oOpacity.prototype, 
{

    FadeIn: function(id, millisec) 
    {
        this.Set(id, millisec, 0, 100);
    },

    FadeOut: function(id, millisec) 
    {
        this.Set(id, millisec, 100, 0);
    },

    Set: function(id, millisec, opacStart, opacEnd) 
    {
        this.Change(id, opacStart);
        var self = this;

        if (isUndefined(millisec)) millisec = 100;

        //speed for each frame 
        var speed = Math.round(millisec / 100);
        var timer = 0;

        //determine the direction for the blending, if start and end are the same nothing happens
        if (opacStart > opacEnd) 
        {
            for (i = opacStart; i >= opacEnd; i--) 
            {
                setTimeout("Freedom.Opacity.Change('" + id + "'," + i + ")", (timer * speed));
                timer++;
            }
        }
        else if (opacStart < opacEnd) 
        {
            for (i = opacStart; i <= opacEnd; i++) 
            {
                setTimeout("Freedom.Opacity.Change('" + id + "'," + i + ")", (timer * speed));
                timer++;
            }
        }
    },

    Show: function(id)
    {
        this.Change(id, 100)
    },

    Hide: function(id)
    {
        this.Change(id, 0)
    },

    Change: function(id, opacity) 
    {
        var object = $(id).style;
        object.opacity = (opacity / 100);
        object.MozOpacity = (opacity / 100);
        object.KhtmlOpacity = (opacity / 100);
        object.filter = "alpha(opacity=" + opacity + ")";
    }
});

function showContextMenu(e, html, posx, posy) 
{
    var mousePos;

    if (isUndefined(posx) || isUndefined(posy))
        mousePos = locateMousePos(e);
    else
        mousePos = { x: posx, y: posy }; ;

    document.onmouseup = function (event)
    {
        if ($("contextMenu") != null)
            setTimeout("document.body.removeChild($('contextMenu'))", 50);
    };

    element = document.createElement("div");
    element.id = "contextMenu";
    element.name = "contextMenu";
    element.className = "contextMenu";
    element.style.position = "absolute";
    element.style.left = mousePos.x + "px";
    element.style.top = mousePos.y + "px";
    element.innerHTML = html;

    document.body.appendChild(element);

    return false;
}

function locateMousePos(e) 
{
    var posx = 0, posy = 0;
    if (e == null) e = window.event;
    if (e.pageX || e.pageY) 
    {
        posx = e.pageX; posy = e.pageY;
    } 
    else if (e.clientX || e.clientY) 
    {
        if (document.documentElement.scrollTop) 
        {
            posx = e.clientX + document.documentElement.scrollLeft;
            posy = e.clientY + document.documentElement.scrollTop;
        } 
        else 
        {
            posx = e.clientX + document.body.scrollLeft;
            posy = e.clientY + document.body.scrollTop;
        }
    }
    return { x: posx, y: posy };
}

function WindowDimensions()
{
    var intH = 0, intW = 0;

    if (self.innerHeight)
    {
        intH = window.innerHeight;
        intW = window.innerWidth;
    }
    else
    {
        if (document.documentElement && document.documentElement.clientHeight)
        {
            intH = document.documentElement.clientHeight;
            intW = document.documentElement.clientWidth;
        }
        else
        {
            if (document.body)
            {
                intH = document.body.clientHeight;
                intW = document.body.clientWidth;
            }
        }
    }

    return { height: parseInt(intH, 10), width: parseInt(intW, 10) };
}

function ScrollPosition()
{
    var posx = 0, posy = 0;
    if (typeof (window.pageYOffset) == 'number')
    {
        //Netscape compliant
        posy = window.pageYOffset;
        posx = window.pageXOffset;
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop))
    {
        //DOM compliant
        posy = document.body.scrollTop;
        posx = document.body.scrollLeft;
    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop))
    {
        //IE6 standards compliant mode
        posy = document.documentElement.scrollTop;
        posx = document.documentElement.scrollLeft;
    }
    return { x: posx, y: posy };
}

function CenterElement(elem, add, noleft, fixed)
{
    var viewport = WindowDimensions();
    var left = (viewport.width == 0) ? 50 : parseInt((viewport.width - elem.offsetWidth) / 2, 10) ;
    var top = (viewport.height == 0) ? 50 : parseInt((viewport.height - elem.offsetHeight) / 2, 10);
    
    left += add;
    if (!noleft) elem.style.left = left + 'px';
    
    top += add;
    if (!fixed)
    {
        var scroll = ScrollPosition();
        top += scroll.y;
    }
    elem.style.top = top + 'px';

    viewport, left, top, elem = null;
}

function MakeLayer(id, layerParent)
{
    var div = document.createElement("div");
    div.id = id;
    div.name = name;

    if (layerParent)
        layerParent.appendChild(div);
    else
        document.body.appendChild(div);

    return div;
}

function DeleteLayer(id)
{
    var div = $(id);
    if (div)
        document.body.removeChild(div);
}
    
function rgb2Hex(rgbColour) 
{
    if (rgbColour.substring(0, 3) == "rgb") 
	{
	    var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")"));
	    var rgbArray = rgbValues.split(", ");
	
	    var red   = parseInt(rgbArray[0]);
	    var green = parseInt(rgbArray[1]);
	    var blue  = parseInt(rgbArray[2]);
	    var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);
		return hexColour;
	}
	else 
	{
    	return rgbColour;
	}
}

// Converts a number to hexadecimal format
function IntToHex(strNum) 
{
	base = strNum / 16;
	rem = strNum % 16;
	base = base - (rem / 16);
	baseS = MakeHex(base);
	remS = MakeHex(rem);
	return baseS + '' + remS;
}

// gets the hex bits of a number
function MakeHex(x) 
{
    if ((x >= 0) && (x <= 9)) 
	{
		return x;
	}
	else 
	{
	    switch (x) 
		{
			case 10: return "A";
		  	case 11: return "B";
		  	case 12: return "C";
		  	case 13: return "D";
		  	case 14: return "E";
		  	case 15: return "F";
		}
	}
}

function toggleDisabled(el, isDisabled) 
{
    try 
    {
        if (isDisabled) 
        {
            var href = el.getAttribute("href");
            if (href && href != "" && href != null) 
            {
                el.setAttribute('href_bak', href);
            }
            el.removeAttribute('href');
            el.className = "btn disabled";
        }
        else 
        {
            el.setAttribute('href', el.attributes['href_bak'].nodeValue);
            el.className = "btn";
        }
    }
    catch(ex){}

//    if (el.childNodes && el.childNodes.length > 0) 
//    {
//        for (var i = 0; i < el.childNodes.length; i++) 
//        {
//            toggleDisabled(el.childNodes[i], isDisabled);
//        }
//    }
}

function disableAnchor(obj, disable) 
{
    if (disable) 
    {
        var href = obj.getAttribute("href");
        if (href && href != "" && href != null) 
        {
            obj.setAttribute('href_bak', href);
        }
        obj.removeAttribute('href');
        obj.style.color = "gray";
    }
    else 
    {
        obj.setAttribute('href', obj.attributes['href_bak'].nodeValue);
        obj.style.color = "blue";
    }
}
  
if (document.implementation.hasFeature("XPath", "3.0"))
{
	if ( typeof XMLDocument == "undefined" ) { XMLDocument = Document; }
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode) 
	{
        if ( !xNode ) xNode = this; 
		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for (var i = 0; i < aItems.snapshotLength; i++)
		{
		    aResult[i] = aItems.snapshotItem(i); 
		}
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode)
	{
		if ( !xNode ) xNode = this; 
		var xItems = this.selectNodes(cXPathString, xNode);
		if (xItems.length > 0)
		    return xItems[0];
		else 
		    return null;
	}
	Element.prototype.selectNodes = function(cXPathString)
	{
		if (this.ownerDocument.selectNodes) 
		    return this.ownerDocument.selectNodes(cXPathString, this);
		else 
		    throw "For XML Elements Only";
	}
	Element.prototype.selectSingleNode = function(cXPathString)
	{	
		if (this.ownerDocument.selectSingleNode) 
		    return this.ownerDocument.selectSingleNode(cXPathString, this);	
		else 
		    throw "For XML Elements Only";
	}
	Element.prototype.text = function() 
	{
	    return this.childNodes[0].nodeValue
	};
}

//if(!document.documentElement.outerHTML){
//	Node.prototype.getAttributes = function(){
//		var attStr = "";
//		if(this && this.attributes.length > 0){
//			for(a = 0; a < this.attributes.length; a ++){
//				attStr += " " + this.attributes.item(a).nodeName + "=\"";
//				attStr += this.attributes.item(a).nodeValue + "\"";
//			}
//		}
//		return attStr;
//	}

//	Node.prototype.getInsideNodes = function(){
//		if(this){
//			var cNodesStr = "", i = 0;
//			var iEmpty = /^(img|embed|input|br|hr)$/i;
//			var cNodes = this.childNodes;
//			for(i = 0; i < cNodes.length; i ++){
//				switch(cNodes.item(i).nodeType){
//					case 1 :
//						cNodesStr += "<" + cNodes.item(i).nodeName.toLowerCase();
//						if(cNodes.item(i).attributes.length > 0){
//							cNodesStr += cNodes.item(i).getAttributes();
//						}
//						cNodesStr += (cNodes.item(i).nodeName.match(iEmpty))? "" : ">";
//						if(cNodes.item(i).childNodes.length > 0){
//							cNodesStr += cNodes.item(i).getInsideNodes();
//						}
//						if(cNodes.item(i).nodeName.match(iEmpty)){
//							cNodesStr += " />";
//						} else {
//							cNodesStr += "</" + cNodes.item(i).nodeName.toLowerCase() + ">";
//						}
//						break;
//					case 3 :
//						cNodesStr += cNodes.item(i).nodeValue;
//						break;
//					case 8 :
//						cNodesStr += "<!--" + cNodes.item(i).nodeValue + "-->";
//						break;
//				}
//			}
//			return cNodesStr;
//		}
//	}

//	HTMLElement.prototype.outerHTML getter = function(){
//		var strOuter = "";
//		var iEmpty = /^(img|embed|input|br|hr)$/i;
//		switch(this.nodeType){
//			case 1 :
//				strOuter += "<" + this.nodeName.toLowerCase();
//				strOuter += this.getAttributes();
//				if(this.nodeName.match(iEmpty)){
//					strOuter += " />";
//				} else {
//					strOuter += ">" + this.getInsideNodes();
//					strOuter += "</" + this.nodeName.toLowerCase() + ">";
//				}
//				break;
//			case 3 :
//				strOuter += this.nodeValue;
//				break;
//			case 8 :
//				cNodesStr += "<!--" + this.nodeValue + "-->";
//				break;
//		}
//		return strOuter;
//	}

//	HTMLElement.prototype.outerHTML setter = function(str){
//		var iRange = document.createRange();

//		iRange.setStartBefore(this);

//		var strFragment = iRange.createContextualFragment(str);
//		var sRangeNode = iRange.startContainer;

//		iRange.insertNode(strFragment);
//		sRangeNode.removeChild(this);
//	}
//}

var Hash = (function() 
{
    var 
    // Import globals
    window = this,
    documentMode = document.documentMode,
    history = window.history,
    location = window.location,
        // Plugin variables
    callback, hash,
        // IE-specific
    iframe,

    getHash = function() 
    {
        // Internet Explorer 6 (and possibly other browsers) extracts the query
        // string out of the location.hash property into the location.search
        // property, so we can't rely on it. The location.search property can't be
        // relied on either, since if the URL contains a real query string, that's
        // what it will be set to. The only way to get the whole hash is to parse
        // it from the location.href property.
        //
        // Another thing to note is that in Internet Explorer 6 and 7 (and possibly
        // other browsers), subsequent hashes are removed from the location.href
        // (and location.hash) property if the location.search property is set.
        //
        // Via Aaron: Firefox 3.5 (and below?) always unescape location.hash which
        // causes poll to fire the hashchange event twice on escaped hashes. This is
        // because the hash variable (escaped) will not match location.hash
        // (unescaped.) The only consistent option is to rely completely on
        // location.href.
        var index = location.href.indexOf('#');
        return (index == -1 ? '' : location.href.substr(index + 1));
    },

    // Used by all browsers except Internet Explorer 7 and below.
    poll = function() 
    {
        var curHash = getHash();
        if (curHash != hash) 
        {
            hash = curHash;
            callback(curHash);
        }
    },

    // Used to create a history entry with a value in the iframe.
    setIframe = function(newHash) 
    {
        try 
        {
            var doc = iframe.contentWindow.document;
            doc.open();
            doc.write('<html><body>' + newHash + '</body></html>');
            doc.close();
            hash = newHash;
        }
        catch (e) 
        {
            setTimeout(function() { setIframe(newHash); }, 10);
        }
    },

    // Used by Internet Explorer 7 and below to set up an iframe that keeps track
    // of history changes.
    setUpIframe = function() 
    {
        // Don't run until access to the iframe is allowed.
        try 
        {
            iframe.contentWindow.document;
        } 
        catch (e) 
        {
            setTimeout(setUpIframe, 10);
            return;
        }

        // Create a history entry for the initial state.
        setIframe(hash);
        var data = hash;

        setInterval(function() 
        {
            var curData, curHash;

            try 
            {
                curData = iframe.contentWindow.document.body.innerText;
                if (curData != data) 
                {
                    data = curData;
                    location.hash = hash = curData;
                    callback(curData);
                } 
                else 
                {
                    curHash = getHash();
                    if (curHash != hash) setIframe(curHash);
                }
            } 
            catch (e) {}
        }, 50);
    };

    return {
        init: function(cb) 
        {
            // init can only be called once.
            if (callback) return;

            callback = cb;

            // Keep track of the hash value.
            hash = getHash();
            cb(hash);

            // Run specific code for Internet Explorer.
            if (window.ActiveXObject) 
            {
                if (!documentMode || documentMode < 8) 
                {
                    // Internet Explorer 5.5/6/7 need an iframe for history
                    // support.
                    //iframe = ifr;
                    iframe = document.createElement('iframe');
                    document.body.appendChild(iframe);
                    iframe.style.display = 'none';
                    iframe.src = 'javascript:"<html></html>"';
                    setUpIframe();
                } 
                else 
                {
                    // Internet Explorer 8 has onhashchange event.
                    window.attachEvent('onhashchange', poll);
                }
            } 
            else 
            {
                // Change Opera navigation mode to improve history support.
                if (history.navigationMode) history.navigationMode = 'compatible';

                setInterval(poll, 50);
            }
        },

        go: function(newHash) 
        {
            // Cancel if the new hash is the same as the current one, since there
            // is no cross-browser way to keep track of navigation to the exact
            // same hash multiple times in a row. A wrapper can handle this by
            // adding an incrementing counter to the end of the hash.
            if (newHash == hash) return;
            if (iframe) 
            {
                setIframe(newHash);
            } 
            else 
            {
                location.hash = hash = newHash;
                callback(newHash);
            }
        }
    };
})();