// Determine browser and version.

function Browser() {

    var ua, s, i;

    this.isIE    = false;  // Internet Explorer
    this.isNS    = false;  // Netscape
    this.version = null;

    ua = navigator.userAgent;

    s = "MSIE";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isIE = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }

    s = "Netscape6/";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }

    // Treat any other "Gecko" browser as NS 6.1.

    s = "Gecko";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = 6.1;
        return;
    }
}

var browser = new Browser();

//=============================================================================
// Window Object
//=============================================================================

function Window(el) {

    var i, mapList, mapName;

    // Get window components.

    this.frame           = el;
    this.titleBar        = winFindByClassName(el, "titleBar");
    this.titleBarText    = winFindByClassName(el, "titleBarText");
    this.titleBarButtons = winFindByClassName(el, "titleBarButtons");
    this.clientArea      = winFindByClassName(el, "clientArea");

    // Find matching button image map.

    mapName = this.titleBarButtons.useMap.substr(1);
    mapList = document.getElementsByTagName("MAP");
    for (i = 0; i < mapList.length; i++)
        if (mapList[i].name == mapName)
            this.titleBarMap = mapList[i];

    // Save colors.

    this.activeFrameBackgroundColor  = this.frame.style.backgroundColor;
    this.activeFrameBorderColor      = this.frame.style.borderColor;
    this.activeTitleBarColor         = this.titleBar.style.backgroundColor;
    this.activeTitleTextColor        = this.titleBar.style.color;
    this.activeClientAreaBorderColor = this.clientArea.style.borderColor;
    if (browser.isIE)
        this.activeClientAreaScrollbarColor = this.clientArea.style.scrollbarBaseColor;

    // Save images.

    this.activeButtonsImage   = this.titleBarButtons.src;
    this.inactiveButtonsImage = this.titleBarButtons.longDesc;

    // Set flags.

    this.isOpen      = false;
    this.isMinimized = false;

    // Set methods.

    this.open       = winOpen;
    this.close      = winClose;
    this.minimize   = winMinimize;
    this.restore    = winRestore;
    this.makeActive = winMakeActive;

    // Set up event handling.

    this.frame.parentWindow = this;
    this.frame.onmousemove  = winResizeCursorSet;
    this.frame.onmouseout   = winResizeCursorRestore;
    this.frame.onmousedown  = winResizeDragStart;

    this.titleBar.parentWindow = this;
    this.titleBar.onmousedown  = winMoveDragStart;

    this.clientArea.parentWindow = this;
    this.clientArea.onclick      = winClientAreaClick;

    for (i = 0; i < this.titleBarMap.childNodes.length; i++)
        if (this.titleBarMap.childNodes[i].tagName == "AREA")
            this.titleBarMap.childNodes[i].parentWindow = this;

    // Calculate the minimum width and height values for resizing
    // and fix any initial display problems.

    var initLt, initWd, w, dw;

    // Save the inital frame width and position, then reposition
    // the window.

    initLt = this.frame.style.left;
    initWd = parseInt(this.frame.style.width);
    this.frame.style.left = -this.titleBarText.offsetWidth + "px";

    // For IE, start calculating the value to use when setting
    // the client area width based on the frame width.

    if (browser.isIE) {
        this.titleBarText.style.display = "none";
        w = this.clientArea.offsetWidth;
        this.widthDiff = this.frame.offsetWidth - w;
        this.clientArea.style.width = w + "px";
        dw = this.clientArea.offsetWidth - w;
        w -= dw;
        this.widthDiff += dw;
        this.titleBarText.style.display = "";
    }

    // Find the difference between the frame's style and offset
    // widths. For IE, adjust the client area/frame width
    // difference accordingly.

    w = this.frame.offsetWidth;
    this.frame.style.width = w + "px";
    dw = this.frame.offsetWidth - w;
    w -= dw;
    this.frame.style.width = w + "px";
    if (browser.isIE)
        this.widthDiff -= dw;

    // Find the minimum width for resize.

    this.isOpen = true;  // Flag as open so minimize call will work.
    this.minimize();
    // Get the minimum width.
    if (browser.isNS && browser.version >= 1.2)
        // For later versions of Gecko.
        this.minimumWidth = this.frame.offsetWidth;
    else
        // For all others.
        this.minimumWidth = this.frame.offsetWidth - dw;

    // Find the frame width at which or below the title bar text will
    // need to be clipped.

    this.titleBarText.style.width = "";
    this.clipTextMinimumWidth = this.frame.offsetWidth - dw;

    // Set the minimum height.

    this.minimumHeight = 1;

    // Restore window. For IE, set client area width.

    this.restore();
    this.isOpen = false;  // Reset flag.
    initWd = Math.max(initWd, this.minimumWidth);
    this.frame.style.width = initWd + "px";
    if (browser.isIE)
        this.clientArea.style.width = (initWd - this.widthDiff) + "px";

    // Clip the title bar text if needed.

    if (this.clipTextMinimumWidth >= this.minimumWidth)
        this.titleBarText.style.width = (winCtrl.minimizedTextWidth + initWd - this.minimumWidth) + "px";

    // Restore the window to its original position.

    this.frame.style.left = initLt;
}

