//   $Header: $
//
//   Copyright (c) 2001-2006 / SiteScape, Inc.  All Rights Reserved.
//
//  This information in this document is subject to change without notice 
//  and should not be construed as a commitment by SiteScape, Inc.  
//  SiteScape, Inc. assumes no responsibility for any errors that may appear 
//  in this document.
//
//  Restricted Rights:  Use, duplication, or disclosure by the U.S. Government 
//  is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the
//  Rights in Technical Data and Computer Software clause at DFARS 252.227-7013.
//
//  SiteScape and SiteScape Forum are trademarks of SiteScape, Inc.
//
//
// browser-specific vars

var isNSN = (navigator.appName == "Netscape");
var isNSN4 = isNSN && ((navigator.userAgent.indexOf("Mozilla/4") > -1));
var isNSN6 = ((navigator.userAgent.indexOf("Netscape6") > -1));
var isMoz5 = ((navigator.userAgent.indexOf("Mozilla/5") > -1) && !isNSN6);
var isMacIE = ((navigator.userAgent.indexOf("IE ") > -1) && (navigator.userAgent.indexOf("Mac") > -1));
var isIE = ((navigator.userAgent.indexOf("IE ") > -1));

//Define the "list" function for older browsers which know no better
function list() {}

var eventList = new list;
var eventTypeList = new list;
//Routine to create a new "eventObj" object
//eventObj objects are set up whenever you want to call a routine on an event.
//   event_name is the event name (e.g., "MOUSEDOWN")
function createEventObj(function_name, event_name) {
    if (eventList[function_name] == null) {
        eventList[function_name] = new eventObj(function_name);
        eventList[function_name].setEventName(event_name);
    }
    if (eventTypeList[event_name] == null) {
        eventTypeList[event_name] = event_name
        //Enable the event
        if (isNSN) {
            eval("self.document.captureEvents(Event."+event_name+")")
        }
        eval("self.document.on"+eventList[function_name].eventName+" = ssf_event_handler;")
    }
}
function eventObj(function_name) {
    this.functionName = function_name;
    this.eventName = null;
    this.setEventName = m_setEventName;
    this.callEventFunction = this.functionName;
}
function m_setEventName(event_name) {
    this.eventName = event_name.toLowerCase();
}

//Common event handler
//  This function will call the desired routines on an event
function ssf_event_handler(e) {
    if (!isNSN) {e = event}
    for (var n in eventList) {
        if (e.type.toLowerCase() == eventList[n].eventName) {
            eval(eventList[n].functionName+'(e)');
        }
    }
}


var onLoadList = new list;
//Routine to create a new "onLoadObj" object
//onLoadObj objects are set up whenever you want to call something at onLoad time.
function createOnLoadObj(name, initName) {
    if (onLoadList[name] == null) {
        onLoadList[name] = new onLoadObj(name);
        onLoadList[name].setInitRoutine(initName);
    }
}
function onLoadObj(name) {
    this.name = name;
    this.initRoutine = null;
    this.getInitRoutine = m_getInitRoutine;
    this.setInitRoutine = m_setInitRoutine;
}
function m_getInitRoutine() {
    return this.initRoutine;
}
function m_setInitRoutine(initRoutine) {
    this.initRoutine = initRoutine;
}

var onResizeList = new list;
//Routine to create a new "onResizeObj" object
//onResizeObj objects are set up whenever you want to call something at onResize time.
function createOnResizeObj(name, resizeName) {
    if (onResizeList[name] == null) {
        onResizeList[name] = new onResizeObj(name);
        onResizeList[name].setResizeRoutine(resizeName);
    }
}
function onResizeObj(name) {
    this.name = name;
    this.resizeRoutine = null;
    this.getResizeRoutine = m_getResizeRoutine;
    this.setResizeRoutine = m_setResizeRoutine;
}
function m_getResizeRoutine() {
    return this.resizeRoutine;
}
function m_setResizeRoutine(resizeRoutine) {
    this.resizeRoutine = resizeRoutine;
}
function ssf__onresize_event_handler() {
    for (var n in onResizeList) {
        onResizeList[n].resizeRoutine();
    }
}

