/**
 * 
 * All content on this website (including text, images, source code and any
 * other original works), unless otherwise noted, is licensed under a Creative
 * Commons License.
 * 
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 * 
 * Copyright (C) 2004-2010 Open-Xchange, Inc. Mail: info@open-xchange.com
 * 
 * @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com>
 * @ignore
 */

// DEVELOPMENT IN PROGRESS // SUBJECT TO PERMANENT CHANGE!

ox.gui.PanelMenu = ox.gui.Container.extend( {
/** @lends ox.gui.PanelMenu.prototype */

    getClass : function() {
        return "ox.gui.PanelMenu";
    },

    /**
     * The basic container widget
     * 
     * @constructs
     * @extends ox.gui.Container
     * @param {String} id An optional unique id for the widget.
     * @param {String} title The title of the panel menu. Important when using as TabMenu.
     */
    construct : function(id, title) {

        // call super class constructor (inherit from Container)
        this._super(this.autoId(id));
    
        // title (used for TabMenu)
        this.title = title || noI18n("");
    
        // rows
        this.rows = 3;
    
        // dynamic resizing
        this.dynamicResizing = false;
        this.hasCollapsedSections = false;
    
        // set layout manager
        this.setLayout(new ox.gui.PanelMenuLayout(this));
    
        // add widget listener
        this.addListener("widget:show", function() {
            this.layoutManager.resize();
        });
    },
    
    nodeInit: function() {
        this._super();
        this.setStyle("overflow: hidden");
    },

    /**
     * @private
     */
    propagateOpenHover: function(item) {
        // local handler?
        var p = this.parent;
        if (p.openHover !== undefined) {
            // another item open?
            if (p.openHover && p.openHover != item) {
                p.openHover.deactivate();
            }
            // set open menu item
            p.openHover = item;
        } else if ($.isFunction(p.propagateOpenHover)) {
            // a parent widget will take care
            p.propagateOpenHover(item);
        }
    },
    
    setTitle: function(title) {
        this.title = title;
        if (this.parent) this.parent.layoutManager.doLayout();
    }
});

// ------------------------------------------------------------------------------

ox.gui.PanelMenuSection = ox.gui.Container.extend( {
/** @lends ox.gui.PanelMenuSection.prototype */

    getClass : function() {
        return "ox.gui.PanelMenuSection";
    },

    /**
     * The basic container widget
     * 
     * @constructs
     * @extends ox.gui.Container
     * @param {I18nString}
     *            title The title of the menu section.
     */
    construct : function(text, id) {

        // call super class constructor (inherit from Container)
        this._super(id);

        this.text = text || noI18n("");

        // dynamic resizing
        this.collapsed = false;
        this.dropdown = null;
        this.maxWidth = 0;

        // set layout manager
        this.setLayout(new ox.gui.PanelMenuSectionLayout(this));
    },

    add : function() {
        var target = this.collapsed ? this.dropdown : this;
        ox.gui.Container.prototype.add.apply(target, arguments);
    },

    insert : function() {
        var target = this.collapsed ? this.dropdown : this;
        ox.gui.Container.prototype.insert.apply(target, arguments);
    },

    /**
     * @private
     */
    propagateOpenHover: function(item) {
        // local handler?
        var p = this.parent;
        if (p && p.openHover !== undefined) {
            // another item open?
            if (p.openHover && p.openHover != item) {
                p.openHover.deactivate();
            }
            // set open menu item
            p.openHover = item;
        } else if (p && $.isFunction(p.propagateOpenHover)) {
            // a parent widget will take care
            p.propagateOpenHover(item);
        }
    },

    /**
     * Expands the menu section (if collapsed).
     */
    expand : function() {
        if (this.collapsed) {
            this.removeChildren();
            // move children
            this.dropdown.each(function(child) {
                child.forceSmallIcon = false;
                if (child.bigIcon) {
                    child.menuStripAlign = "bottom";
                    child.statusValid = false;
                } else {
                    child.menuStripAlign = "right";
                }
                ox.gui.Container.prototype.add.call(this.parent, child);
            });
            this.dropdown.removeChildren();
            this.collapsed = false;
            this.statusValid = false;
            this.validate();
        }
    },

    /**
     * Collapses the menu section.
     */
    collapse : function() {
        if (!this.collapsed && this.hasChildren()) {
            // first icon
            var icon = this.getChildren()[0].icon;
            if (this.dropdown == null) {
                this.dropdown = new ox.gui.MenuItem(this.text || _("Dropdown"),
                        icon, true);
            }
            // move children
            // 1st: copy items with big icons
            this.each(function(child) {
                if (child.bigIcon) {
                    child.forceSmallIcon = true;
                    child.menuStripAlign = "right";
                    child.statusValid = false; // big icons only
                    this.dropdown.add(child);
                }
            });
            // 2nd: copy items with small icons
            this.each(function(child) {
                if (!child.bigIcon) {
                    child.forceSmallIcon = true;
                    child.menuStripAlign = "right";
                    this.dropdown.add(child);
                }
            });
            // remove child from section
            this.removeChildren();
            // add dropdown as new child
            ox.gui.Container.prototype.add.call(this, this.dropdown);
            this.collapsed = true;
            this.dropdown.statusValid = false;
            this.statusValid = false;
            this.validate();
        }
    }
});