//=============================================================================
// Window Methods
//=============================================================================

function winOpen() {

    if (this.isOpen)
        return;

    // Restore the window and make it visible.

    this.makeActive();
    this.isOpen = true;
    if (this.isMinimized)
        this.restore();
    this.frame.style.visibility = "visible";
    this.frame.style.display = "block";
    this.frame.style.position = "fixed";

    this.frame.style.left = 200;
    this.frame.style.top = 150;
}

function winClose()
{

    // Hide the window.
    
    this.frame.style.visibility = "hidden";
    this.frame.style.display = 'none';
    this.isOpen = false;
}

function winMinimize() {

    if (!this.isOpen || this.isMinimized)
        return;

    this.makeActive();

    // Save current frame and title bar text widths.

    this.restoreFrameWidth = this.frame.style.width;
    this.restoreTextWidth = this.titleBarText.style.width;

    // Disable client area display.

    this.clientArea.style.display = "none";

    // Minimize frame and title bar text widths.

    if (this.minimumWidth)
        this.frame.style.width = this.minimumWidth + "px";
    else
        this.frame.style.width = "";
    this.titleBarText.style.width = winCtrl.minimizedTextWidth + "px";

    this.isMinimized = true;
}

function winRestore() {

    if (!this.isOpen || !this.isMinimized)
        return;

    this.makeActive();

    // Enable client area display.

    this.clientArea.style.display = "";

    // Restore frame and title bar text widths.

    this.frame.style.width = this.restoreFrameWidth;
    this.titleBarText.style.width = this.restoreTextWidth;

    this.isMinimized = false;
}

function winMakeActive() {

    if (winCtrl.active == this)
        return;

    // Inactivate the currently active window.

    if (winCtrl.active) {
        winCtrl.active.frame.style.backgroundColor    = winCtrl.inactiveFrameBackgroundColor;
        winCtrl.active.frame.style.borderColor        = winCtrl.inactiveFrameBorderColor;
        winCtrl.active.titleBar.style.backgroundColor = winCtrl.inactiveTitleBarColor;
        winCtrl.active.titleBar.style.color           = winCtrl.inactiveTitleTextColor;
        winCtrl.active.clientArea.style.borderColor   = winCtrl.inactiveClientAreaBorderColor;
        if (browser.isIE)
            winCtrl.active.clientArea.style.scrollbarBaseColor = winCtrl.inactiveClientAreaScrollbarColor;
        if (browser.isNS && browser.version < 6.1)
            winCtrl.active.clientArea.style.overflow = "hidden";
        if (winCtrl.active.inactiveButtonsImage)
            winCtrl.active.titleBarButtons.src = winCtrl.active.inactiveButtonsImage;
    }

    // Activate this window.

    this.frame.style.backgroundColor    = this.activeFrameBackgroundColor;
    this.frame.style.borderColor        = this.activeFrameBorderColor;
    this.titleBar.style.backgroundColor = this.activeTitleBarColor;
    this.titleBar.style.color           = this.activeTitleTextColor;
    this.clientArea.style.borderColor   = this.activeClientAreaBorderColor;
    if (browser.isIE)
        this.clientArea.style.scrollbarBaseColor = this.activeClientAreaScrollbarColor;
    if (browser.isNS && browser.version < 6.1)
        this.clientArea.style.overflow = "auto";
    if (this.inactiveButtonsImage)
        this.titleBarButtons.src = this.activeButtonsImage;
    this.frame.style.zIndex = ++winCtrl.maxzIndex;
    winCtrl.active = this;
}

