/**
 * ZWindow class.
 *
 * A floating window widget 
 * inside your web page.
 *
 * Usage:      var mywindow = new ZWindow(content, title, x, y, width, height)
 * Functions:  setContent(html), setHref(url), close()
 *
 * @param content  The optional content or url, defaults to "&nbsp;"
 * @param title    The optional window title, defaults to "&nbsp;"
 * @param x        The optional horizontal initial coordinate, defaults to 100
 * @param y        The optional vertical initial coordinate, defaults to 100
 * @param width    The optional width, defaults to 160
 * @param height   The optional width, defaults to 100
 */
function ZWindow(content, title, x, y, width, height) {

    /**
     * ZWindow constructor
     *
     * @param content  The optional content or url, defaults to "&nbsp;"
     * @param title    The optional window title, defaults to "&nbsp;"
     * @param x        The optional horizontal initial coordinate, defaults to 100
     * @param y        The optional vertical initial coordinate, defaults to 100
     * @param width    The optional width, defaults to 160
     * @param height   The optional width, defaults to 100
     */
    this.ZWindow = function(content, title, x, y, width, height) {
        if(! xDef(content)) { content = "&nbsp;"; }
        if(! xDef(title))   { title = "&nbsp;"; }
        if(! xDef(width))   { width = 160; }
        if(! xDef(x))       { x = 100; }
        if(! xDef(y))       { y = 100; }
        this.buildWindow(title, x, y, width, height);
        if(content.substr(0,5) == 'http:') {
            this.setHref(content);
        } else {
            this.setContent(content);
        }
    }

    /**
     * Build the window
     *
     * @param title   The window title
     * @param x       The horizontal initial coordinate
     * @param y       The vertical initial coordinate
     * @param width   The width
     * @param height  The width
     */
    this.buildWindow = function(title, x, y, width, height) {
        var titlerow;
        var item;
        var html = '';

        // 1. create window div
        this.element = document.createElement('div');
        html += "<img width='8' height='8' border='0' src='w4.gif' style='position:absolute;visibility:hidden;cursor:resize;top:0px;left:0px;z-index:1024'/>";
        html += "<table cellspacing='0' cellpadding='0'";
        html += " style='padding:0px;margin:0px;width:100%;height:100%;border:1px solid black'>";
        html += "<tr><td style='width:11px;height:12px'>";
        html += "<img width='11' height='12' border='0' src='w1.gif' style='cursor:pointer'/>"
        html += "</td><td style='";
        html += "background-image:url(w2.gif);";
        html += "font-family:Verdana, Arial, sans-serif;font-size:10px;";
        html += "overflow:hidden;cursor:default;height:12px";
        html += "'>";
        html += title;
        html += "</td><td style='width:10px;height:12px'>";
        html += "<img width='10' height='12' border='0' src='w3.gif' style='cursor:pointer'/>";
        html += "</td></tr><tr><td colspan='3'>";
        html += "<img border='0' src='pixel.gif'/>";
        html += "</td></tr></table>";

        // 2. prepare and fill div
        this.element.setAttribute('style', 'position:absolute;visibility:hidden');
        this.element.style.position = 'absolute';
        this.element.style.visibility = 'hidden';
        document.body.appendChild(this.element);
        this.element.innerHTML = html;

        // 3. position div
        xLeft(this.element, x);
        xTop(this.element, y);
        xWidth(this.element, width);
        xHeight(this.element, height);
        xShow(this.element);
        titlerow = this.element.getElementsByTagName('table')[0].rows[0];

        // 4. enable drag on title bar
        item = titlerow.cells[1];
        item.zwindow = this;
        xZIndex(item, xZIndex(this.element));
        xEnableDrag(item, this.startDrag, this.dragWindow, this.stopDrag);

        // 5. enable resize corner
        this.corner = this.element.getElementsByTagName('img')[0];
        this.corner.zwindow = this;
        xLeft(this.corner, width - 9);
        xTop(this.corner, height - 9);
        xAddEventListener(this.element, 'mouseover', this.showCorner, 1);
        xAddEventListener(this.element, 'mouseout', this.hideCorner, 1);
        xEnableDrag(this.corner, this.startResize, this.dragCorner, this.stopResize);

        // 6. enable minimize on right icon
        item = titlerow.cells[2].getElementsByTagName('img')[0];
        item.zwindow = this;
        xAddEventListener(item, 'click', this.minimizeToggle, 1);

        // 7. enable close on left icon
        item = titlerow.cells[0].getElementsByTagName('img')[0];
        item.zwindow = this;
        xAddEventListener(item, 'click', this.close, 1);

        // 6. Register zwindow private fields
        this.element.zwindow = this;
        this.title = title;
        this._last_click = new Date();
        this._under_drag = 0;
    }

    /**
     * Set a new html content
     *
     * @param html  The new html to render inside the window
     */
    this.setContent = function(html) {
        var contentcell;

        contentcell = this.element.getElementsByTagName('table')[0].rows[1].cells[0];
        contentcell.style.backgroundColor = 'white';
        contentcell.innerHTML = html;
        xLeft(this.corner, xWidth(this.element) - 9);
        xTop(this.corner, xHeight(this.element) - 9);
    }

    /**
     * Set a new url content
     *
     * @param url  The new url to show inside the window
     */
    this.setHref = function(url) {
        var html = '';

        //html += '<iframe name="zwindow_';
        //html += (_zwindow_index++);
        html += '<iframe src="';
        html += url;
        html += '" width="100%" height="100%" '; 
        html += 'marginwidth="0" marginheight="0" '
        html += 'frameborder="0" scrolling="auto"/>';
        this.setContent(html);
    }

    /**
     * Start drag handler
     *
     * @param ele  The target element
     * @param x    The starting point horizontal coordinate
     * @param y    The starting point vertical coordinate
     */
    this.startDrag = function(ele, x, y) {
        var contentcell, i, firsttag;
        var table = ele;

        ele.zwindow._under_drag = 1;
        ele.zwindow._has_moved = 0;
        ele.zwindow._frame_hidden_on_drag = 0;
        while(table.tagName.toUpperCase() != 'TABLE') {
            table = table.parentNode;
        }
        contentcell = table.rows[1].cells[0];
        if(contentcell.innerHTML.substring(0,7) == '<iframe') {
            ele.zwindow._frame_hidden_on_drag = 1;
            contentcell.getElementsByTagName('iframe')[0].style.display = 'none';
            contentcell.style.backgroundColor = '';
        }
    }

    /**
     * Running drag handler
     *
     * @param ele  The target element
     * @param dx   The horizontal shift since last call
     * @param dy   The vertical shift since last call
     */
    this.dragWindow = function(ele, dx, dy) {
        var wind = ele.zwindow.element;
        ele.zwindow._has_moved = 1;
        xLeft(wind, xLeft(wind)+dx);
        xTop(wind, xTop(wind)+dy);
    }

    /**
     * Stop drag handler
     *
     * @param ele  The target element
     * @param x    The stopping point horizontal coordinate
     * @param y    The stopping point vertical coordinate
     */
    this.stopDrag = function(ele, x, y) {
        var table = ele;
        var contentcell;
        var now, last;

        ele.zwindow._under_drag = 0;
        if(ele.zwindow._frame_hidden_on_drag) {
            while(table.tagName.toUpperCase() != 'TABLE') {
                table = table.parentNode;
            }
            contentcell = table.rows[1].cells[0];
            contentcell.style.backgroundColor = 'white';
            contentcell.getElementsByTagName('iframe')[0].style.display = '';
        }
        if(! ele.zwindow._has_moved) {
            now = new Date();
            last = ele.zwindow._last_click;
            if(now-last < 200) {
                ele.zwindow.doMinimizeToggle(null);
            }
            ele.zwindow._last_click = now;
        }
    }

    /**
     * Start corner drag handler
     *
     * @param ele  The target element
     * @param x    The starting point horizontal coordinate
     * @param y    The starting point vertical coordinate
     */
    this.startResize = function(ele, x, y) {
        var contentcell;

        ele.zwindow._under_drag = 1;
        ele.zwindow._frame_hidden_on_drag = 0;
        contentcell = ele.zwindow.element.getElementsByTagName('table')[0].rows[1].cells[0];
        if(contentcell.innerHTML.substring(0,7) == '<iframe') {
            ele.zwindow._frame_hidden_on_drag = 1;
            contentcell.getElementsByTagName('iframe')[0].style.display = 'none';
            contentcell.style.backgroundColor = '';
        }
    }

    /**
     * Running corner drag handler
     *
     * @param ele  The target element
     * @param dx   The horizontal shift since last call
     * @param dy   The vertical shift since last call
     */
    this.dragCorner = function(ele, dx, dy) {
        var wind = ele.zwindow.element;
        var table = wind.getElementsByTagName('table')[0];

        xWidth(wind, xWidth(wind)+dx);
        xHeight(wind, xHeight(wind)+dy);
        xWidth(wind, xWidth(table));
        xHeight(wind, xHeight(table));
        xLeft(ele, xLeft(ele)+dx);
        xTop(ele, xTop(ele)+dy);
    }

    /**
     * Stop corner drag handler
     *
     * @param ele  The target element
     * @param x    The stopping point horizontal coordinate
     * @param y    The stopping point vertical coordinate
     */
    this.stopResize = function(ele, x, y) {
        var contentcell;

        ele.zwindow._under_drag = 0;
        xLeft(ele, xWidth(ele.zwindow.element) - 9);
        xTop(ele, xHeight(ele.zwindow.element) - 9);
        if(ele.zwindow._frame_hidden_on_drag) {
            contentcell = ele.zwindow.element.getElementsByTagName('table')[0].rows[1].cells[0];
            contentcell.style.backgroundColor = 'white';
            contentcell.getElementsByTagName('iframe')[0].style.display = '';
        }
    }

    /**
     * Show corner handler
     *
     * @param event  The native browser event
     */
    this.showCorner = function(event) {
        // event func : 'this' is the corner icon
        var self = this.zwindow;
        if(!xDef(self)) {
            self = element.zwindow;
        }
        self.doShowCorner(new xEvent(event));
    }

    /**
     * Show corner internal handler
     *
     * @param event  The xEvent
     */
    this.doShowCorner = function(evt) {
        var table;

        table = this.element.getElementsByTagName('table')[0];
        if(table.rows[1].style.display == '') {
            xShow(this.corner);
        }
    }

    /**
     * Hide corner handler
     *
     * @param event  The native browser event
     */
    this.hideCorner = function(event) {
        // event func : 'this' is the corner icon
        var self = this.zwindow;
        if(!xDef(self)) {
            self = element.zwindow;
        }
        self.doHideCorner(new xEvent(event));
    }

    /**
     * Hide corner internal handler
     *
     * @param event  The xEvent
     */
    this.doHideCorner = function(evt) {
        if(! this._under_drag) {
            xHide(this.corner);
        }
    }

    /**
     * Minimization handler
     *
     * @param event  The native browser event
     */
    this.minimizeToggle = function(event) {
        // event func : 'this' is the minimize icon
        var self = this.zwindow;
        if(!xDef(self)) {
            self = element.zwindow;
        }
        self.doMinimizeToggle(new xEvent(event));
    }

    /**
     * Minimization internal handler
     *
     * @param event  The xEvent
     */
    this.doMinimizeToggle = function(evt) {
        var table, contentrow;

        table = this.element.getElementsByTagName('table')[0];
        contentrow = table.rows[1];
        if(contentrow.style.display == '') {
            xHide(this.corner);
            this.element.unfoldedHeight = xHeight(this.element);
            table.style.borderBottom = '0px';
            contentrow.style.display = 'none';
            xHeight(this.element, 12);
        } else {
            table.style.borderBottom = '1px solid black';
            contentrow.style.display = '';
            xHeight(this.element, this.element.unfoldedHeight);
            xShow(this.corner);
        }
    }

    /**
     * Close handler
     *
     * @param event  The native browser event
     */
    this.close = function(event) {
        // event func : 'this' is the minimize icon
        var self = this.zwindow;
        if(!xDef(self)) {
            self = element.zwindow;
        }
        self.doClose(new xEvent(event));
    }

    /**
     * Close internal handler
     *
     * @param event  The xEvent
     */
    this.doClose = function(evt) {
        this.element.parentNode.removeChild(this.element);
    }

    /**
     * Representation function
     */
    this.toString = function() {
        return ('[ZWindow object, title='+this.title+']');
    }

    this.ZWindow(content, title, x, y, width, height);
}

