﻿/***********************************************************************

Albatross Client-Side Framework 
Written By: Brian Mancini
Version: 1.1-09
Modified: 1/21/2009

Special thanks to Kenny Huang for his contributions
and testing of the framework.

This code is provided under the GNU General Public License (GPL).

***********************************************************************/

/***************************************************************************************************************************/
// GLOBAL FUNCTIONS

if (window["$"] == undefined)
{
    $ = function(id)
    {
        return document.getElementById(id);
    }
}
$id = function(id)
{
    return document.getElementById(id);
}


if (window["$$"] == undefined)
{
    $$ = function(name)
    {
        return document.getElementsByTagName(name);
    }
}

/************************************************************************************************************************/
// Basic Framework Utilities

function Albatross() { }
var albt = new Albatross();

Albatross.prototype.browser = function() {        
    return navigator.appName;
}

Albatross.prototype.browserVer = function() {        
    if(this.ie())                        
        return parseFloat(navigator.appVersion.split("MSIE")[1])    
    else
        return parseFloat(navigator.appVersion);
}

Albatross.prototype.ie = function () {
    return (this.browser() == "Microsoft Internet Explorer")
}

Albatross.prototype.ie6 = function() {
    return (this.ie() && this.browserVer() == 6)
}



Albatross.prototype.listObject = function(object,html) {
    var output = "";
    for(var key in object) {    
        output+= key + ": " + object[key] + ((html==null||html==true)?"<br/>":"\n");
    }
    return output;
}


Albatross.prototype.show = function(object) {
    var hideDisplay = "";
    if(object.getAttribute("hideDisplay")!= null)
    {
        hideDisplay = object.getAttribute("hideDisplay");
        object.removeAttribute("hideDisplay");
    }
    object.style.display = hideDisplay;
        
}

Albatross.prototype.hide = function(object) {
    var existingDisplay = Albatross.prototype.disp.getStyle(object, "display");
    if (existingDisplay != "none")
        object.setAttribute("hideDisplay", existingDisplay);    
    object.style.display = "none";       
}

Albatross.prototype.selectOption = function(object, value) {                
    for(var i=0; i<object.options.length; i++)
    {
        if(object.options[i].value == value)
        {
            object.options[i].selected = true;
            return true;
        }        
    }    
    return false;
}

Albatross.prototype.createCookie = function(cname,cvalue,minutes,path) {    
    var expire = "";
    var path = path || "/";    
    if(minutes!=null) {
        var date = new Date();
        date.setTime(date.getTime()+(1000*60*minutes));
        expire = "; expires="+date.toGMTString();
    }       
    if(cname && cvalue)
        document.cookie = cname+"="+cvalue+expire+"; path="+path;
}

Albatross.prototype.readCookie = function(name) {
	var nameLength = name.length + 1 ;      //name.length + equal sign ie: "name="		
	var cookie = document.cookie;           //get the cookie string
	var index = cookie.indexOf(name+"=");   //get the index of the cookie		
	
	if(index > -1)
	{	    	    
	    cookie = cookie.substring(index+nameLength,cookie.length);	    
	    var array = cookie.split(";");	    
	    if(array.length>0)
	        return array[0];	        
	}
	return null;	
}

Albatross.prototype.removeCookie = function(name) {
    var value = Albatross.prototype.readCookie(name);
	this.createCookie(name,value,-1);
}

/***********************************************************************************************************************/
// Client side XSLT stuff
// Modified from http://www.w3schools.com/xsl/xsl_client.asp on 7/1/2008 by Brian Mancinis

Albatross.prototype.xslt = new Object();

// Loads the specified file as an XML document.  Can be used for loading XML or XSLT files.
Albatross.prototype.xslt.load = function(fileName)
{
    var xmlDoc;
    
    if(window.ActiveXObject)    
        xmlDoc = ActiveXObject("Microsoft.XMLDOM");
    else if(document.implementation && document.implementation.createDocument)    
        xmlDoc = document.implementation.createDocument("","",null);    
    else
        throw "XML loading not available on this browser.";
        
    xmlDoc.async=false;
    xmlDoc.load(fileName);
    
    return xmlDoc;
}