// ------------------------------------------------------------------------------

ox.gui.PanelMenuLayout = ox.gui.LayoutManager.extend( {
/** @lends ox.gui.PanelMenuLayout.prototype */

    /**
     * A layout manager for the panel menu.
     * 
     * @extends ox.gui.LayoutManager
     * @constructs
     * @param {ox.gui.Container} The container widget that should be managed by the layout manager.
     */
    construct: function (container) {
        this._super(container);
        
        this.table = null;
        this.tbody = null;
        this.tfoot = null;
        
        this.maxWidth = 0;
    },

    getClass : function () {
        return "ox.gui.PanelMenuLayout";
    },

    doLayout : function () {

        // local vars
        var container = this.container;
        var showNames = this.container.parent.options.showSectionNames;
        var target = $(this.container.dom.node);
        var self = this;
        
        // create table
        if (this.table === null) { 
            this.table = $("<table/>", { border: 0, cellPadding: 0, cellSpacing: 0 }).
                addClass("panelMenu").
                append(
                    $("<tbody/>").append(this.tbody = $("<tr/>"))
                ).
                append(
                    $("<tfoot/>").append(this.tfoot = $("<tr/>"))
                );
        }
        
        // park children
        this.park();
        
        // clear table body
        this.tbody.empty();
        
        // loop children
        container.eachVisible(function (child, i, childCount) {
            // add to DOM & show
            var td = $("<td/>");
            // set class name
            td.addClass("panelSectionContainer" + (i === childCount - 1 ? " last" : ""));
            // add child
            td.appendTo(self.tbody).append(child.dom.node);
        });
        
        // loop children (again)
        this.tfoot.empty();
        if (showNames === true) {
            container.eachVisible(function (child) {
                $("<td/>").text(expectI18n(child.text)).
                    addClass("panelMenuSectionName").
                    appendTo(self.tfoot);
            });
        }
        
        // add now, so that we can implement dynamic resizing
        target.append(this.table);

        // add listener
        container.addListener("dom:resize", window, function(e) {
            // get size
            var manager = this.layoutManager;
            manager.maxWidth = $(this.dom.node).width();
            // too large/might be too small
            this.layoutManager.resize();
        });
        
        // find topmost, invalid parent
        var current = container;
        while (current.parent && !current.parent.statusValid) {
            current = current.parent;
        }
        
        // and wait for it
        container.addListener("widget:valid", current, function(event) {
            // get size
            var manager = this.layoutManager;
            manager.maxWidth = $(this.dom.node).width();
            // get size of sections
            this.eachVisible(function(child) {
                child.maxWidth = child.dom.node.clientWidth;
            });
            // activate dynamic resizing (once all parent nodes are
            // rendered)
            this.dynamicResizing = true;
            this.layoutManager.resize();
        });
        
        // don't resize twice
        if (container != current) {
            container.layoutManager.resize();
        }
    },

    resize : function() {

        // disable resize (needs some polishing)
        return;
        
        // shortcut
        var container = this.container;
        var children = container.getVisibleChildren();
        var maxWidth = this.maxWidth;

        if (container.dynamicResizing
                && (this.table.clientWidth > maxWidth || container.hasCollapsedSections)) {
            // try to expand (from left to right)
            if (container.hasCollapsedSections
                    && this.table.clientWidth < maxWidth) {
                for ( var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (child.collapsed
                            && (this.table.clientWidth + child.maxWidth) < maxWidth) {
                        child.expand();
                    }
                }
            }
            // collapse sections (right to left)
            if (this.table.clientWidth >= maxWidth) {
                for ( var i = children.length - 1; i >= 0; i--) {
                    var child = children[i];
                    // now check size
                    if (this.table.clientWidth >= maxWidth) {
                        child.collapse();
                    } else {
                        break;
                    }
                }
            }
        }
        // collapsed sections?
        for ( var i = children.length - 1; i >= 0; i--) {
            if (children[i].collapsed) {
                container.hasCollapsedSections = true;
                break;
            }
        }
    }
});

