std = {

    savedBgColor: '#ffffff',
    
    viewActions: {},
    
    includes: [],
    
    setViewAction: function(name,action) {
        std.viewActions[name] = action;
    },
    
    doPrompt: true,
    matchVal: null,
    matchId: null,

    isIE: typeof ActiveXObject != "undefined",

    enablePrompt: function() {
        std.matchVal = null;
        std.matchId = null;
        std.doPrompt = true;
    },
    
    prompt1: function(tag,msg) {
        std.prompt(tag,msg);
    },
    
    prompt2: function(tag,msg) {
//        this.prompt(tag,msg);
    },
    
    prompt: function(tag,msg) {
        if (tag instanceof Tag) {
            msg = "TAG="+tag.tagName+" ID="+tag.id+" "+msg;
        } else if (tag) {
            msg = "NODE="+tag.nodeName+" ID="+tag.id+" "+msg;
        }
        if (std.doPrompt) {
            Top.debug(msg);
            if (    (! std.matchId || (tag.id == std.matchId))
                 && (!std.matchVal || (msg.indexOf(std.matchVal) >= 0))   ) {
                for (;;) {
                    var cmd = prompt(std.lastMsg+"\n"+msg);
                    if (cmd == null) {
                        std.doPrompt =  false;
                    } else if (cmd == "id") {
                        std.matchId = prompt("Enter ID");
                    } else if (cmd == "val") {
                        std.matchVal = prompt("Enter match val");
                    } else if (cmd == "body") {
                        Top.debug(std.showTag("",document.body,true));
                    } else if (cmd == "this") {
                        Top.debug(std.showTag("",tag,false));
                    } else if (cmd == "show") {
                        var tagId = prompt("Enter tag Id to show");
                        var tagToShow = document.getElementById(tagId);
                        Top.debug(std.showTag("",tagToShow,true));
                    } else if (cmd == "clear") {
                        std.matchId = null;
                        std.matchVal = null;
                    } else {
                        break;
                    }
                }
                std.lastMsg = msg;
            }
        }
    },
    
    prompt3: function(msg) {
        Top.debug(msg);
        if (std.doPrompt) {
            if (prompt(msg) == null) {
                std.doPrompt =  false;
            }
        }
    },
    
    showTag: function(indent,tag,recursive) {
        if (! tag) return "NO TAG";
        if (! tag.currentStyle) {
            tag.currentStyle = window.getComputedStyle(tag,null);
        }
        var dim = {x:std.getWidth(tag),y:std.getHeight(tag)};
        var content = null;        
//        var content = fix.getContent(tag);
//        var boxWidthAndHeight = fix.getWidthAndHeight(tag);
        var buf = "";
        if ((tag.nodeName != "TBODY") && (tag.nodeName != "TR") && (tag.nodeName != "TD")) {
            
            buf += indent + "TAG: "+tag.nodeName+" ID="+tag.id+"\n"
            + indent + " class="+tag.className+"\n"
            + indent + " dim.w/h="+dim.x+"/"+dim.y+"\n"
            + indent + " t.s="+tag.style.cssText+"\n"
            + indent + " parentW/H="+tag.lastParentWidth+"/"+tag.lastParentWidth+"\n"
            + indent + " borderW/H="+tag.horizontalBorder+"/"+tag.verticalBorder+"\n"
//            + indent + " lastPx: int="+tag.lastPx+" val="+tag.lastPxVal+" AT "+tag.lastPxFrom+"\n"
            + indent + " pctW/H="+tag.getAttribute("percentwidth")+"/"+tag.getAttribute("percentheight")+"\n"
            + indent + " margT/R/B/L="+tag.currentStyle.marginTop+"/"
                                      +tag.currentStyle.marginRight+"/"
                                      +tag.currentStyle.marginBottom+"/"
                                      +tag.currentStyle.marginLeft+"\n";
            if (tag.nodeName == "TABLE") {
                var tdNode = std.findParent(tag,"TD");
                if (! tdNode) tdNode = std.findParent(tag,"BODY");
                if (! tdNode.currentStyle) {
                    tdNode.currentStyle = window.getComputedStyle(tdNode,null);
                }
                buf += indent + " brdrT/B/L/R="+tag.currentStyle.borderTopWidth
                              +"/"+tag.currentStyle.borderBottomWidth
                              +"/"+tag.currentStyle.borderLeftWidth
                              +"/"+tag.currentStyle.borderRightWidth + "\n";
                buf += indent + " td.s.W/H="+tdNode.style.width+"/"+tdNode.style.height + "\n";
                buf += indent + " minW/H="+tag.currentStyle.minWidth+"/"+tag.currentStyle.minHeight+"\n";
                buf += indent + " td.minW/H="+tdNode.currentStyle.minWidth+"/"+tdNode.currentStyle.minHeight+"\n";
                buf += indent + " tdW/H="+std.getWidth(tdNode)+"/"+std.getHeight(tdNode);
            }
            if (tag.buf) buf += indent + "BUF:"+tag.buf+"\n";
            buf += "\n";
        }
        if (recursive) {
            indent = "  "+indent;            
            var children = tag.childNodes;
            for (var i=0; i<children.length; i++) {
                var child = children[i];
                if (child.nodeType == 1) {
                    buf += std.showTag(indent,child,recursive);
                }
            }
        }
        return buf;
    },
        
    expandTimeoutKey: null,
    
    savedBgColor: '#ffffff',
    savedFgColor: '#000000',
    doMouseOver: function(item,hoverFgColor,hoverBgColor) {
        std.savedFgColor = item.style.color;
        std.savedBgColor = item.style.backgroundColor;
        if (hoverFgColor != null) item.style.color = hoverFgColor;
        if (hoverBgColor != null) item.style.backgroundColor = hoverBgColor;
        item.style.cursor = 'pointer';
    },
    doMouseOut: function(item) {
        item.style.backgroundColor=std.savedBgColor;
        item.style.color=std.savedFgColor;
        item.style.cursor = 'default';
    },
    
    doNumKeypress: function(e,item,dotOk) {
        if (!e) e = window.event;
        var keyCode = 0;
        if (e.keyCode) {
            keyCode = e.keyCode;
        } else {
            keyCode = e.which;
        }
        var rslt = false;
        if (item.value == null) item.value = "";
        if (    (keyCode == 8)
             || ((keyCode >= 35) && (keyCode <= 40))  ) {
            // BS, End, Home or Arrow key
            rslt = true;
        } else if (dotOk && ((keyCode == 46) || (keyCode == 190))) {
            // not number or dot
            rslt = true;
            var n = item.value.indexOf('.');
            if (n >= 0) {
                rslt = false;
            }
        } else if ((keyCode >= 48) && (keyCode <= 57)) {
            rslt = true;
        }
        if (! e.stopPropogation) {
            e.returnValue = rslt;     
        }
        return rslt;
    },
    
    getTrNodes: function(tag) {
        var children = tag.childNodes;
        for (var i=0; i<children.length; i++) {
            var child = children[i];
            if ((child.nodeType == 1) && (child.tagName == "TBODY")) {
                return child.childNodes;
            }
        }
        return children;
    },
    
    onresize: null,

    useQuirksMode: false,

    app: window,

    get: function(id) {
        if ((id == null) || (id.length == 0)) return null;
        return document.getElementById(id);
    },


    toAttrName: function(name) {
        for (;;) {
            var n = name.indexOf('-');
            if (n < 0) return name;
            name = name.substring(0,n)+name.charAt(n+1).toUpperCase()
                 + name.substring(n+2);
        }
    },            
            
    getHeight: function(elem)  {
        var result = 0;
        if (elem.offsetHeight) {
            result = elem.offsetHeight;
        } else if (elem.clip && elem.clip.height) {
            result = elem.clip.height;
        } else if (elem.style && elem.style.pixelHeight) {
            result = elem.style.pixelHeight;
        }
        return parseInt(result);
    },
    
    getWidth: function(elem)  {
        var result = 0;
        if (elem.offsetWidth) {
            result = elem.offsetWidth;
        } else if (elem.clip && elem.clip.width) {
            result = elem.clip.width;
        } else if (elem.style && elem.style.pixelWidth) {
            result = elem.style.pixelWidth;
        }
        return parseInt(result);
    },
    
    getPosition: function(obj) {
        var xpos = 0;
        var ypos = 0;
        if (obj.offsetParent) {
            while (obj.offsetParent) {
                xpos += obj.offsetLeft
                ypos += obj.offsetTop
                obj = obj.offsetParent;
            }
        } else if (obj.x) {
            xpos = obj.x;
            ypos = obj.y;
        }
        return {x: xpos,y: ypos};
    },
    
    getEventPosition: function(e) {
        var xpos = 0;
        var ypos = 0;
        if (typeof(e.pageX) == 'number') {
            xpos = e.pageX;
            ypos = e.pageY;
        } else if (typeof(e.clientX) == 'number') {
            xpos = e.clientX + (document.body.scrollLeft || 0);
            ypos = e.clientY + (document.body.scrollTop || 0);
        }
        return {x: xpos,y: ypos};
    },
    
    findParent: function(item,tagName) {
        item = item.parentNode;
        while (item && (item.nodeName != tagName)) {
            item = item.parentNode;
        }
        return item;
    },
    
    findPrevious: function(item,tagName) {
        item = item.previousSibling;
        while (item && (item.nodeName != tagName)) {
            item = item.previousSibling;
        }
        return item;
    },

    findNext: function(item,tagName) {
        item = item.nextSibling;
        while (item && (item.nodeName != tagName)) {
            item = item.nextSibling;
        }
        return item;
    },

    findFirst: function(item,tagName) {
        item = item.firstChild;
        while (item && (item.nodeName != tagName)) {
            item = item.nextSibling;
        }
        return item;
    },
    
    findFirstTrNode: function(tag) {
        var children = tag.childNodes;
        for (var i=0; i<children.length; i++) {
            var child = children[i];
            if (child.nodeType == 1) {
                if (child.tagName == "TBODY") return std.findFirst(child,"TR");
                if (child.tagName == "TR") return child;
            }
        }
        return null;
    },
        
    getLimits: function() {
        var xpos = 0;
        var ypos = 0;
        if (self.innerWidth) {
            xpos = self.innerWidth;
            ypos = self.innerHeight;
        } else if (document.documentElement && document.documentElement.clientWidth) {
            xpos = document.documentElement.clientWidth;
            ypos = document.documentElement.clientHeight;
        } else if (document.body) {
            xpos = document.body.clientWidth;
            ypos = document.body.clientHeight;
        }
        return {x: xpos,y: ypos};
    },
    
    useAttr: function(item,attr,val) {
        if (item.attrs[attr]) {
            val = item.attrs[attr];
            delete item.attrs[attr];
        }
        if (!val) return "";
        return " "+attr+"=\""+val+"\"";
    },
    
    applyAttrs: function(attrs) {
        if (! attrs) return "";
        var buf = "";
        for (var attr in attrs) {
            buf += " "+attr+"=\""+attrs[attr]+"\"";
        }
        return buf;
    },

    endOfItems: ""
}