// Transforms the supplied XMLDocument into a results Document utilizing the provided stylesheet XML fragment
Albatross.prototype.xslt.transform = function(stylesheet, input, target)
{
    var results;
    if(window.ActiveXObject && input.transformNode)    
    {        
        document.getElementById(target).innerHTML = input.transformNode(stylesheet);    
    }
    else if(document.implementation && document.implementation.createDocument)
    {
        var proc = new XSLTProcessor();
        proc.importStylesheet(stylesheet);
        var docfrag = proc.transformToFragment(input, document);
        document.getElementById(target).appendChild(docfrag);
    }
}


/************************************************************************************************************************/
// Basic Graphical Utilities

Albatross.prototype.disp = new Object();


Albatross.prototype.disp.toRGBArray = function(color)
{
    if(color.search(/rgb/) == 0) //rgb(255,255,255) type
    {
        var temp = color.match(/\d+/g);        
        return [ parseInt(temp[0]), parseInt(temp[1]), parseInt(temp[2]) ];
    }
    else if(color.length == 7) //#ffffff type
    {
        return [ parseInt(color.substring(1,3),16), parseInt(color.substring(3,5),16), parseInt(color.substring(5,7),16) ];
    }
    else
        return null;    
}

Albatross.prototype.disp.toRGBString = function(colorArray)
{
    return "rgb(" + parseInt(colorArray[0]) + ", " + parseInt(colorArray[1]) + ", " + parseInt(colorArray[2]) + ")";
}

Albatross.prototype.disp.coord = function(x, y) {    
    this.x = x;
    this.y = y;    
}

Albatross.prototype.disp.size = function(width, height) {
    this.width = width;
    this.height = height;
}


Albatross.prototype.disp.getAbs = function(object) {    
    var left = 0;
    var top = 0;
    
    //iterate through
    while(object!=null)
    {
        left += object.offsetLeft;
        top += object.offsetTop;
        object = object.offsetParent;
    }       
    return new this.coord(left, top);
}

Albatross.prototype.disp.getRelPos = function(object)
{
    var left = 0;
    var top = 0;       
    
    
    //iterate through
    while(object!=null && Albatross.prototype.disp.getStyle(object,"position")!="absolute")
    {
        left += object.offsetLeft;
        top += object.offsetTop;
        object = object.offsetParent;
    }       
    return new this.coord(left, top);
}

Albatross.prototype.disp.getSize = function(object) {        
    return new this.size(object.offsetWidth, object.offsetHeight);   //non W3 spec, DHTML compliant
}


Albatross.prototype.disp.getStyle = function(object, styleProperty)
{
    if(Albatross.prototype.ie())    
        return object.currentStyle[styleProperty];        
    else
        return document.defaultView.getComputedStyle(object,null).getPropertyValue(styleProperty);
}

Albatross.prototype.disp.fullScreen = function(object) {    
    object.style.top="0px";
    object.style.left="0px";
    object.style.width="100%";
    object.style.height="100%";
    object.style.position = "fixed";    
        
    if(Albatross.prototype.ie6())   //IE6 fixed position bug
    {               
        object.style.position = "absolute";                        
        //object.style.setExpression("width","(parseInt(document.body.clientWidth) - 2*parseInt(this.style.borderWidth) - parseInt(this.style.paddingLeft) - parseInt(this.style.paddingRight) + parseInt(document.body.style.marginLeft) + parseInt(document.body.style.marginRight)) + 'px'");
        //object.style.setExpression("height","(parseInt(document.body.clientHeight) - 2*parseInt(this.style.borderWidth) - parseInt(this.style.paddingTop) - parseInt(this.style.paddingBottom) + parseInt(document.body.style.marginTop) + parseInt(document.body.style.marginBottom)) + 'px'");
        object.style.setExpression("marginTop", "document.documentElement.scrollTop");
        object.style.setExpression("width", "document.documentElement.clientWidth");
        object.style.setExpression("height", "document.documentElement.clientHeight");
    }               
}