//=============================================================================
// Event handlers.
//=============================================================================

function winClientAreaClick(event) {

    // Make this window the active one.

    this.parentWindow.makeActive();
}

//-----------------------------------------------------------------------------
// Window dragging.
//-----------------------------------------------------------------------------

function winMoveDragStart(event) {

    var target;
    var x, y;

    if (browser.isIE)
        target = window.event.srcElement.tagName;
    if (browser.isNS)
        target = event.target.tagName;

    if (target == "AREA")
        return;

    this.parentWindow.makeActive();

    // Get cursor offset from window frame.

    if (browser.isIE) {
        x = window.event.x;
        y = window.event.y;
    }
    if (browser.isNS) {
        x = event.pageX;
        y = event.pageY;
    }
    winCtrl.xOffset = winCtrl.active.frame.offsetLeft - x;
    winCtrl.yOffset = winCtrl.active.frame.offsetTop  - y;

    // Set document to capture mousemove and mouseup events.

    if (browser.isIE) {
        document.onmousemove = winMoveDragGo;
        document.onmouseup   = winMoveDragStop;
    }
    if (browser.isNS) {
        document.addEventListener("mousemove", winMoveDragGo,   true);
        document.addEventListener("mouseup",   winMoveDragStop, true);
        event.preventDefault();
    }

    winCtrl.inMoveDrag = true;
}