Top.registerNamespace("http://std.ajaxtop.com",std);
Top.registerPrefix("std",std);
Top.registerPrefix("default",std);


std.resizeCount = 0;
std.onresize = window.onresize;
std.adjustTablesOnresize = function() {
    if (std.onresize) std.onresize();
    std.resizeCount++;
    if (std.expandTimeoutKey) clearTimeout(std.expandTimeoutKey);
    std.expandTimeoutKey = setTimeout("std.adjustBody();",50);
}

window.onresize = std.adjustTablesOnresize;

// This is standard handling of a View response. It looks for
// a "target" attribute to specify where to put the HTML, if not
// found, it puts it in the BODY. It looks for a "name" attribute
// and if found uses it log a dhtmlHistory event. It looks
// for a viewAction associated with the "name" and if found,
// invokes it.
//
std.view = function() {}
std.view.prototype = new Tag();
Top.registerTag(std.view,"view");
std.view.prototype.apply = function() {
    var target = document.body; 
    if (this.attrs.target) {
        target = document.getElementById(this.attrs.target);
    }
//    Top.debug("VIEW: target="+this.attrs.target+" target="+target);
    var text = this.showBody(target);
    target.innerHTML = text;
    while (std.includes.length > 0) {
        var includeObj = std.includes.shift();
        includeObj.loadFile();
    }
    var name = this.attrs.name;
    //Top.debug("-------- View name="+name+" ---------");
    //Top.showSource();
    //Top.debug("-----------------------------------");
    if (name) {
        if (dhtmlHistory) {
            dhtmlHistory.add(name,null);
        }
        var action = std.viewActions[name];
        if (action) action();
    }
    if (std.expandTimeoutKey) clearTimeout(this.timeoutKey);
    std.expandTimeoutKey = setTimeout("std.adjustBody();",100);
}

std.include = function() {}
std.include.nextIdNum = 0;
std.include.prototype = new Tag();
Top.registerTag(std.include,"include");
std.include.prototype.show = function() {
    std.includes.push(this);
    std.include.nextIdNum++;
    this.idNum = std.include.nextIdNum;
    return "<div id='_INCLUDE_"+this.idNum+"'>INCLUDE-"+this.idNum+"</div>";
}
std.include.prototype.loadFile = function() {
//    std.prompt1(this,"INCLUDE file="+this.attrs.file);
    Top.loadText(this.attrs.file,this);
//    std.prompt1(this,"INCLUDE file="+this.attrs.file+" LOADED");
}
std.include.prototype.applyText = function(text) {
//    Top.debug("include.applyText id="+this.idNum);
    var divItem1 = document.getElementById("_INCLUDE_"+this.idNum);
    if (! divItem1) return; // May have loaded new page with open request
    if (this.attrs.entify) {
        text = text.replace(/&/g,"&amp;")
                   .replace(/</g,"&lt;")
                   .replace(/>/g,"&gt;");
    }
    if (this.attrs.box) {
        text = "<div style='margin-left:20px; border:thin solid black; background-color:white;'>"
             + "<pre style='margin:15px;'>"+text+"</pre></div>";
    }
    //Top.debug("INCLUDE: TXT="+text);
    divItem1.innerHTML = text;
    std.prompt2(this,"CALLING EXPAND (INCLUDE)...");
    if (std.expandTimeoutKey) clearTimeout(this.timeoutKey);
    std.expandTimeoutKey = setTimeout("std.adjustBody();",100);
}