Albatross.prototype.disp.innerWidth = function()
{
    if(window.innerWidth != null)
        return new Albatross.prototype.disp.size(window.innerWidth, window.innerHeight);
    else if(document.body.clientWidth != null)
        return new Albatross.prototype.disp.size(document.body.clientWidth, document.body.clientHeight);
    else
        return new Albatross.prototype.disp.size(0,0);
}


Albatross.prototype.disp.center = function(object)
{
    object.style.position="absolute"; // moved from top line in 1.0.11
    var size = Albatross.prototype.disp.getSize(object);
    var windowHeight, windowWidth;
             
    windowHeight = document.documentElement.clientHeight;
    windowWidth = document.documentElement.clientWidth;
                                              
    object.style.left = "50%";
    object.style.top = "50%";
    object.style.position = "fixed";
    object.style.marginTop = "-" + parseInt(size.height/2) + "px";
    object.style.marginLeft = "-"+ parseInt(size.width/2) + "px";

    if(Albatross.prototype.ie6())   //IE6 fixed position bug
    {        
        object.style.marginTop = "0px";        
        object.style.position = "absolute";
        object.style.setExpression("marginTop","0 - parseInt(this.offsetHeight / 2) + document.documentElement.scrollTop + 'px'");                                
        object.style.setExpression("marginLeft","0 - parseInt(this.offsetWidth / 2) + 'px'");                                
    }                
        
    if(size.height >= (parseInt(windowHeight) - 20))
    {
        object.style.overflow = "auto";
        object.style.height = (parseInt(windowHeight) - 50) + "px"; //setting the height will auto adjust in ie6 since its an expression
        
        if(!Albatross.prototype.ie6())
        {
            object.style.top = "10px";
            object.style.bottom = "10px";
            object.style.marginTop = "0px";
            object.style.marginBottom = "0px";
        }        
    }
    
    if(size.width >= (parseInt(windowWidth) - 50))
    {        
        object.style.overflow = "auto";
        object.style.width = (parseInt(windowWidth) - 60) + "px";   //set the width will auto adjust in ie6 since its an expression
        
        if(!Albatross.prototype.ie6())
        {
            object.style.left = "10px";
            object.style.right = "10px";      
            object.style.marginLeft = "0px";
            object.style.marginRight = "0px";          
        }
    }      
}

Albatross.prototype.disp.toPos = function(object, coord) {
    object.style.position = "absolute";
    object.style.left = coord.x + "px";
    object.style.top = coord.y + "px";
}



Albatross.prototype.disp.opacity = function(object, opacity) {                    
    if(Albatross.prototype.ie())
    {        
        if(object.currentStyle && object.currentStyle.width=="auto")
            object.style.width = object.offsetWidth;
                        
        object.style.filter = "alpha(opacity="+opacity+")";
        
        if(opacity == 100)
            object.style.filter = "";
    }
    else
    {
        object.style.MozOpacity = opacity/100;
        object.style.opacity = opacity/100;                              
        
        if(opacity == 100)
        {
            object.style.MozOpacity = "";
            object.style.opacity = "";
        }
    }    
}



/************************************************************************************************************************/
// Advanced Graphical Effects

Albatross.prototype.fx = new Object();

Albatross.prototype.fx.fxOptions = function() {
    this.duration = 250;
    this.frames = 5;      
    this.opacity;        
    this.rgb = [255,255,136];
    this.opacityDelta = function() {
            //100 % 
            return 100 / this.frames;
        }
    this.timeout = function() {
            return (this.duration/this.frames);
        }                    
}

Albatross.prototype.fx.fadeIn = function(object, params) {
    var options = new this.fxOptions();
    
    if(!options.opacity)
        options.opacity=0;
    
    //copy matching params
    if(params)
        for(var key in options)
            if(params[key]!=null) options[key] = params[key];
    
    
    options.opacity = options.opacity+options.opacityDelta();
    
    if(options.opacity <= 100)
    {    
        Albatross.prototype.disp.opacity(object,options.opacity);        

        var _scope = this;                               
        window.setTimeout(function(){_scope.fadeIn(object, options)},options.timeout());
    }
    else
    {
        Albatross.prototype.disp.opacity(object,100);                                            
    }    
}