var onErrorList = new list;
//Routine to create a new "onErrorObj" object
//onErrorObj objects are set up whenever you want to call something at onError time.
function createOnErrorObj(name, onErrorName) {
    if (onErrorList[name] == null) {
        onErrorList[name] = new onErrorObj(name);
        onErrorList[name].setOnErrorRoutine(onErrorName);
        window.onerror = ssf__onError_event_handler
    }
}
function onErrorObj(name) {
    this.name = name;
    this.onErrorRoutine = null;
    this.getOnErrorRoutine = m_getOnErrorRoutine;
    this.setOnErrorRoutine = m_setOnErrorRoutine;
}
function m_getOnErrorRoutine() {
    return this.onErrorRoutine;
}
function m_setOnErrorRoutine(onErrorRoutine) {
    this.onErrorRoutine = onErrorRoutine;
}
function ssf__onError_event_handler() {
    var ret = false
    for (var n in onErrorList) {
        if (onErrorList[n].onErrorRoutine()) {ret = true}
    }
    return ret
}

var spannedAreasList = new list;
//Routine to create a new "spannedArea" object
//spannedAreaObj objects are set up whenever you need some form elements to be 
//   blanked when showing the menus
function createSpannedAreaObj(name) {
    if (spannedAreasList[name] == null) {
        spannedAreasList[name] = new spannedAreaObj(name);
    }
    return spannedAreasList[name];
}
function spannedAreaObj(name) {
    this.name = name;
    this.showArgumentString = '';
    this.hideArgumentString = '';
    this.showRoutine = null;
    this.show = m_showSpannedArea;
    this.setShowRoutine = m_setShowRoutine;
    this.hideRoutine = null;
    this.hide = m_hideSpannedArea;
    this.setHideRoutine = m_setHideRoutine;
}
function m_setShowRoutine(showRoutine) {
    this.showRoutine = showRoutine;
    //See if there are any other arguments passed in
    //  These will get passed on to the show routine
    for (var i = 1; i < m_setShowRoutine.arguments.length; i++) {
        if (this.showArgumentString != '') {this.showArgumentString += ',';}
        this.showArgumentString += '"'+m_setShowRoutine.arguments[i]+'"';
    }
}
function m_setHideRoutine(hideRoutine) {
    this.hideRoutine = hideRoutine;
    //See if there are any other arguments passed in
    //  These will get passed on to the show routine
    for (var i = 1; i < m_setHideRoutine.arguments.length; i++) {
        if (this.hideArgumentString != '') {this.hideArgumentString += ',';}
        this.hideArgumentString += '"'+m_setHideRoutine.arguments[i]+'"';
    }
}
function m_showSpannedArea() {
    eval(this.showRoutine+'('+this.showArgumentString+');')
}
function m_hideSpannedArea() {
    eval(this.hideRoutine+'('+this.hideArgumentString+');')
}

function toggleSpannedAreas(spanName,newValue) {
    if (isNSN6 || isMoz5) {
        if (document.getElementById(spanName) != null) {
            document.getElementById(spanName).style.visibility = newValue;
        }    
    } else {  
        if (self.document.layers && document.layers[spanName] != null) {
            self.document.layers[spanName].visibility = newValue;
        } else if (self.document.all && document.all[spanName] != null) {
            self.document.all[spanName].style.visibility = newValue;
        }
    }
}

function hideSpannedAreas() {
    //Hide the various standard form elements used by the product 
    toggleSpannedAreas('attrformspan','hidden')
    toggleSpannedAreas('attrform2span','hidden')
    toggleSpannedAreas('viewentry','hidden')

    //Hide any form elements that may be visible
    for (var name in spannedAreasList) {
        spannedAreasList[name].hide()
    }
}

function showSpannedAreas() {
    //Make the standard form elements visible again
    toggleSpannedAreas('attrformspan','visible')
    toggleSpannedAreas('attrform2span','visible')
    toggleSpannedAreas('viewentry','visible')

    //Show any form elements that should be returned to the visible state
    for (var name in spannedAreasList) {
        spannedAreasList[name].show()
    }
}


// general functions