// This generates a standard footer which contains some useful
// debuggging help.
//
std.footer = function() {}
std.footer.prototype = new Tag();
std.footer.prototype.show = function() {
    return "<div class='footer'>\n"
         + "  <div class='buttonLine'>\n"
         + "    <input type='button' value='Show HTML' onclick='Top.showSource();;'/>\n"
         + "  </div>\n"
         + "  <div class='buttonLine'>\n"
         + "    <div class='spacer'></div>\n"
         + "    <div id='messageBox'></div>\n"
         + "    <div class='spacer'></div>\n"
         + "  </div>\n"
         + "</div>\n";
}

std.banner = function() {}
std.banner.prototype = new Tag();
std.banner.prototype.show = function() {
    // Create a table that divides the banner up into two parts and puts
    // the title to the left of the left part and any contained elements
    // to the right of the right part.
    var buf = "<table style='width:100%;'";
    if (this.attrs.cls) buf += " class='"+this.attrs.cls+"'";
    buf += "><tr><td style='width:50%; text-align:left;'>"
    if (this.attrs.title) buf += "<span>"+this.attrs.title+"</span>";
    buf += "</td><td style='width:50%; text-align:right;'>";
    for (var i=0; i<this.tags.length; i++) {
        //Top.debug("banner: tags["+i+"]="+this.tags[i]);
        if (this.tags[i].show) buf += this.tags[i].show();
    }
    buf += "</td></tr></table>\n";
    return buf;
}

std.link = function() {}
std.link.prototype = new Tag();

std.link.prototype.show = function() {
    var hoverFgColor = "null";
    var hoverBgColor = "null";
    if (this.attrs.hoverFgColor) hoverFgColor = "\""+this.attrs.hoverFgColor+"\"";
    if (this.attrs.hoverBgColor) hoverBgColor = "\""+this.attrs.hoverBgColor+"\"";
    var buf = "<span";
    for (var attr in this.attrs) {
        if ((attr != "hoverFgColor") && (attr != "hoverBgColor")) {
            buf += " "+attr+"='"+this.attrs[attr]+"'";
        }
    }
    return buf + " onmouseover='std.doMouseOver(this,"+hoverFgColor+","+hoverBgColor+");'"
               + " onmouseout='std.doMouseOut(this);'>"+this.showBody()+"</span>\n";
}    


std.monthName = ['Jan','Feb','Mar','Apr','May','Jun'
                ,'Jul','Aug','Sep','Oct','Nov','Dec'];
std.msPerDay = 24 * 3600000;

// Register it three ways for flexibility.
std.component = function() {}
std.component.prototype = new Tag();
std.component.prototype.applyAttrs = function() {
    return std.applyAttrs(this.attrs);
}
// Move an attribute from this.attrs to this
std.component.prototype.extract = function(attr,val) {
    if (this.attrs[attr]) {
        this[attr] = this.attrs[attr];
        delete this.attrs[attr];
    } else if (val) {
        this[attr] = val;
    }
}
std.component.prototype.extractQualified = function(prefix) {
    var qualAttrs = {}
    for (var attr in this.attrs) {
        if (attr.substring(0,prefix.length) == prefix) {
            qualAttrs[attr.substring(prefix.length)] = this.attrs[attr];
            delete this.attrs[attr];
        }
    }
    return qualAttrs;
}
std.component.prototype.handleTitle = function() {
   var buf = "";
   this.extract("title");
   var caption = null;
   for (var i=0; i<this.tags.length; i++) {
       var item = this.tags[i];
       if (item instanceof std.caption) {
           caption = item;
           this.tags.splice(i,1);
           break;
       }
       if (item instanceof Tag) break;
   }
   if (this.title) {
       this.captionAttrs = this.extractQualified("caption.");
       if (caption == null) {
            caption = new std.caption();
            caption.initAttrs();
            caption.parent = this;
       }
   }
   if (caption != null) buf = caption.show();
   return buf;
}
std.component.prototype.mergeAttributes = function(attrs) {
    for (var attr in attrs) {
        if (! (attr in this.attrs)) this.attrs[attr] = attrs[attr];
    }
}

std.component.prototype.getStyles = function() {
    var styles = sty.getCssStyle(this);
//        Top.debug("BOX(CSS): id="+this.id+" nodeName="+this.nodeName+" className="+this.className+" styles="+this.style);
    if (this.attrs.style) {
        if (styles) this.attrs.style = styles + this.attrs.style;
    } else if (styles) {
        this.attrs.style = styles;
    }
}

std.evalScript = function() {}
std.evalScript.prototype = new std.component();
std.evalScript.prototype.apply = function() {
    var text = "";
    for (var i=0; i<this.tags.length; i++) {
        var item = this.tags[i];
        if (item instanceof String) text += item;
    }
    eval(Top.deentify(text));
}

std.textLabel = function() {}
std.textLabel.idnum = 1;
std.textLabel.prototype = new std.component();
std.textLabel.prototype.show = function() {
    this.name = this.attrs.name;
    this.value = this.attrs.value;
    if (this.attrs.name) {
        std.app[this.attrs.name] = this;
    }
    
    if (! this.attrs.id) {
        this.attrs.id = "lab_"+std.textLabel.idnum;
        std.textLabel.idnum++;
    }
    this.id = this.attrs.id;
    var buf = "<span"+this.applyAttrs()+">";
    if (this.value) buf += this.value;
    buf += "</span>\n";
    return buf;
}
std.textLabel.prototype.setValue = function(val) {
    this.value = val;
    if (! this.item) this.item = document.getElementById(this.id);
    this.item.innerHTML = val;
}
    

std.groupbox = function() {}
std.groupbox.prototype = new std.component();
std.groupbox.prototype.show = function() {
   var buf = "<fieldset" + this.applyAttrs() + ">\n";
   buf += this.handleTitle();
   for (var i=0; i<this.tags.length; i++) {
       var item = this.tags[i];
       if (item instanceof Tag) {
           buf += item.show();
       } else {
           buf += item;
       }
   }
   buf += "</fieldset>";
   return buf;
}