Albatross.prototype.fx.fadeOut = function(object, params) {
    var options = new this.fxOptions(false);
    
    if(!options.opacity)
        options.opacity=100;
    
    //copy matching params
    if(params)
        for(var key in options)
            if(params[key]!=null) options[key] = params[key];
    
    options.opacity = options.opacity-options.opacityDelta();
    
    if(options.opacity >= 0)
    {    
        Albatross.prototype.disp.opacity(object,options.opacity);

        var _scope = this;                               
        window.setTimeout(function(){_scope.fadeOut(object, options)},options.timeout());
    }
    else
    {
         Albatross.prototype.disp.opacity(object,0);                                         
    } 
}

Albatross.prototype.fx.highlight = function(object, params) {
    var options = new this.fxOptions();
    
    //copy matching params
    if(params)
        for(var key in options)
            if(params[key]!=null) options[key] = params[key];
    
    //get current color    
    var backgroundColor = object.currentStyle ? object.currentStyle.backgroundColor : object.style.getPropertyValue("background-color");
    var ocolor = Albatross.prototype.disp.toRGBArray(backgroundColor||"#ffffff");
                    
    //go up
    var rd = (ocolor[0] - options.rgb[0]) / options.frames;
    var gd = (ocolor[1] - options.rgb[1]) / options.frames;
    var bd = (ocolor[2] - options.rgb[2]) / options.frames;                               

    
    //start               
    this._highlightStep(object, ocolor, options, rd, gd, bd); 
}

Albatross.prototype.fx._highlightStep = function(object, ocolor, options, rd, gd, bd) {
                                                  
    if(rd>=0 && options.rgb[0] >= ocolor[0] || rd<=0 && options.rgb[0] <= ocolor[0])
        rd = 0;    
    if(gd>=0 && options.rgb[1] >= ocolor[1] || gd<=0 && options.rgb[1] <= ocolor[1])
        gd = 0;
    if(bd>=0 && options.rgb[2] >= ocolor[2] || bd<=0 && options.rgb[2] <= ocolor[2])
        bd = 0;
        
    if(rd == 0 && gd == 0 && bd == 0)   //we're done!
    {
        object.style.backgroundColor = Albatross.prototype.disp.toRGBString(ocolor);
    }
    else    //call again in timeout        
    {                        
        //increment
        var red = options.rgb[0];
        red +=rd;        
        var green = options.rgb[1];
        green +=gd;
        var blue = options.rgb[2];
        blue+=bd;
        options.rgb = [red,green,blue];
    
        var to = Albatross.prototype.disp.toRGBString([red,green,blue]);  
        object.style.backgroundColor = to;
            
        //make call
        _scope = this;
        window.setTimeout(function() { _scope._highlightStep(object, ocolor, options, rd, gd, bd) }, options.timeout());
               
    }
}



/************************************************************************************************************************/
// UI Utilities

Albatross.prototype.ui = new Object();

Albatross.prototype.ui.popupOptions = function() {
    this.modal = false;     //make a modal box
    this.title = false;      //show the title bar  
    this.closer = true;     //show x      
    this.titleText = "";
    this.onClose = null;
    this.onOk = null;
    this.coord = new Albatross.prototype.disp.coord(10,10);
    this.center = true;    
    this.modalBackground = "#303030";
    this.modalOpacity = 50;
    
}

Albatross.prototype.ui.modal = function(object, params) {
    
    var options = new this.popupOptions();
    
    //copy params
    if(params!=null)
        for(var key in options)
            if(params[key]!=null)
                options[key] = params[key];
        
    options.modal = true;
    this.popup(object, options);
}
Albatross.prototype.ui.popupStack = new Array();
Albatross.prototype.ui.popupStack.isEmpty = function() {
    return this.length <= 0;
}
Albatross.prototype.ui.popupStack.top = function() {
    if(this.isEmpty())
        return null;
    else
        return this[this.length-1];
}
Albatross.prototype.ui.keyUpHook = function(e) {
    e = e != null ? e : window.event;
    if (e.keyCode == 27 && !albt.ui.popupStack.isEmpty()) {
        if (Albatross.prototype.ui.formerKeyUpHook != undefined && Albatross.prototype.ui.formerKeyUpHook != null)
            Albatross.prototype.ui.formerKeyUpHook();
        var top = albt.ui.popupStack.top();
        if(top != null)
            albt.ui.closePopup($id(top));
    }
}