//Routine to show a div on top of an anchor point
function showDivAtAnchor(ancName,divName) {
    var divObj
    if (isNSN || isNSN6 || isMoz5) {
        divObj = self.document.getElementById(divName)
    } else {
        divObj = self.document.all[divName]
    }
    divObj.style.top = getAnchorTop(ancName)
    divObj.style.left = getAnchorLeft(ancName)
    divObj.style.visibility = 'visible'
}

function showHideObj(objName, visibility) {
    var obj
    if (isNSN || isNSN6 || isMoz5) {
        obj = self.document.getElementById(objName)
    } else {
        obj = self.document.all[objName]
    }
    obj.style.visibility = visibility
}


function getObjAbsX(obj) {
    var x = 0
    var parentObj = obj
    while (parentObj.offsetParent && parentObj.offsetParent != '') {
        x += parentObj.offsetParent.offsetLeft
        parentObj = parentObj.offsetParent
    }
    return x
}

function getObjAbsY(obj) {
    var y = 0
    var parentObj = obj
    while (parentObj.offsetParent && parentObj.offsetParent != '') {
        y += parentObj.offsetParent.offsetTop
        parentObj = parentObj.offsetParent
    }
    return y
}

function getLeftMargin(defValue) {
    var left = defValue;
    if (isNSN6 || isMoz5) {
        if (self.document.body.style.marginLeft && self.document.body.style.marginLeft != '') {
            left = self.document.body.style.marginLeft
        }
    } else if (isNSN) {
    } else {
        if (self.document.body.leftMargin) {
            left = self.document.body.leftMargin
        }
    }
    return parseInt(left);
}