std.caption = function() {}
std.caption.prototype = new std.component();
std.caption.prototype.show = function() {
    var buf = "";
    this.extract("label");
    if (this.parent.title) {
        if (this.label) {
            this.label = this.parent.title + " - " + this.label;
        } else {
            this.label = this.parent.title;
        }
    }
    this.getStyles();
    if (this.parent instanceof std.window) {
        buf = "<tr><td" + this.applyAttrs() + ">" + this.label+"</td></tr>\n";
    } else if (this.parent instanceof std.groupbox) {
        buf = "<legend "+this.applyAttrs()+">"+this.label+"</legend>\n";
    }
    return buf;
}

std.parseStyles = function(text) {
    var styles = {};
    if (text) {
        var list = text.toLowerCase().split(";");
        for (var i=0; i<list.length; i++) {
            var style = list[i];
            var n = style.indexOf(":");
            if (n <= 0) continue;
            var m = 0;
            while ((style.charAt(m) == ' ') || (style.charAt(m) == '\t')) m++;
            var k = n + 1;
            while ((style.charAt(k) == ' ') || (style.charAt(k) == '\t')) k++;
            styles[style.substring(m,n)] = style.substring(k);
        }
    }
    return styles;
}

std.showStyles = function(styles) {
    var buf = "";
    if (styles) {
        for (var style in styles) {
            if (style.length > 0) {
                buf += style+":"+styles[style]+";";
            }
        }
    }
    return buf;
}

std.showStyleAttr = function(styles) {
    var buf = std.showStyles(styles);
    if (buf.length == 0) return "";
    return " style='"+buf+"'";
}

std.getIntAttribute = function(tag,name) {
    var val = tag.getAttribute(name);
    if (! val) return -1;
    return parseInt(val);
}

std.borderVal = function(text) {
    text = text.toUpperCase();
    if (text == "THIN") return 2;
    if (text == "MEDIUM") return 4;
    if (text == "THICK") return 6;
    if (text.indexOf("PX") >= 0) return parseInt(text);
    return 0;
}

std.getVerticalBorder = function(tag) {
    if (! tag.currentStyle) {
        tag.currentStyle = window.getComputedStyle(tag,null);
    }
    var val = 0;
    if (tag.currentStyle.borderTopWidth) val += std.borderVal(tag.currentStyle.borderTopWidth);
    if (tag.currentStyle.borderBottomWidth) val += std.borderVal(tag.currentStyle.borderBottomWidth);
    return val;
}

std.getHorizontalBorder = function(tag) {
    if (! tag.currentStyle) {
        tag.currentStyle = window.getComputedStyle(tag,null);
    }
    var val = 0;
    if (tag.currentStyle.borderLeftWidth) val += std.borderVal(tag.currentStyle.borderLeftWidth);
    if (tag.currentStyle.borderRightWidth) val += std.borderVal(tag.currentStyle.borderRightWidth);
    return val;
}

std.boxInit = function(tag,buf) {
    tag.boxInitialized = true;
    tag.percentHeight = std.getIntAttribute(tag,"percentheight");
    tag.percentWidth = std.getIntAttribute(tag,"percentwidth");
    tag.minHeight = std.getIntAttribute(tag,"minheight");
    tag.maxHeight = std.getIntAttribute(tag,"maxheight");
    tag.minWidth = std.getIntAttribute(tag,"minwidth");
    tag.maxWidth = std.getIntAttribute(tag,"maxwidth");
    tag.horizontalBorder = std.getHorizontalBorder(tag);
    tag.verticalBorder = std.getVerticalBorder(tag);
    tag.autoWidth = tag.getAttribute("autowidth");
    tag.autoHeight = tag.getAttribute("autoheight");
//    if (buf) buf += "{"+tag.nodeName+" pcW/H="+tag.percentWidth+"/"+tag.percentHeight+"}";
    return buf;
}

std.checkPx = function(tag,from,val) {
    var ival = parseInt(val);
    if (ival < 0) ival = 0;
    tag.lastPx = ival;
    tag.lastPxVal = val;
    tag.lastPxFrom = from;
    return ival + "px";
}

std.adjustCount = 0;
std.adjustBody = function() {
//    Top.debug("ADJUST "+std.adjustCount);
    std.adjustCount++;
    var body = document.body;
    var html = body.parentNode;
    std.shrinkTables(body);
    html.style.height = "0px";
    body.style.height = "0px";
    std.adjustTables(body);
    body.style.height = "100%";
    html.style.height = "100%";
}