Albatross.prototype.ui.popup = function(object, params) {

    var options = new this.popupOptions();

    if (params != null)
        for (var key in options)
        if (params[key] != null)
        options[key] = params[key];

    // MODAL STUFF        
    // build the fader
    if (options.modal && $id(object.id + "_fader") == null) {
        
        $$('html')[0].style.overflow = 'hidden'; // hide the overflow 1.1.01 fix        

        //create hider layer
        var fader = document.createElement("div");
        fader.id = object.id + "_fader";
        fader.style.backgroundColor = options.modalBackground;
        Albatross.prototype.disp.fullScreen(fader);
        Albatross.prototype.disp.opacity(fader, options.modalOpacity);
        $$('body')[0].appendChild(fader);   //append the fader to the body           
        fader.style.zIndex = 150;
    }

    $$('body')[0].appendChild(object);

    //append closer
    if (options.closer) {
        var close = document.createElement("div");
        var closeButton = document.createElement("input");
        closeButton.type = "button";
        closeButton.value = "X";
        closeButton.style.width = "20px";
        closeButton.style.paddingLeft = "3px";
        closeButton.style.paddingRight = "3px";
        closeButton.style.fontWeight = "bold";
        closeButton.style.cursor = "pointer";
        closeButton.onclick = function() { Albatross.prototype.ui.closePopup(object); }
        close.appendChild(closeButton);
        close.style.position = "absolute";
        close.style.top = "2px";
        close.style.right = "5px";
        close.style.zIndex = 152;
        object.insertBefore(close, object.firstChild);
    }

    //append title
    if (options.title) {
        var title = document.createElement("div");
        title.id = object.id + "_title";
        title.style.height = "2em;";
        title.innerHTML = options.titleText
        object.insertBefore(title, object.firstChild);
    }

    // hide selects that aren't a member of our object in ie6
    if (Albatross.prototype.ie6()) {
        var selects = $$('select');
        for (var i = 0; i < selects.length; i++) {
            var parentNode = selects[i].parentNode;
            var isPart = false;
            while (!isPart && parentNode != null) {
                if (parentNode == object)
                    isPart = true;
                else
                    parentNode = parentNode.parentNode;
            }
            if (!isPart) {
                Albatross.prototype.hide(selects[i]);
            }
        }
    }

    //show the object
    object.style.zIndex = 151;
    Albatross.prototype.show(object);

    //move to appropriate position now that its on display
    if (options.center) {
        Albatross.prototype.disp.center(object);
    }
    else {
        Albatross.prototype.disp.toPos(object, options.coord);
    }

    // add to stack
    Albatross.prototype.ui.popupStack.push(object.id);
    
    // add the excape keypress hook
    if (document.onkeyup != null && document.onkeyup != Albatross.prototype.ui.keyUpHook) {
        Albatross.prototype.ui.formerKeyUpHook = document.onkeyup;
    }
    document.onkeyup = Albatross.prototype.ui.keyUpHook;

}

Albatross.prototype.ui.closePopup = function(object, retain) {

    //if modal, remove the fader
    var fader = $id(object.id + "_fader");
    if (fader) {
        fader.parentNode.removeChild(fader);        
    }

    var title = $id(object.id + "_title");
    if (title)
        title.parentNode.removeChild(title);
    
    $$('html')[0].style.overflow = 'auto'; // show the overflow 1.1.01 fix

    if (retain == false )
        object.parentNode.removeChild(object);
    else
        Albatross.prototype.hide(object);   //hide the object
        

    if (Albatross.prototype.ie6()) {
        var selects = $$('select');
        for (var i = 0; i < selects.length; i++) {
            var parentNode = selects[i].parentNode;
            var isPart = false;
            while (!isPart && parentNode != null) {
                if (parentNode == object)
                    isPart = true;
                else
                    parentNode = parentNode.parentNode;
            }
            if (!isPart) {
                Albatross.prototype.show(selects[i]);
            }
        }
    }
    
    // pop off stack
    Albatross.prototype.ui.popupStack.pop();

}