function getAnchorTop(anchorName) {
    var top = 0;
    if (isNSN6 || isMoz5) {
        var obj = document.anchors[anchorName]
        while (1) {
            if (!obj) {break}
            top += parseInt(obj.offsetTop)
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    } else if (isNSN) {
        top = document.anchors[anchorName].y
    } else {
        var obj = document.all[anchorName]
        while (1) {
            if (!obj) {break}
            top += obj.offsetTop
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    }
    return parseInt(top);
}

function getAnchorLeft(anchorName) {
    var left = 0;
    if (isNSN6 || isMoz5) {
        var obj = document.anchors[anchorName]
        while (1) {
            if (!obj) {break}
            left += parseInt(obj.offsetLeft)
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    } else if (isNSN) {
        left = document.anchors[anchorName].x
    } else {
        var obj = document.all[anchorName]
        while (1) {
            if (!obj) {break}
            left += obj.offsetLeft
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    }
    return parseInt(left);
}

function getImageTop(imageName) {
    var top = 0;
    if (isNSN6 || isMoz5) {
        var obj = document.images[imageName]
        while (1) {
            if (!obj) {break}
            top += parseInt(obj.offsetTop)
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    } else if (isNSN) {
        top = document.images[imageName].y
    } else {
        var obj = document.all[imageName]
        while (1) {
            if (!obj) {break}
            top += obj.offsetTop
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    }
    return parseInt(top);
}

function getImageLeft(imageName) {
    var left = 0;
    if (isNSN6 || isMoz5) {
        var obj = document.images[imageName]
        while (1) {
            if (!obj) {break}
            left += parseInt(obj.offsetLeft)
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    } else if (isNSN) {
        left = document.images[imageName].x
    } else {
        var obj = document.all[imageName]
        while (1) {
            if (!obj ) {break}
            left += obj.offsetLeft
            if (obj == obj.offsetParent) {break}
            obj = obj.offsetParent
        }
    }
    return parseInt(left);
}

function getObjectWidth(obj) {
    if (isNSN6 || isMoz5) {
        return parseInt(obj.offsetWidth)
    } else if (isNSN) {
        return parseInt(obj.clip.width)
    } else {
        return parseInt(obj.clientWidth)
    }
}

function getObjectHeight(obj) {
    if (isNSN6 || isMoz5) {
        return parseInt(obj.offsetHeight)
    } else if (isNSN) {
        return parseInt(obj.clip.height)
    } else {
        return parseInt(obj.clientHeight)
    }
}

function getObjectLeft(obj) {
    if (isNSN6 || isMoz5) {
        return parseInt(obj.style.left)
    } else if (isNSN) {
        return parseInt(obj.style.left)
    } else {
        return parseInt(obj.style.pixelLeft)
    }
}

function getObjectTop(obj) {
    if (isNSN6 || isMoz5) {
        return parseInt(obj.style.top)
    } else if (isNSN) {
        return parseInt(obj.style.top)
    } else {
        return parseInt(obj.style.pixelTop)
    }
}

function setObjectLeft(obj, value) {
    if (isNSN6 || isMoz5) {
        obj.style.left = value;
    } else if (isNSN) {
        obj.style.left = value;
    } else {
        obj.style.pixelLeft = value;
    }
}

function setObjectTop(obj, value) {
    if (isNSN6 || isMoz5) {
        obj.style.top = value;
    } else if (isNSN) {
        obj.style.top = value;
    } else {
        obj.style.pixelTop = value;
    }
}

function getWindowWidth() {
    if (isNSN) {
        return parseInt(window.innerWidth)
    } else {
        return document.body.clientWidth
    }
}

function getWindowHeight() {
    if (isNSN) {
        return parseInt(window.innerHeight)
    } else {
        return document.body.clientHeight
    }
}


function getBodyWindowHeight() {
  var myHeight = 0;
  if( typeof( window.innerHeight ) == 'number' ) {
    //Non-IE
    myHeight = window.innerHeight;
  } else if( document.documentElement && document.documentElement.clientHeight ) {
    //IE 6+ in 'standards compliant mode'
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && document.body.clientHeight ) {
    //IE 4 compatible
    myHeight = document.body.clientHeight;
  }
  return myHeight;
}


// function to dynamically change the size of a textarea; called by
// TextArea, defined in home_page_support.html, which captures the name
// of the form and the element.
// If the text area is in a section, need to call showSections to push
// them all down for the resized textarea; sectionList must exist
var sectionList;
function changeTextArea(formEle, form, op, what, rowInc, colInc) {
    if (!rowInc) {rowInc = 5};
    if (!colInc) {colInc = 15};
    var colMax = 140;
    var rowMax = 50;
    var colMin = 20;
    var rowMin = 5;

    if (op == "add") {
        if (what == "rows" && formEle.rows < rowMax) {
            formEle.rows = formEle.rows + rowInc;
            if (sectionList != null) {
                showSections();
            }
        } else if (what == "cols" && formEle.cols < colMax) {
            formEle.cols = formEle.cols + colInc;
        } else if (what == "all") {
            if (formEle.rows < rowMax) {
                formEle.rows = formEle.rows + rowInc;
            }
            if (formEle.cols < colMax) {
                formEle.cols = formEle.cols + colInc;
            }
        }
    }  else {
        if (what == "rows" && formEle.rows > rowMin) {
            formEle.rows = formEle.rows - rowInc;
            if (sectionList != null) {
                showSections();
            }
        } else if (what == "cols" && formEle.cols > colMin) {
            formEle.cols = formEle.cols - colInc;
        } else if (what == "all") {
           if (formEle.rows > rowMin) {
                formEle.rows = formEle.rows - rowInc;
            }
            if (formEle.cols > colMin) {
                formEle.cols = formEle.cols - colInc;
            }
        }
    }    
    
    var sizeString = formEle.rows+" "+formEle.cols;
    //alert(sizeString)
    form.TextAreaSize.value = sizeString;
    //alert("TextAreaSize "+form.TextAreaSize.value)
}
//this does what definedSpannedArea does, without the area.
function defineSpannedElements(spanId) {
    var spanObj = createSpannedAreaObj(spanId);
    spanObj.setShowRoutine('showElement', spanId)
    spanObj.setHideRoutine('hideElement', spanId)
}

// this function submits a select box form, no submit button
function submitSelectBox(selectObj) {
    var index = selectObj.selectedIndex;
    var value = selectObj.options[index].value;
    var url = value;
    if (url != 'none' && url != '') {
        self.window.location.href = url;
    }
    if(navigator.appName.indexOf('Netscape') == -1 ||  
        navigator.userAgent.indexOf('WinNT') != -1 ||  
        navigator.userAgent.indexOf('Win95') != -1 ) {

        selectObj.options[index].selected = false;
        selectObj.options[0].selected = true;
    }
}

// for help popups in NN4.7, and wherever we can't do div layers (e.g., frames)
function openPopupWindow(helpType, windowTitle, style1, style2, btnText) {
    newWindow = window.open("", "newWindow", "scrollbars,resizable,width=400,height=250" );
    newWindow.document.open("text/html");
    with (newWindow.document) {
        writeln("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        write("<html><head><title>");
        write(windowTitle);
        writeln("</title>");
        write("<link rel=\"stylesheet\" href=\"");
        write(style1);
        writeln("\" type=\"text/css\">");
        write("<link rel=\"stylesheet\" href=\"");
        write(style2);
        writeln("\" type=\"text/css\">");
        writeln("</head><body>");
        writeln("<br /><span class=\"content\">");
        writeln(helpType);
        writeln("</span><br /><form name=\"closeWindow\" action=\"\">");
        write("<div align=\"center\"><input type=\"button\" class=\"fineprintSubmitOff\" name=\"closeBtn\" value=\"");
        write(btnText);
        writeln("\" onclick=\"window.close();\"></div>");
        writeln("</form></body></html>");
        newWindow.focus();
        close();
    }
}

//Define some dummy routines that will get rewritten if needed
function saveEditorHtml() {}
function setViewHtmlMode() {}
function saveSpellCheckedText() {}

// scrolling MOTD/marquee functions and variables
var scrollMarqueePass1 = true
var marqueeMovementWidth = 1
var marqueeTimerInterval = 20
var marqueeObj = null
var marqueeTimer = null;

//Function to see if the marquee element exists
//  If it exists, then the marqueeObj variable is set up
//Returns true if the marquee object exists
function defineMarqueeObjects() {
    if (isNSN6 || isMoz5) {
        if (document.getElementById('marquee')) {
            marqueeObj = document.getElementById('marquee')
        }
    } else if (isNSN) {
        if (document.marquee) {
            marqueeObj = document.marquee
        }
    } else {
        if (document.all.marquee) {
            marqueeObj = document.all.marquee
        }
    }

    if (marqueeObj != null) {
        return true;
    } else {
        return false;
    }
}

//Function to turn on the marquee scrolling
function scrollMarquee() {
    if (marqueeTimer != null) {
        clearTimeout(marqueeTimer);
        marqueeTimer = null;
    }
    if (defineMarqueeObjects()) {
        var newLeft = parseInt(getObjectLeft(marqueeObj) - marqueeMovementWidth)
        if (newLeft > screen.width) {
            newLeft = screen.width
        }
        if (scrollMarqueePass1 || parseInt(getObjectLeft(marqueeObj) + getObjectWidth(marqueeObj)) < 0) {
            setObjectLeft(marqueeObj, parseInt(getWindowWidth() - 10))
            marqueeObj.style.visibility = 'visible';
            scrollMarqueePass1 = false
        } else {
            setObjectLeft(marqueeObj, newLeft)
        }

        // window.status = 'newLeft: ' + newLeft + '  mL: ' + getObjectLeft(marqueeObj) + '  mW: ' + getObjectWidth(marqueeObj) + '  wW: ' + getWindowWidth() + '  sW: ' + screen.width;
    }
    if (marqueeTimer == null) {
        marqueeTimer = setTimeout('scrollMarquee()', marqueeTimerInterval)
    }
}

//Function to pause the marquee scrolling
function pauseMarquee() {
    if (marqueeTimer != null) {
        clearTimeout(marqueeTimer);
        marqueeTimer = null;
    }
}

function launchHelp(url) {
    viewHelp(url, 'help')
    return(false);
}

function viewHelp(url, target) {
    helpWindow = window.open(url, target);
    if(navigator.appVersion.indexOf('MSIE 3.0') == -1 && helpWindow.focus) {helpWindow.focus();}
}

function findGroups(s, formName, eleName) {
//alert("findGroups "+s)
    if (s == "") {
        groupList = ""
        self.document.getElementById(eleName).rows = 8;
    } else {
        var groupArray = s.split('\n');
        groupList = groupArray[0];
        for (var i = 1; i < groupArray.length; i++) {
            groupList = groupList + "\n" + groupArray[i];
        }
        if (i <= 8) {
            self.document.getElementById(eleName).rows = i + 1;
        } else {
            self.document.getElementById(eleName).rows = 8;
        }
    }
    self.document.getElementById(eleName ).value = s;
}

function listGroups(s, formName, eleName) {
    //alert("listGroups function "+formName+" "+eleName)
    self.document.getElementById(eleName).value = s;
    eval('self.document.' + formName + '.submit()');
}

function findGroupsAndUsersHidden(s, formName, eleName) {
//alert("findGroupsAndUsersHidden "+s)
    self.document.getElementById(eleName).value = s;
}

function findGroupsAndUsers(s, formName, eleName, rows) {
//alert("findGroupsAndUsers "+s)
    if (rows == null) {rows = 8}
    self.document.getElementById(eleName).value = s;
    self.document.getElementById(eleName).rows = rows;
}

//alert box for non-editable form fields (textareas)
function noedit(text) {
    if (text == null) {
        alert("This area is not editable.")
    } else {
        alert(text)
    }
}


//Routines to support getting stuff from the server without reloading the page
function getXMLObj() {
	var req;
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return req;
}

function http_rpc_post(url, callbackRoutine, data) {
	var x;
	x = getXMLObj();
	x.open("POST", url, true);
	x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	x.onreadystatechange = function() {
		if (x.readyState != 4) {
			return;
		}
		fetch_url_debug("received " + x.responseText);
        if (x.status == 200) {
        	callbackRoutine(x.responseText)        	
        } else {
        	callbackRoutine(x.statusText)
        }
	}
	x.send(data);
	fetch_url_debug(" waiting... url = " + url);
	delete x;
}                

function fetch_url_debug(str) {
    //alert(str);
}


function quickMeetingRPC(meetingUrl, userId, title, desc, meetingMessage) {
    var postData;
	postData = 'participantsList=' + escape(userId);
	postData += '&title=' + escape(title);
	postData += '&desc=' + escape(desc);
	postData += '&meetingMessage=' + escape(meetingMessage);
    http_rpc_post(meetingUrl,launchMeeting, postData);
}

function launchMeeting(id) {
    if (id.substr(0, 2) == 'OK') {
		// alert('launchMeeting: ' + id.substr(3));
		self.location.href = 'iic:meetmany?meetingtoken=' + id.substr(3);
	} else {
		alert('Error launching Zon meeting: ' + id);
	}
	return false;
}


function addToMySummary(url, forumId) {
    var postData;
	postData = 'forumId=' + escape(forumId);
    http_rpc_post(url, addToMySummaryDone, postData);
}


function addToMySummaryDone(result) {
    if (result.substr(0, 2) == 'OK') {
		alert(result.substr(3));
	} else {
		alert('Error: ' + result );
	}
	return false;
}


function backgroundColorOf(elementId) {
    if (isNSN6 || isMoz5) {
        var e = document.getElementById(elementId); 
        return document.defaultView.getComputedStyle(e,null).getPropertyValue('background-color');
    } else {  
        var e = self.document.all[elementId];
        return e.currentStyle['backgroundColor']
    }
}








var Fat = {
	make_hex : function (r,g,b) 
	{
		r = r.toString(16); if (r.length == 1) r = '0' + r;
		g = g.toString(16); if (g.length == 1) g = '0' + g;
		b = b.toString(16); if (b.length == 1) b = '0' + b;
		return "#" + r + g + b;
	},
	fade_all : function ()
	{
		var a = document.getElementsByTagName("*");
		for (var i = 0; i < a.length; i++) 
		{
			var o = a[i];
			var r = /fade-?(\w{3,6})?/.exec(o.className);
			if (r)
			{
				if (!r[1]) r[1] = "";
				if (o.id) Fat.fade_element(o.id,null,null,"#"+r[1]);
			}
		}
	},
	fade_element : function (id, fps, duration, from, to) 
	{
		if (!fps) fps = 30;
		if (!duration) duration = 3000;
		if (!from || from=="#") from = "#FFFF83";
		if (!to) to = this.get_bgcolor(id);
		
		var frames = Math.round(fps * (duration / 1000));
		var interval = duration / frames;
		var delay = interval;
		var frame = 0;
		
		if (from.length < 7) from += from.substr(1,3);
		if (to.length < 7) to += to.substr(1,3);
		
		var rf = parseInt(from.substr(1,2),16);
		var gf = parseInt(from.substr(3,2),16);
		var bf = parseInt(from.substr(5,2),16);
		var rt = parseInt(to.substr(1,2),16);
		var gt = parseInt(to.substr(3,2),16);
		var bt = parseInt(to.substr(5,2),16);
		
		var r,g,b,h;
		while (frame < frames)
		{
			r = Math.floor(rf * ((frames-frame)/frames) + rt * (frame/frames));
			g = Math.floor(gf * ((frames-frame)/frames) + gt * (frame/frames));
			b = Math.floor(bf * ((frames-frame)/frames) + bt * (frame/frames));
			h = this.make_hex(r,g,b);
		
			setTimeout("Fat.set_bgcolor('"+id+"','"+h+"')", delay);

			frame++;
			delay = interval * frame; 
		}
		setTimeout("Fat.set_bgcolor('"+id+"','"+to+"')", delay);
	},
	fade_element_fg : function (id, fps, duration, from, to) 
	{
		if (!fps) fps = 30;
		if (!duration) duration = 3000;
		if (!from || from=="#") from = "#FFFF33";
		if (!to) to = this.get_fgcolor(id);
		
		var frames = Math.round(fps * (duration / 1000));
		var interval = duration / frames;
		var delay = interval;
		var frame = 0;
		
		if (from.length < 7) from += from.substr(1,3);
		if (to.length < 7) to += to.substr(1,3);
		
		var rf = parseInt(from.substr(1,2),16);
		var gf = parseInt(from.substr(3,2),16);
		var bf = parseInt(from.substr(5,2),16);
		var rt = parseInt(to.substr(1,2),16);
		var gt = parseInt(to.substr(3,2),16);
		var bt = parseInt(to.substr(5,2),16);
		
		var r,g,b,h;
		while (frame < frames)
		{
			r = Math.floor(rf * ((frames-frame)/frames) + rt * (frame/frames));
			g = Math.floor(gf * ((frames-frame)/frames) + gt * (frame/frames));
			b = Math.floor(bf * ((frames-frame)/frames) + bt * (frame/frames));
			h = this.make_hex(r,g,b);
		
			setTimeout("Fat.set_fgcolor('"+id+"','"+h+"')", delay);

			frame++;
			delay = interval * frame; 
		}
		setTimeout("Fat.set_fgcolor('"+id+"','"+to+"')", delay);
	},
	set_bgcolor : function (id, c)
	{
		var o = document.getElementById(id);
		o.style.backgroundColor = c;
	},
	get_bgcolor : function (id)
	{
		var o = document.getElementById(id);
		while(o)
		{
			var c;
			if (window.getComputedStyle) c = window.getComputedStyle(o,null).getPropertyValue("background-color");
			if (o.currentStyle) c = o.currentStyle.backgroundColor;
			if ((c != "" && c != "transparent") || o.tagName == "BODY") { break; }
			o = o.parentNode;
		}
		if (c == undefined || c == "" || c == "transparent") c = "#FFFFFF";
		var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
		if (rgb) c = this.make_hex(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
		return c;
	},
	set_fgcolor : function (id, c)
	{
		var o = document.getElementById(id);
		o.style.color = c;
	},
	get_fgcolor : function (id)
	{
		var o = document.getElementById(id);
		while(o)
		{
			var c;
			if (window.getComputedStyle) c = window.getComputedStyle(o,null).getPropertyValue("color");
			if (o.currentStyle) c = o.currentStyle.color;
			if ((c != "" && c != "transparent") || o.tagName == "BODY") { break; }
			o = o.parentNode;
		}
		if (c == undefined || c == "" || c == "transparent") c = "#FFFFFF";
		var rgb = c.match(/rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/);
		if (rgb) c = this.make_hex(parseInt(rgb[1]),parseInt(rgb[2]),parseInt(rgb[3]));
		return c;
	}
}

function hideAway(elementId, inMs) {
    if (inMs != 0) {
        setTimeout("hideAway('"+elementId+"',0)", inMs);
    } else {
        var o = document.getElementById(elementId);
        o.style.visibility = 'hidden';
    }
}