std.adjustTables = function(tag) {
    if (tag.nodeName == 'TABLE') {
        var boxKind = tag.getAttribute("boxkind");
        var myTdNode = std.findParent(tag,"TD");
        if (myTdNode == null) std.findParent(tag,"BODY");
        var buf = "";
        if (myTdNode && (boxKind == "hbox")) {
            var savedHeight = myTdNode.style.height;
            myTdNode.style.height = "0px";
            var myWidth = std.getWidth(tag);
            var tdWidth = std.getWidth(myTdNode);
            var space = std.getWidth(myTdNode) - std.getHorizontalBorder(tag);
            var space = tdWidth - std.getHorizontalBorder(tag);
            var totalPercent = 0;
            var fillCount = 0;
            var fillPercent = 0;
            var percentCount = 0;
            var trNode = std.findFirstTrNode(tag);
            var tdNode = std.findFirst(trNode,"TD");
            while (tdNode) { 
                var percentWidth = tdNode.getAttribute("percentwidth");
                if (percentWidth) {
                    percentCount++;
                    buf += " "+percentWidth;
                    if (percentWidth == "fill") {
                        fillCount++;
                    } else {
                        totalPercent += parseInt(percentWidth);
                    }
                } else {
                    buf += " "+std.getWidth(tdNode)+"PX";
                    space -= std.getWidth(tdNode);
                }
                tdNode = std.findNext(tdNode,"TD");
            }
            if ((fillCount > 0) && (totalPercent < 100)) {
                fillPercent = (100 - totalPercent) / fillCount;
                totalPercent = 100;
            } else if (totalPercent < 100) {
                totalPercent = 100;
            }
            var maxHeight = 0;
            var width = 0;
            var spaceUsed = 0;
            buf = "";
            tdNode = std.findFirst(trNode,"TD");
            while (tdNode) { 
                var percentWidth = tdNode.getAttribute("percentwidth");
                if (percentWidth) {
//                    var borderVal = 0;
                    if (percentWidth == "fill") {
                        width = Math.round(fillPercent / totalPercent * space);
                    } else {
                        width = Math.round(parseInt(percentWidth) / totalPercent * space);
//                        if (std.isIE) {
//                            var tableNode = std.findFirst(tdNode,"TABLE");
//                            if (tableNode) {
//                                borderVal = std.getHorizontalBorder(tableNode);
//                            }
//                        }
                        
                    }
                    spaceUsed += width;
                    percentCount--;
//                    if (borderVal > 0) {
//                        width -= borderVal;
//                    }
                    if((percentCount == 0) && (spaceUsed != space)) {
                        width += Math.round(space - spaceUsed);
                    }
                    buf += " "+percentWidth+":"+width;
                    tdNode.style.width = width + "px";
                } else {
                    buf += " "+std.getWidth(tdNode);
                }
                var tdHeight = std.getHeight(tdNode);
                if (tdHeight > maxHeight) maxHeight = tdHeight;
                tdNode = std.findNext(tdNode,"TD");
            }
            myTdNode.style.height = savedHeight;
        } else if (myTdNode && (boxKind == "vbox")) {
            var savedWidth = myTdNode.style.width;
//            myTdNode.style.width = "0px";
            var tdHeight = std.getHeight(myTdNode);
            var myHeight = std.getHeight(tag);
            var firstTrNode = std.findFirstTrNode(tag);
            // Space to use for Percent heights is the height of the TD
            // minus the vertical border minus all the non-percent elements.
            var space = tdHeight - std.getVerticalBorder(tag);
            var totalPercent = 0;
            var fillCount = 0;
            var fillPercent = 0;
            var percentCount = 0;
            for (var trNode=firstTrNode; trNode; trNode=std.findNext(trNode,"TR")) {
                var tdNode = std.findFirst(trNode,"TD");
                var percentHeight = tdNode.getAttribute("percentheight");
                if (percentHeight) {
                    percentCount++;
                    buf += " "+percentHeight;
                    if (percentHeight == "fill") {
                        fillCount++;
                    } else {
                        totalPercent += parseInt(percentHeight);
                    }
                } else {
                    buf += " "+std.getHeight(tdNode)+"PX";
                    space -= std.getHeight(tdNode);
                }
            }
//            if (percentCount > 0) {
//                tag.style.height = "100%";
//            }
            if (! tag.currentStyle) {
                tag.currentStyle = window.getComputedStyle(tag,null);
            }
            var borderTop = tag.currentStyle.borderTopWidth; 
            var borderBottom = tag.currentStyle.borderBottomWidth; 
            if ((fillCount > 0) && (totalPercent < 100)) {
                fillPercent = (100 - totalPercent) / fillCount;
                totalPercent = 100;
            } else if (totalPercent < 100) {
                totalPercent = 100;
            }
            var height = 0;
            var spaceUsed = 0;
            buf = "";
            for (var trNode=firstTrNode; trNode; trNode=std.findNext(trNode,"TR")) {
                var tdNode = std.findFirst(trNode,"TD");
                var percentHeight = tdNode.getAttribute("percentheight");
                if (percentHeight) {
                    var borderVal = 0;
                    if (percentHeight == "fill") {
                        height = Math.round(fillPercent / totalPercent * space);
                        buf += " "+height;
                    } else {
                        height = Math.round(parseInt(percentHeight) / totalPercent * space);
                        if (std.isIE) {
                            var tableNode = std.findFirst(tdNode,"TABLE");
                            if (tableNode) {
                                borderVal = std.getVerticalBorder(tableNode);
                            }
                        }
                        buf += " "+height;
                    }
                    spaceUsed += height;
                    percentCount--;
                    if (borderVal > 0) {
                        buf += "-"+borderVal;
                        height -= borderVal;
                    }
                    if ((percentCount == 0) && (spaceUsed != space)) {
                        buf += "+"+(space-spaceUsed);
                        height += Math.round(space - spaceUsed);
                    }
                    tdNode.style.height = height + "px";
                }
            }
        }
    }
    var children = tag.childNodes;
    for (var i=0; i<children.length; i++) {
        var child = children[i];
        if (child.nodeType == 1) {
            std.adjustTables(child);
        }
    }
        
}
    
std.shrinkTables = function(tag) {
    if (tag.nodeName == 'BODY') {
        if (! tag.currentStyle) {
            tag.currentStyle = window.getComputedStyle(tag,null);
        }
//        std.prompt(tag," W/H="+std.getWidth(tag)+"/"+std.getHeight(tag)
//                  +" s.w/h="+tag.style.width+"/"+tag.style.height
//                  +" cs.w/h="+tag.currentStyle.width+"/"+tag.currentStyle.height);
    } else if (tag.nodeName == 'TABLE') {
        var boxKind = tag.getAttribute("boxkind");
        var myTdNode = std.findParent(tag,"TD");
        if (myTdNode == null) std.findParent(tag,"BODY");
        var anyPercentHeights = false;
        if (myTdNode && boxKind) {
            var firstTrNode = std.findFirstTrNode(tag);
            for (var trNode=firstTrNode; trNode; trNode=std.findNext(trNode,"TR")) {
                var tdNode = std.findFirst(trNode,"TD");
                while (tdNode) {
                    var percentHeight = tdNode.getAttribute("percentheight");
                    if (percentHeight) {
                        anyPercentHeight = true;
                        if (percentHeight == "fill") {
                            if (std.isIE) {
                                tdNode.style.height = "0%";
                            } else {
                                tdNode.style.height = "100%";
                            }
                        } else {
                            tdNode.style.height = percentHeight + "%";
                        }
                    }
                    var percentWidth = tdNode.getAttribute("percentwidth");
                    if (percentWidth) {
                        if (percentWidth == "fill") {
                            tdNode.style.width = "100%";
                        } else {
                            tdNode.style.width = percentWidth + "%";
                        }
                    }
                    tdNode = std.findNext(tdNode,"TD");
                }
            }
//            if ((myTdNode.nodeName == "TD") && anyPercentHeights) {
//                var height = tag.style.height;
//                if (height && (height.indexOf("%") >= 0)) {
//                    tag.style.height = "0px";
//                    std.prompt1(tag,"SHRINK height="+height+"/"+std.getHeight(tag));
//                    tag.style.height = height;
//                }
//            }
        }
    }
    var children = tag.childNodes;
    for (var i=0; i<children.length; i++) {
        var child = children[i];
        if (child.nodeType == 1) {
            std.shrinkTables(child);
        }
    }
        
}
    
std.tdStyleNames = ['margin','margin-left','margin-right','margin-top','margin-bottom'
                   ,'padding','padding-left','padding-right','padding-top','padding-bottom'];

                   