// ------------------------------------------------------------------------------

ox.gui.PanelMenuSectionLayout = ox.gui.LayoutManager.extend( {
/** @lends ox.gui.PanelMenuLayout.prototype */

    /**
     * A layout manager for a panel menu section.
     * 
     * @extends ox.gui.LayoutManager
     * @constructs
     * @param {ox.gui.Container} The container widget that should be managed by the layout manager.
     */
    construct: function (container) {
        this._super(container);
        this.table = null;
        this.tbody = null;
    },

    getClass: function () {
        return "ox.gui.PanelMenuSectionLayout";
    },

    doLayout: function () {
        
        // create table
        if (this.table === null) {
            this.table = $("<table/>", { border: 0, cellPadding: 0, cellSpacing: 0 }).
                addClass("panelMenuSection").
                append(
                    this.tbody = $("<tbody/>")
                );
        }
        
        this.renderPartial();
        
        this.table.appendTo(this.container.dom.node);
    },

    /**
     * @private
     */
    renderPartial : function() {
    
        // park children
        var park = $("<div/>");
        this.container.each(function (child) {
            park.append(child.dom.node);
        });
        
        // clear table body
        this.tbody.empty();
        
        // get big & small icons
        var bigIcons = [], smallIcons = [];
        // loop children (big icons only)
        this.container.each(function (child) {
            if (child.bigIcon) {
                bigIcons.push(child);
            } else {
                smallIcons.push(child);
            }
        });
        
        var hasBigIcons = bigIcons.length > 0;
        var rows = 2;
        var columns = Math.ceil(smallIcons.length / rows);
        
        // create rows
        var trs = [], r = 0;
        for (; r < rows; r++) {
            trs.push($("<tr/>").appendTo(this.tbody));
        }
        
        // vars
        var i, c, r, td;
        
        // loop children (big icons)
        for (i = 0; i < bigIcons.length; i++) {
            var child = bigIcons[i];
            td = $("<td/>", { rowSpan: rows }).
                addClass("panelMenuItem large").
                append(child.dom.node);
            // append to row
            trs[0].append(td);
        }
        
        // create cells for small icons
        for (c = 0, i = 0; c < columns; c++) {
            for (r = 0; r < rows; r++, i++) {
                td = $("<td/>").addClass("panelMenuItem").css({
                    height: Math.floor(100 / rows) + "%"
                });
                // bottom?
                if (r === rows - 1) {
                    td.addClass("bottom");
                }
                trs[r].append(td);
                // small icon?
                if (smallIcons[i]) {
                    td.append(smallIcons[i].dom.node);
                } else {
                    td.html("&nbsp;");
                }
            }
        }
        
//        park.empty();
//        park = null;
    }
});

// ------------------------------------------------------------------------------

ox.gui.TabMenu = ox.gui.TabControl.extend( {
/** @lends ox.gui.TabMenu.prototype */

    getClass : function() {
        return "ox.gui.TabMenu";
    },

    /**
     * A TabMenu container. A combination of TabControl and PanelMenu.
     * 
     * @constructs
     * @extends ox.gui.TabControl
     * @param {String} id An optional unique id for the widget.
     */
    construct : function(options) {

        // defaults
        this.options = $.extend( {
            id : undefined,
            action : $.noop,
            showSectionNames : true,
            inHover: false
        }, options || {});
    
        // call super class constructor
        this._super(this.options.id);
    
        // set layout manager (for tabs; not pages)
        this.setLayout(new ox.gui.TabMenuLayout(this));
    
        // expand/hover
        this.expanded = true;
        this.expandable = true;
        this.inHover = this.options.inHover;
    
        // required to work with ox.gui.menuItem
        this.openHover = null;
        
        // apply "inHover"
        if (this.options.inHover) {
            // mark as collapsed
            this.expanded = false;
            // move container
            $(this.tabPageContainer).
                addClass("oxTabControlPageContainerInHover").
                appendTo(this.dom.hover);
        }
    }
});

ox.gui.TabMenuLayout = ox.gui.TabControlLayout.extend({
/** @lends ox.gui.TabMenuLayout.prototype */
    
    getClass: function() { return "ox.gui.TabMenuLayout"; }
    
});