Albatross.prototype.position = new Object();
Albatross.prototype.position.TOP = 0;
Albatross.prototype.position.RIGHT = 1;
Albatross.prototype.position.BOTTOM = 2;
Albatross.prototype.position.LEFT = 3;

Albatross.prototype.ui.toggleMenu = function(containerName) {
    this.containerName = containerName;
}
Albatross.prototype.ui.toggleMenu.prototype.toggle = function(callerName, menuName, position, alignment)
{                
    if(this.callerDOM != null && this.callerDOM.id != callerName || this.menuDOM != null && this.menuDOM.id != menuName)
    {
        this.hide();
        this.show(callerName, menuName, position, alignment);
    }
    else if(this.callerDOM == null || this.menuDOM == null)
        this.show(callerName, menuName, position, alignment);
    else
        this.hide();
}
Albatross.prototype.ui.toggleMenu.prototype.show = function(callerName, menuName, position, alignment) 
{
    this.callerDOM = $id(callerName);
    this.menuDOM = $id(menuName);        

    this.menu = $id(this.containerName)
    
    if(this.menu == null)
    {
        this.menu = document.createElement("div");
        this.menu.id = this.containerName;
        this.menu.style.position='absolute';
        this.menu.style.zIndex=150;
        $$('body')[0].appendChild(this.menu);
    }
    
    this.menu.innerHTML="";
    this.menu.style.left = '';            
 
    this.oldParent = this.menuDOM.parentNode;
    this.menu.appendChild(this.menuDOM);    
    this.menuDOM.style.display="block";    
    this.menu.style.display="block"; // show the menu
    
    //position menu to ensure it doesn't go off screen
    var docWidth = document.width;
    var docHeight = document.height;                        
    var callerPos = albt.disp.getAbs(this.callerDOM);                 
    var callerSize = albt.disp.getSize(this.callerDOM);        
    var menuSize = albt.disp.getSize(this.menu);  
    
    // align caller left to menu left --> left aligned
    if(alignment == Albatross.prototype.position.LEFT)
        this.menu.style.left = callerPos.x; + 'px';
    
    // align caller right to menu right --> right aligned
    if(alignment == Albatross.prototype.position.RIGHT)
        this.menu.style.left = callerPos.x + callerSize.width - menuSize.width + 'px';
    
    // align caller left to menu right --> left side menu
    if(position == Albatross.prototype.position.LEFT)
        this.menu.style.left = callerPos.x - menuSize.width + 'px';
    
    // align caller right to menu left --> right side menu
    if(position == Albatross.prototype.position.RIGHT)
        this.menu.style.left = callerPos.x + callerSize.width + 10 + 'px';
        
    // align caller top with menu top --> top aligned
    if(alignment == Albatross.prototype.position.TOP)
        this.menu.style.top = callerPos.y +'px';        
        
    // align caller bottom with menu bottom --> bottom aligned
    if(alignment == Albatross.prototype.position.BOTTOM)
        this.menu.style.top = callerPos.y + callerSize.height - menuSize.height + 'px';
    
    // align caller top with menu bottom --> menu on top
    if(position == Albatross.prototype.position.TOP)
        this.menu.style.bottom = callerPos.y + 'px';
    
    // align caller bottom with menu top --> menu on bottom
    if(position == Albatross.prototype.position.BOTTOM)
        this.menu.style.top = callerPos.y + callerSize.height + 'px';
       
}
Albatross.prototype.ui.toggleMenu.prototype.hide = function() 
{ 
    // hide the menu object and the controls container
    if(this.menu != null)
        this.menu.style.display='none';
    
    if(this.menuDOM != null)
        this.menuDOM.style.display='none';

    // return the element to its previous parent
    if(this.oldParent != null && this.menuDOM != null)
        this.oldParent.appendChild(this.menuDOM);        
    
    // set the pointers to null
    this.callerDOM = null;
    this.menuDOM = null;
    this.callerName = null;
    this.menuName = null;    
}