// Box special handling:
//
// VBOX allows a single column of Cells.  When a BOX is placed in a VBOX,
// it may have a percent height which will be taken to be the percent of
// space remaining after all non-percent heights are alocated. Any item
// put into a VBOX that is not a BOX, will use whatever height adjustment
// is provided by the Browser. Width may be specified within a VBOX as long
// as the width of the VBOX itself is fixed or determined by some cell other
// than the one(s) that use percent width.
//
// HBOX allows a single row of cells. When a BOX is placed in an HBOX, it
// may have a percent width which will be taken to be the percent of
// space remaining after all non-percent widths are allocated.
//
std.box = function() {}
std.box.prototype = new std.component();
std.box.prototype.showInHBox = function(attrs) {
//    this.inTd = true;
    this.tdAttrs = "";
    if (attrs) this.tdAttrs = attrs;
    this.inHBox = true;
    return this.show();
}
std.box.prototype.showInVBox = function(attrs) {
//    this.inTr = true;
    this.tdAttrs = "";
    if (attrs) this.tdAttrs = attrs;
    this.inVBox = true;
    return this.show();
}
std.box.prototype.show = function(parentTag) {
    this.parentNode = parentTag;
    if (this.attrs.kind) {
        this.kind = this.attrs.kind;
    } else {
        this.kind = this.tagName;
        var n = this.kind.indexOf(':');
        if (n > 0) this.kind = this.kind.substring(n+1);
    }
    if (this.attrs["class"]) {
        this.className = this.attrs["class"];
        delete this.attrs["class"];
    }
    if (this.attrs.id) {
        this.id = this.attrs.id;
        delete this.attrs.id;
    }
    var buf = "";
    this.getStyles();
    this.extract("style");
    var styles = std.parseStyles(this.style);
    if ((this.kind == "spacer") && ! styles.height) {
        styles.height = "100%";
    }
    if (this.inVBox || this.inHBox) {
        buf += "<td"+this.tdAttrs;
        if (this.inHBox) {
            buf += " style='height:100%;";
            if (styles.width) {
                if (styles.width.indexOf("%") >= 0) {
                    buf += " width:0%;'";
                    buf += " percentwidth='"+parseInt(styles.width)+"'";
                } else {
                    buf += " width:"+styles.width+";";
                }
                styles.width = "100%";
            }
        } else {
            buf += " style='width:100%;";
            if (styles.height) {
                if (styles.height.indexOf("%") >= 0) {
                    buf += " height:0%;'";
                    buf += " percentheight='"+parseInt(styles.height)+"'";
                } else {
                    buf += " height:"+styles.height+"'";
                }
                styles.height = "100%";
            }
        }
        buf += "'>";
    }
    buf += "<table cellspacing='0' cellpadding='0'"
    if (this.className) buf += " class='"+this.className+"'";
    if (this.id) buf += " id='"+this.id+"'";
    buf += " boxkind='"+this.kind+"'";
    var valign = "";
    var halign = "";
    
    if (styles["vertical-align"]) {
        valign = " valign='"+styles["vertical-align"]+"'";
        delete styles["vertical-align"];
    }
    if (styles["text-align"]) {
        halign = " align='"+styles["text-align"]+"'";
        delete styles["text-align"];
    }
    var theStyle = "border-width:0px; " + std.showStyles(styles);
    if (theStyle.length > 0) {
        buf += " style='"+theStyle+"'";
    }
    buf += ">";
    if (this.kind == "vbox") {
        for (var i=0; i<this.tags.length; i++) {
            var item = this.tags[i];
            if (item instanceof Tag) {
                buf += "<tr>"+item.showInVBox(halign)+"</tr>\n";
            } else if (item.match(/\S/)) {
                buf += "<tr><td style='width:100%;' align='"+halign+"'>"+item+"</td></tr>\n";
            }
        }
    } else if (this.kind == "hbox") {
        buf += "<tr"+valign+">";
        for (var i=0; i<this.tags.length; i++) {
            var item = this.tags[i];
            if (item instanceof Tag) {
                buf += item.showInHBox(valign)+"\n";
            } else if (item.match(/\S/)) {
                buf += "<td style='height:100%;'"+valign+">"+item+"</td>\n";
            }
        }
        buf += "</tr>";
    } else {
        if (this.kind == "window") buf += this.handleTitle();
        var align = "";
        if (halign.length > 0) align = " align='"+halign+"'";
        if (valign.length > 0) align += " valign='"+valign+"'";
        buf += "<tr"+valign+"><td"+halign+" style='height:100%;'>";
        var anyContent = false;
        for (var i=0; i<this.tags.length; i++) {
            var item = this.tags[i];
            if (item instanceof Tag) {
                anyContent = true;
                buf += item.show();
            } else if (item.match(/\S/)) {
                anyContent = true;
                buf += item;
            }
        }
        if (! anyContent) buf += "&nbsp;";
        buf += "</td></tr>";
    }
    buf += "</table>";
    if (this.inVBox || this.inHBox) {
        buf += "</td>";
    }
    buf += "\n";
//    Top.debug("BOX ID="+this.id+" kind="+this.kind+" inH/VBox="+this.inHBox+"/"+this.inVBox+" BUF=["+buf+"]");
    return buf;
}

std.vbox = function() {}
std.vbox.prototype = new std.box();

std.hbox = function() {}
std.hbox.prototype = new std.box();

std.window = function() {}
std.window.prototype = new std.box();

std.spacer = function() {}
std.spacer.prototype = new std.component();
std.spacer.prototype.show = function(parentTag) {
    return "<div style='width:100%; height:100%;'></div>";
}
std.spacer.prototype.showInHBox = function(attrs) {
    return "<td percentwidth='fill' style='width:0%; height:100%;'></td>";
}
std.spacer.prototype.showInVBox = function(attrs) {
    return "<td percentheight='fill' style='height:0%; width:100%;'></td>";
}

std.textbox = function() {}
std.textbox.prototype = new std.component();
std.textbox.prototype.show = function() {
    var buf = "";
    if (this.attrs.rows || this.attrs.cols) {
        var val = " ";
        if (this.attrs.value) val = this.attrs.value;
        buf = "<textarea"+this.applyAttrs()+">"+val+"</textarea>\n";
    } else {
        buf = "<input type=\"text\""+this.applyAttrs()+"/>\n";
    }
    return buf;
}

std.intbox = function() {}
std.intbox.prototype = new std.component();
std.intbox.prototype.show = function() {
    if (! this.attrs.onkeydown) this.attrs.onkeydown = "return std.doNumKeypress(event,this,false);";
    if (this.attrs.style) {
        this.attrs.style = "text-align:right;"+this.attrs.style;
    } else {
        this.attrs.style = "text-align:right;";
    }
    var buf = "<input type=\"textbox\""+this.applyAttrs()+"/>\n";
    return buf;
}

std.decimalbox = function() {}
std.decimalbox.prototype = new std.component();
std.decimalbox.prototype.show = function() {
    if (! this.attrs.onkeydown) this.attrs.onkeydown = "return std.doNumKeypress(event,this,true);";
    this.getStyles();
    if (this.attrs.style) {
        this.attrs.style = "text-align:right;"+this.attrs.style;
    } else {
        this.attrs.style = "text-align:right;";
    }
    return "<input type=\"textbox\""+this.applyAttrs()+"/>\n";
}