function winMoveDragGo(event) {

    var x, y;

    if (!winCtrl.inMoveDrag)
        return;

    // Get cursor position.

    if (browser.isIE) {
        x = window.event.x;
        y = window.event.y;
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    if (browser.isNS) {
        x = event.pageX;
        y = event.pageY;
        event.preventDefault();
    }

    // Move window frame based on offset from cursor.

    winCtrl.active.frame.style.left = (x + winCtrl.xOffset) + "px";
    winCtrl.active.frame.style.top  = (y + winCtrl.yOffset) + "px";
}

function winMoveDragStop(event) {

    winCtrl.inMoveDrag = false;

    // Remove mousemove and mouseup event captures on document.

    if (browser.isIE) {
        document.onmousemove = null;
        document.onmouseup   = null;
    }
    if (browser.isNS) {
        document.removeEventListener("mousemove", winMoveDragGo,   true);
        document.removeEventListener("mouseup",   winMoveDragStop, true);
    }
}

//-----------------------------------------------------------------------------
// Window resizing.
//-----------------------------------------------------------------------------

function winResizeCursorSet(event) {

    var target;
    var xOff, yOff;

    if (this.parentWindow.isMinimized || winCtrl.inResizeDrag)
        return;

    // If not on window frame, restore cursor and exit.

    if (browser.isIE)
        target = window.event.srcElement;
    if (browser.isNS)
        target = event.target;
    if (target != this.parentWindow.frame)
        return;

    // Find resize direction.

    if (browser.isIE) {
        xOff = window.event.offsetX;
        yOff = window.event.offsetY;
    }
    if (browser.isNS) {
        xOff = event.layerX;
        yOff = event.layerY;
    }
    winCtrl.resizeDirection = ""
    if (yOff <= winCtrl.resizeCornerSize)
        winCtrl.resizeDirection += "n";
    else if (yOff >= this.parentWindow.frame.offsetHeight - winCtrl.resizeCornerSize)
        winCtrl.resizeDirection += "s";
    if (xOff <= winCtrl.resizeCornerSize)
        winCtrl.resizeDirection += "w";
    else if (xOff >= this.parentWindow.frame.offsetWidth - winCtrl.resizeCornerSize)
        winCtrl.resizeDirection += "e";

    // If not on window edge, restore cursor and exit.

    if (winCtrl.resizeDirection == "") {
        this.onmouseout(event);
        return;
    }

    // Change cursor.

    if (browser.isIE)
        document.body.style.cursor = winCtrl.resizeDirection + "-resize";
    if (browser.isNS)
        this.parentWindow.frame.style.cursor = winCtrl.resizeDirection + "-resize";
}

function winResizeCursorRestore(event) {

    if (winCtrl.inResizeDrag)
        return;

    // Restore cursor.

    if (browser.isIE)
        document.body.style.cursor = "";
    if (browser.isNS)
        this.parentWindow.frame.style.cursor = "";
}

function winResizeDragStart(event) {

    var target;

    // Make sure the event is on the window frame.

    if (browser.isIE)
        target = window.event.srcElement;
    if (browser.isNS)
        target = event.target;
    if (target != this.parentWindow.frame)
        return;

    this.parentWindow.makeActive();

    if (this.parentWindow.isMinimized)
        return;

    // Save cursor position.

    if (browser.isIE) {
        winCtrl.xPosition = window.event.x;
        winCtrl.yPosition = window.event.y;
    }
    if (browser.isNS) {
        winCtrl.xPosition = event.pageX;
        winCtrl.yPosition = event.pageY;
    }

    // Save window frame position and current window size.

    winCtrl.oldLeft   = parseInt(this.parentWindow.frame.style.left,  10);
    winCtrl.oldTop    = parseInt(this.parentWindow.frame.style.top,   10);
    winCtrl.oldWidth  = parseInt(this.parentWindow.frame.style.width, 10);
    winCtrl.oldHeight = parseInt(this.parentWindow.clientArea.style.height, 10);

    // Set document to capture mousemove and mouseup events.

    if (browser.isIE) {
        document.onmousemove = winResizeDragGo;
        document.onmouseup   = winResizeDragStop;
    }
    if (browser.isNS) {
        document.addEventListener("mousemove", winResizeDragGo,   true);
        document.addEventListener("mouseup"  , winResizeDragStop, true);
        event.preventDefault();
    }

    winCtrl.inResizeDrag = true;
}

function winResizeDragGo(event) {

    var north, south, east, west;
    var dx, dy;
    var w, h;

    if (!winCtrl.inResizeDrag)
        return;

    // Set direction flags based on original resize direction.

    north = false;
    south = false;
    east  = false;
    west  = false;
    if (winCtrl.resizeDirection.charAt(0) == "n")
        north = true;
    if (winCtrl.resizeDirection.charAt(0) == "s")
        south = true;
    if (winCtrl.resizeDirection.charAt(0) == "e" || winCtrl.resizeDirection.charAt(1) == "e")
        east = true;
    if (winCtrl.resizeDirection.charAt(0) == "w" || winCtrl.resizeDirection.charAt(1) == "w")
        west = true;

    // Find change in cursor position.

    if (browser.isIE) {
        dx = window.event.x - winCtrl.xPosition;
        dy = window.event.y - winCtrl.yPosition;
    }
    if (browser.isNS) {
        dx = event.pageX - winCtrl.xPosition;
        dy = event.pageY - winCtrl.yPosition;
    }

    // If resizing north or west, reverse corresponding amount.

    if (west)
        dx = -dx;
    if (north)
        dy = -dy;

    // Check new size.

    w = winCtrl.oldWidth  + dx;
    h = winCtrl.oldHeight + dy;
    if (w <= winCtrl.active.minimumWidth) {
        w = winCtrl.active.minimumWidth;
        dx = w - winCtrl.oldWidth;
    }
    if (h <= winCtrl.active.minimumHeight) {
        h = winCtrl.active.minimumHeight;
        dy = h - winCtrl.oldHeight;
    }

    // Resize the window. For IE, keep client area and frame widths in synch.

    if (east || west) {
        winCtrl.active.frame.style.width = w + "px";
        if (browser.isIE)
            winCtrl.active.clientArea.style.width = (w - winCtrl.active.widthDiff) + "px";
    }
    if (north || south)
        winCtrl.active.clientArea.style.height = h + "px";

    // Clip the title bar text, if necessary.

    if (east || west) {
        if (w < winCtrl.active.clipTextMinimumWidth)
            winCtrl.active.titleBarText.style.width = (winCtrl.minimizedTextWidth + w - winCtrl.active.minimumWidth) + "px";
        else
            winCtrl.active.titleBarText.style.width = "";
    }

    // For a north or west resize, move the window.

    if (west)
        winCtrl.active.frame.style.left = (winCtrl.oldLeft - dx) + "px";
    if (north)
        winCtrl.active.frame.style.top  = (winCtrl.oldTop  - dy) + "px";

    if (browser.isIE) {
        window.event.cancelBubble = true;
        window.event.returnValue = false;
    }
    if (browser.isNS)
        event.preventDefault();
}

function winResizeDragStop(event) {

    winCtrl.inResizeDrag = false;

    // Remove mousemove and mouseup event captures on document.

    if (browser.isIE) {
        document.onmousemove = null;
        document.onmouseup   = null;
    }
    if (browser.isNS) {
        document.removeEventListener("mousemove", winResizeDragGo,   true);
        document.removeEventListener("mouseup"  , winResizeDragStop, true);
    }
}

//=============================================================================
// Utility functions.
//=============================================================================

function winFindByClassName(el, className) {

    var i, tmp;

    if (el.className == className)
        return el;

    // Search for a descendant element assigned the given class.

    for (i = 0; i < el.childNodes.length; i++) {
        tmp = winFindByClassName(el.childNodes[i], className);
        if (tmp != null)
            return tmp;
    }

    return null;
}

//=============================================================================
// Initialization code.
//=============================================================================

var winList = new Array();
var winCtrl = new Object();

function winInit() {

    var elList;


    // Initialize window control object.

    winCtrl.maxzIndex                        =   0;
    winCtrl.resizeCornerSize                 =  16;
    winCtrl.minimizedTextWidth               = 100;
    winCtrl.inactiveFrameBackgroundColor     = "#c0c0c0";
    winCtrl.inactiveFrameBorderColor         = "#f0f0f0 #505050 #404040 #e0e0e0";
    winCtrl.inactiveTitleBarColor            = "#808080";
    winCtrl.inactiveTitleTextColor           = "#c0c0c0";
    winCtrl.inactiveClientAreaBorderColor    = "#404040 #e0e0e0 #f0f0f0 #505050";
    winCtrl.inactiveClientAreaScrollbarColor = "";
    winCtrl.inMoveDrag                       = false;
    winCtrl.inResizeDrag                     = false;

    // Initialize windows and build list.

    elList = document.getElementsByTagName("DIV");
    for (var i = 0; i < elList.length; i++)
        if (elList[i].className == "window")
            winList[elList[i].id] = new Window(elList[i]);
}

window.onload = winInit;  // run initialization code after page loads.

function windowOpen(id)
{
    if (winList[id]) 
    {
        winList[id].open();
        document.getElementById(id).style.left = 200;
        document.getElementById(id).style.top = 140;
    }
}