Albatross.prototype.ui.popupMenuOptions = function() {
    this.position = 0;      
    this.className = 'popup_menu';    
}
Albatross.prototype.ui.popupMenu = function(menuId, params) {
    this.options = new Albatross.prototype.ui.popupMenuOptions();
    
    if(params!=null)
        for(element in this.options)
            if(params[element]!=null)
                this.options[element] = params[element];    
                
    this.menuId = menuId;   
                                                       
}
Albatross.prototype.ui.popupMenu.prototype.initialize = function(callerDOM, menuDOM)
{
    this.menu = $id(this.menuId);  
    if(this.menu==null) //if this.menu doesn't exist, make it
    {
        this.menu=document.createElement("div");
        this.menu.style.position="absolute";   
        this.menu.id=this.menuId;
        $$("body")[0].appendChild(this.menu);    
        
        this.menu.style.zIndex = 1000;  //HACK SHOULD CALC ZINDEX
        
        // autoclose hooks
        _this = this;                
        this.menu.onmouseout=function(){_this.hide();}
        this.menu.onmouseover=function(){_this.stopHide();}                    
    }     
    
    // clear past stuff
    this.menu.innerHTML="";
    this.menu.style.left = '';
    
}
Albatross.prototype.ui.popupMenu.prototype.show = function(callerDOM, menuDOM) {

    this.initialize(callerDOM, menuDOM);  // ensure that the menu is initialized and is alive!!    
    this.stopHide();    // clears the timeout if there is one
    this.performHide(); // hides the menu if it was open
    
    // fill the menu with the appropriate stuff
    this.menu.appendChild(menuDOM.cloneNode(true)); // clone method        
    this.menu.childNodes[0].style.display="block";  // make menu visible        
    this.menu.style.display="block";  // show the menu
    
    //position menu to ensure it doesn't go off screen
    var docWidth = document.width;
    var docHeight = document.height;                        
    var callerPos = albt.disp.getAbs(callerDOM);                 
    var callerSize = albt.disp.getSize(callerDOM);     
    var menuSize = albt.disp.getSize(this.menu);  
    
    if(this.options.position == 0)
    {        
        if(callerPos.x + menuSize.width > docWidth - 10) // check for right overflow
            this.menu.style.left = callerPos.x + callerSize.width - menuSize.width + 'px';
        else
            this.menu.style.left = callerPos.x +'px';            
        
        if(callerPos.y + menuSize.height > docHeight - 10) // check for bottom overflow
            this.menu.style.bottom = callerPos.y + 'px';            
        else            
            this.menu.style.top = callerPos.y + callerSize.height + 'px';
    }
    else if(this.options.position == 1)
    {
        if(callerPos.x + callerSize.width + menuSize.width > docWidth - 10) // check for right overflow
            this.menu.style.left = callerPos.x - menuSize.width - 10 + 'px';            
        else                        
            this.menu.style.left = callerPos.x + callerSize.width + 10 + 'px';
        
        if(callerPos.y + menuSize.height > docHeight -10) // check for bottom overflow
            this.menu.style.top = callerPos.y + callerSize.height - menuSize.height + 'px';
        else            
            this.menu.style.top = callerPos.y +'px';        
    }                                 
    
}
Albatross.prototype.ui.popupMenu.prototype.hideTimeout;
Albatross.prototype.ui.popupMenu.prototype.stopHide = function() {
    window.clearTimeout(this.hideTimeout);
}
Albatross.prototype.ui.popupMenu.prototype.hide = function() {
    this.stopHide();
    var _this = this;
    this.hideTimeout=window.setTimeout(                
            function() {
                    _this.performHide();                                           
            },350);
}
Albatross.prototype.ui.popupMenu.prototype.performHide = function()
{    
    if(this.menu!=null)    
        this.menu.style.display='none';        
}