std.grid = function() {}
std.grid.prototype = new std.component();
std.grid.prototype.init = function() {
    this.columns = [];
}
std.grid.prototype.addColumn = function(col) {
    this.columns[this.columns.length] = col;
}
std.grid.prototype.getColumn = function(colIndex) {
    if (! this.columns) return null;
    return this.columns[colIndex];
}
std.grid.prototype.show = function() {
    if (! this.attrs.cellspacing) this.attrs.cellspacing = '0';
    if (! this.attrs.cellpadding) this.attrs.cellpadding = '0';
    var buf = "<table"+this.applyAttrs()+">\n";
    if (! this.tags) {
        return "";
    }
    for (var i=0; i<this.tags.length; i++) {
        var item = this.tags[i];
        if (item instanceof std.row) {
            buf += item.show();
        }
    }
    buf += "</table>\n";
    return buf;
}

std.col = function() {}
std.col.prototype = new std.component();
std.col.prototype.apply = function() {
    if (this.parent.addColumn) {
        this.parent.addColumn(this);
    }
}

std.row = function() {}
std.row.prototype = new std.component();
std.row.prototype.show = function() {
    var buf = "<tr"+this.applyAttrs()+">";
    var colIndex = 0;
    for (var i=0; i<this.tags.length; i++) {
        var item = this.tags[i];
        if (item instanceof Tag) {
            var col = this.parent.getColumn(colIndex);
            if ((item.attrs.colspan) && (item.attrs.colspan > 0)) {
                colIndex += this.attrs.colspan;
            } else {
                colIndex++;
            }
            if (col != null) {
                item.mergeAttrs(col.attrs);
            }
            buf += "<td"+std.useAttr(item,"rowspan")
                        +std.useAttr(item,"colspan")+">"+item.show()+"</td>";
        }
    }
    buf += "</tr>\n";
    return buf;
}

std.attribute = function() {}
std.attribute.prototype = new std.component();
std.attribute.prototype.apply = function() {
    var text = "";
    for (var i=0; i<this.tags.length; i++) {
        var item = this.tags[i];
        if (item instanceof String) text += item;
    }
    if (this.parent) this.parent.attrs[this.attrs.name] = text;
}

std.styleRule = function() {}
std.styleRule.prototype = new Tag();
std.styleRule.prototype.apply = function() {
    var selector = this.attrs.selector;
    var rule = this.attrs.rule;
    if (! rule) rule = this.showBody();
    if (rule) rule = rule.replace(/\n/g,"");
    sty.addRule(selector,rule);
}
    
// This defines style so we can intercept it and force reevaluation
// of styles.
std.style = function() {}
std.style.prototype = new Tag();
std.style.prototype.show = function(parent) {
    sty.mapInitialized = false; // force styles to be reanalyzed
    if (document.createStyleSheet) {
        var styleText = this.showBody();
        std.prompt2(this,"USING createStyleSheet style="+styleText);
        var styleObj = document.createStyleSheet();
    } else {        
        var htmlText = Tag.prototype.show.apply(this,[parent]);
        std.prompt2(this,"CREATING STYLE text=["+htmlText+"]");
        var divObj = document.createElement("DIV");
        std.prompt2(this,"APPENDING DIV");
        document.body.appendChild(divObj);
            
        std.prompt2(this,"INSERTING STYLE");
        divObj.innerHTML = htmlText;
    }
    sty.getStyleMap();
    return "";
}
    
std.combobox = function() {}
std.combobox.prototype = new std.component();
std.combobox.idnum = 1;
// Show the Text Box for holding the date and the button for expanding the
// calendar.
std.combobox.prototype.show = function() {
    this.name = "combo_"+std.combobox.idnum;
    std[this.name] = this;
    std.combobox.idnum++;
    this.getStyles();
    this.extract("size",10);
    if (! std.imagePath) std.imagePath = "images"; // take a guess
    var buf = "<table cellspacing='0' cellpadding='0'><tr valign='middle'>"
        + "<td><input type='text'" + this.applyAttrs()
        + " onkeydown='return std."+this.name+".doKeypress(event);'/></td>"
        + "<td valign='bottom'><input type='image' src='"+std.imagePath+"/expandButton.gif'"
        + " onblur='return std."+this.name+".onBlur();'"
        + " onclick='return std."+this.name+".expand(this);'/></td></tr></table>";
    this.divItem = document.createElement("DIV");
    this.divItem.style.display = "none";
    document.body.appendChild(this.divItem);
    this.divItem.innerHTML = "<select size='"+this.size+"' onclick='return std."+this.name+".onClick();'>"+this.showBody()+"</select>";
    return buf;
}
std.combobox.prototype.close = function() {
//    Top.debug("COMBO.close");
    if (this.divItem) this.divItem.style.display = "none";
}
std.combobox.prototype.onBlur = function() {
//    Top.debug("COMBO.onBlur");
    this.timeoutKey = setTimeout("std."+this.name+".close();",500);
    return true;
}
std.combobox.prototype.expand = function(item) {
    this.item = item;
    var myTd = std.findParent(item,"TD");
    var priorTd = std.findPrevious(myTd,"TD");
    this.textBox = std.findFirst(priorTd,"INPUT");
    var divItem = this.divItem;
    this.selItem = std.findFirst(divItem,"SELECT");
    var size = this.selItem.getAttribute("size");
    if (! size || (size < 2)) {
        size = 10;
    }
    if (this.selItem.options.length < size) size = this.selItem.options.length;
    this.selItem.setAttribute("size",size);
    
    var pos = std.getPosition(this.textBox);
    var ypos = pos.y + std.getHeight(this.textBox) + 3;
    divItem.style.position = "absolute";
    divItem.style.top = ypos + "px";
    divItem.style.left = pos.x + "px";
    divItem.style.display = "block";

    var height = std.getHeight(this.divItem);
    var lim = std.getLimits();
    if ((ypos + height + 5) >= lim.y) {
        ypos = pos.y - height - 5;
        this.divItem.style.top = ypos + "px";
    }
    return false;
}
std.combobox.prototype.onClick = function() {
//    Top.debug("COMBO.onClick");
    this.textBox.value = this.selItem.options[this.selItem.selectedIndex].value;
    return false;
}