Albatross.prototype.ui.emptyTextbox = function(element, message, dullColor)
{
    if(dullColor==null)
        dullColor = "#c0c0c0";

    if(element!=null && message != "") // ensure we have an element
    {
        if(element.value == "") // mark the element with the message
        {
            element.value = message;
            element.style.color = dullColor;
        }
        
        element.onfocus = function(e) {            
            if(element.value==message)
            {
                element.value = "";
                element.style.color = '';
            }
        }
        element.onblur = function(e) {            
            if(element.value=="")
            {
                element.value = message;
                element.style.color = dullColor;
            }        
        }                        
    }
}



/***********************************************************************/
// RESPONSE HANDLING - Compliments C# ResponseCollection Class

Albatross.prototype.response = function(messageCallback)
{
    this.messageCallback = messageCallback;
    this.debug = new Object();        
}
Albatross.prototype.response.prototype.handler = function(xml)
{
    // get all responses
    var responses = xml.getElementsByTagName("Response");

    // store debug info       
    this.debug.responses = responses;
    
    // iterate through each response
    for(var i=0; i<responses.length; i++)
    {
        var type = "";
        var value = "";
        var target = "";                   

        // get type                                     
        try { type = responses[i].getElementsByTagName("Type")[0].childNodes[0].nodeValue; } catch(ex) { type = ""}
        
        // get value, may contain multiple elements if long enough
        try { 
            for(var j=0; j<responses[i].getElementsByTagName("Value")[0].childNodes.length;j++) 
                value += responses[i].getElementsByTagName("Value")[0].childNodes[j].nodeValue; 
        
        } catch(ex) { value = ""}
        
        // get the target element
        try { target = responses[i].getElementsByTagName("Target")[0].childNodes[0].nodeValue; } catch(ex) { target = ""}                        
        
        // perform necessary operation
        switch(type)
        {
            case "Element":     // handle element content replacement
                var element = $id(target);
                if(element==null)                    
                    throw "Albatross render error: Element " + target + " does not exist";  
                                               
                // IE does not like setting innerHTML on tr elements...
                // so if the replacing element's a tr element lets do some hacking so it works
                // this should eventually be extended to include the other elements in IE that don't support innerHTML
                //  refer to: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx
                if (albt.ie() && element.tagName.toLowerCase() == "tr") 
                {
                    try
                    {   
                        // build a temporary element and place a temp table in it so we can access the cell elements                                                                         
                        var tempdiv = document.createElement("div");
                        tempdiv.style.display="none";
                        tempdiv.id="tempdiv";
                        tempdiv.innerHTML = "<table><tr>"+value+"</tr></table>";
                        document.body.appendChild(tempdiv);                                                          
                        var temprow = tempdiv.getElementsByTagName("tr")[0];
                        
                        // remove all cells in the element                                                        
                        while(element.childNodes.length > 0)                            
                            element.removeChild(element.childNodes[0]);                                                                                           
                        
                        // add new cells                                                        
                        while(temprow.childNodes.length>0) 
                            element.appendChild(temprow.childNodes[0]);                            
                            
                        // clean up                            
                        tempdiv.parentNode.removeChild(tempdiv);
                    }
                    catch (ex) { }
                }
                else // simply replace the element's content
                    element.innerHTML = value;
                break;
                
            case "Eval": // handles evaluation of a string for code execution
                eval(value);
                break;
                
            case "Message": // displays a message
                if(this.messageCallback == null)                        
                    alert(value);
                else
                    this.messageCallback(target, value);
                break;
        };
    }
}

    Albatross.prototype.event = function() 
    {
        // place here so that it is an instance member
        this._delegates = new Array();
    }    
    Albatross.prototype.event.prototype.addDelegate = function(handler) {
        var found = false;
        for (var i = 0; i < this._delegates.length; i++) {
            if (this._delegates[i] == handler) {
                this._delegates[i] = handler;
                found = true;
                break;
            }
        }
        if (!found)
            this._delegates.push(handler);
    }
    Albatross.prototype.event.prototype.removeDelegate = function(handler) {
        for (var i = 0; i < this._delegates.length; i++) {
            if (this._delegates[i] == handler) {
                this._delegates.splice(i, 1);
                break;
            }
        }
    }
    Albatross.prototype.event.prototype.fire = function() {
        for (var i = 0; i < this._delegates.length; i++) {
            this._delegates[i]();
        }
    }