std.calendar = function() {}
std.calendar.prototype = new std.component();
std.calendar.idnum = 1;
// Show the Text Box for holding the date and the button for expanding the
// calendar.
std.calendar.prototype.show = function() {
    this.name = "cal_"+std.calendar.idnum;
    std.calendar.idnum++;
    if (! std.imagePath) std.imagePath = "images"; // take a guess
    std[this.name] = this;
    this.getStyles();
    var buf = "<table><tr valign='middle'>"
            + "<td><input type='text'" + this.applyAttrs() 
            + " onblur='std."+this.name+".onBlur();'"
            + " onkeydown='return std."+this.name+".doKeypress(event);'/></td>"
            + "<td><input type='image' src='"+std.imagePath+"/calendarButton.gif'"
            + " onclick='return std."+this.name+".expand(this);'/></td></tr></table>";
    this.divItem = document.createElement("DIV");
    this.divItem.style.display = "none";
    this.divItem.style.zIndex = 5;
    document.body.appendChild(this.divItem);
    return buf;
}
// Expand the calendar. Set an initial date if provided or use Today.
std.calendar.prototype.expand = function(item) {
    this.item = item;
    var tr = std.findParent(item,"TR");
    var textTd = std.findFirst(tr,"TD");
    this.textBox = std.findFirst(textTd,"INPUT");
    this.date = new Date();
    if (this.textBox.value) {
        this.date.setTime(Date.parse(this.textBox.value));
    }
    this.showCalendar();
    return false;
}
// Set the Text Box with the current date from the Calendar.
std.calendar.prototype.updateDate = function() {
    this.textBox.value = this.date.toDateString();
    return false;
}
// Show the calendar with the specified date.
std.calendar.prototype.showCalendar = function() {
    if (this.timeoutKey) {
        clearTimeout(this.timeoutKey);
        this.timeoutKey = null;
    }
    var pos = std.getPosition(this.textBox);
    var lim = std.getLimits();
    if ((pos.y + 190) > lim.y) {
        pos.y -= 150;
    } else {
        pos.y += 30;
    }
    var buf = "<div style='font-size:8pt;border:solid thin blue;width:168px;"
            + " background-color:white;"
            + " position:absolute; left:"+pos.x+"px;top:"+pos.y+"px;'>"
            + "<table cellspacing='0' cellpadding='0'>"
            + "<tr style='background-color:lightBlue;'>"
            + "<td align='left' style='width:34px;'><input type='image' onclick='return std."+this.name+".onClickYear(-1);' src='"+std.imagePath+"/leftArrow.gif'/></td>"
            + "<td colspan='4' align='center' style='width:100px;'><span style='text-align:center; font-size:10pt;' id='"+this.name+"_monthAndYear'>"+std.monthName[this.date.getMonth()]+", "+this.date.getFullYear()+"</span></td>"
            + "<td align='right' style='width:34px;'><input type='image' onclick='return std."+this.name+".onClickYear(1);' src='"+std.imagePath+"/rightArrow.gif'/></td>"
            + "</tr>\n";
    for (var i=0; i<12; i++) {
        if ((i == 0) || (i == 6)) buf += "<tr style='font-size:8pt;'>";
        buf += "<td style='width:28px;'"
            +  " onmouseover='std."+this.name+".onMouseOver(this);'"
            +  " onmouseout='std."+this.name+".onMouseOut(this);'"
            +  " onclick='return std."+this.name+".onClickMonth("+i+");'>"+std.monthName[i]+"</td>";
        if ((i == 5) || (i == 11)) buf += "</tr>\n";
    }
    buf += "</table>\n"
        +  "<table cellspacing='0' cellpadding='0'"
        +  " style='font-size:8pt;width:168px;'><tr style='background-color:lightGrey;'>"
        +  "<td style='color:red; width:20px; text-align:right; padding-right:4px'>Sun</td>"
        +  "<td style='width:20px; text-align:right; padding-right:4px;'>Mon</td><td style='width:25px;'>Tue</td>"
        +  "<td style='width:20px; text-align:right; padding-right:4px;'>Wed</td><td style='width:25px;'>Thu</td>"
        +  "<td style='width:20px; text-align:right; padding-right:4px;'>Fri</td>"
        +  "<td style='color:red; width:20px; text-align:right; padding-right:4px'>Sat</td></tr>";
     
    // Find the first of the month, then back up to Sunday.
    var curDate = new Date(this.date.getFullYear(),this.date.getMonth(),1,8);
    var time = curDate.getTime();
    time -= curDate.getDay() * std.msPerDay;
    curDate.setTime(time);
    var n = 0;
    var dayOfMonth = this.date.getDate();
    var month = this.date.getMonth();
    for (;;) {
        if ((n % 7) == 0) buf += "<tr>";
        if (   (curDate.getDate() == dayOfMonth)
            && (curDate.getMonth() == month)  ) {
            buf += "<td style='background-color:lightBlue;";
        } else {
            buf += "<td style='"
        }
        var curDay = curDate.getDate();
        var curMonth = curDate.getMonth();
        buf += " text-align:right; width:18px; padding-right:6px;'"
            +  " onmouseover='return std."+this.name+".onMouseOver(this);'"
            +  " onmouseout='return std."+this.name+".onMouseOut(this);'"
            +  " onclick='return std."+this.name+".onClickDay("+curMonth+","+curDay+");'>"
            +  curDay + "</td>";
        time += std.msPerDay;
        curDate.setTime(time);
        if ((n % 7) == 6) {
            buf += "</tr>\n";
            if (curDate.getMonth() != month) break;
        }
        n++;
    }
    buf += "</table></div>\n";
    this.divItem.innerHTML = buf;
    this.divItem.style.display = "block";
    this.textBox.focus();
    return false;
}
std.calendar.prototype.onMouseOver = function(item) {
    item.style.textDecoration = 'underline';
    item.style.cursor = 'pointer';
    return false;
}
std.calendar.prototype.onMouseOut = function(item) {
    item.style.textDecoration = 'none';
    item.style.cursor = 'auto';
    return false;
}
std.calendar.prototype.onClickDay = function(month,date) {
    this.date.setDate(date);
    this.date.setMonth(month);
    return this.close();
}
std.calendar.prototype.onBlur = function() {
    // Take down the calendar in 500MS. This gives the onClickMonth() method
    // a chance to run if it was a Month key that caused the loss of focus.
    this.timeoutKey = setTimeout("std."+this.name+".close();",500);
    return false;
}
std.calendar.prototype.close = function() {
    this.divItem.style.display = 'none';
    this.updateDate();
    return false;
}
std.calendar.prototype.onClickMonth = function(month) {
    var dayOfMonth = this.date.getDate();
    this.date.setMonth(month);
    while (this.date.getDate() != dayOfMonth) {
        dayOfMonth--;
        this.date.setMonth(month);
        this.date.setDate(dayOfMonth);
    }
    this.updateDate();
    this.showCalendar();
    return false;
}
std.calendar.prototype.onClickYear = function(delta) {
    this.date.setYear(this.date.getFullYear()+delta);
    this.updateDate();
    this.showCalendar();
    return false;
}
std.calendar.prototype.doKeypress = function(e) {
    if (!e) e = window.event;
    var keyCode = 0;
    if (e.keyCode) {
        keyCode = e.keyCode;
    } else {
        keyCode = e.which;
    }
    if (keyCode == 37) { // left arrow
        this.date.setTime(this.date.getTime() - std.msPerDay);
    } else if (keyCode == 39) { // Right arrow
        this.date.setTime(this.date.getTime() + std.msPerDay);
    } else if (keyCode == 38) { // Up arrow
        this.date.setTime(this.date.getTime() - 7 * std.msPerDay);
    } else if (keyCode == 40) { // Down arrow
        this.date.setTime(this.date.getTime() + 7 * std.msPerDay);
    } else {
        return false;
    }
    this.updateDate();
    this.showCalendar();
    return false;
}



