/**
 * 
 * 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) Open-Xchange Inc., 2006-2011
 * Mail: info@open-xchange.com 
 * 
 * @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com>
 * @author Stefan Preuss <stefan.preuss@open-xchange.com>
 * 
 */

/*jslint bitwise: false, nomen: false, onevar: false, plusplus: false, regexp: false, white: false, browser: true, devel: true, evil: true, forin: true, undef: true, eqeqeq: true, immed: true */

/*global ox, jQuery, window, getFullImgSrc, _, urlify, setFocus, register */

// window factory for embedded windows
var embeddedWindows = (function () {
    
    var dockVisible = true;
    
    var setDockVisible = function (flag) {
        if (flag === true) {
            // set flag
            dockVisible = true;
            // show dock
            $(dock).show();
            // resize UI
            $("#notheader").css("bottom", "34px");
            $(".ox-embedded-container, .ox-embedded-decorator").css("bottom", "32px");
        } else {
            // set flag
            dockVisible = false;
            // hide dock
            $(dock).hide();
            // resize UI
            $("#notheader").css("bottom", "0px");
            $(".ox-embedded-container, .ox-embedded-decorator").css("bottom", "0px");
        }
    };
    
    // ref
    var $ = jQuery;
    
    // vars
    var count = 0, current = null, initialize = true;
    var showDock, hideDock;
    var show, fnShow, add, remove, addToDock, fnClose;
    var row, table, dock;
    var openWindow, closeWindow, selectWindow;
    
    var readyHandler = function (data) {
        // get window
        var w = ox.api.window.get(data.handle);
        if (w) {
            w.container.children().first().text("" + data.title);
            w.dock.children().find("div.ox-window-title").text("" + data.title);
            w.dock.children().find("div.ox-window-module").
            css({ background: "url('" + getFullImgSrc("icons/16/mod_" + data.module + ".png") + "')" });
        }
    };
    
    var disable = function () {
        // hide dock
        dock.hide();
        // resize UI
        $("#notheader").css("bottom", "0px");
        $(".ox-embedded-container, .ox-embedded-decorator").css("bottom", "0px");
        // unregister ready handler
        ox.api.event.unregister("OX_Window_Ready", readyHandler);
        // reset window factory
        ox.api.window.resetFactory();
    };
    
    var enable = function () {
        
        // update title
        ox.api.event.register("OX_Window_Ready", readyHandler);
        
        if (initialize) {
            
            // show/hide dock
            showDock = function () {
                if (dockVisible === true) {
                    $("#notheader, .ox-embedded-container, .ox-embedded-decorator").css("bottom", "34px");
                    dock.show();
                }
            };
            
            hideDock = function () {
                $("#notheader").css("bottom", "0px");
                dock.hide();
            };
            
            // create dock
            dock = $("<div/>", { id: "ox-dock" })
                .addClass("ox-dock")
                .appendTo(document.body)
                .append(
                    table = $("<table/>", { border: "0", cellPadding: "0", cellSpacing: "0" }).append(
                        $("<tbody/>").append(row = $("<tr/>"))
                    )
                );
            
            // functions
            show = function (guid) {
                // hide current window
                if (current) {
                    current.lightbox.hide();
                    current.container.hide();
                    // remove old selection 
                    current.dock.find(".ox-dock-selected").removeClass("ox-dock-selected");
                    // click on same tab
                    if (current.guid === guid) {
                        // minimize windown
                        if (!current.minimized) {
                            current.minimized = true;
                            return;
                        } else {
                            // maximize
                            delete current.minimized;
                        }
                    }
                }
                
                // show window (not core)?
                if (guid !== "OX.0") {
                    // get window
                    var w = ox.api.window.get(guid);
                    
                    // show
                    w.lightbox.show();
                    w.container.show();
                    // set current
                    current = {
                        guid: guid,
                        lightbox: w.lightbox,
                        container: w.container,
                        dock: w.dock
                    };
                    // select current
                    w.dock.children().first().addClass("ox-dock-selected");
                } else {
                    current = null;
                }
            };
            
            fnShow = function (e) {
                show(e.data.guid);
            };
            
            add = function (guid) {
                // add to dock
                addToDock(guid, "...");
                // show window
                show(guid);
            };
            
            remove = function (guid) {
                // remove last window
                var w = ox.api.window.get(guid);
                w.dock.remove();
                delete w.dock;
                // get number of windows
                var count = ox.api.window.count();
                // adjust table width
                table.css("width", (Math.min(count, 5) * 20) + "%");
                table.find("td").css("width", ((100 / count) >> 0) + "%");
                // clear current?
                if (current && current.guid === guid) {
                    current = null;
                }
                if (count <= 2) {
                    hideDock();
                }
            };
            
            fnClose = function (e) {
                ox.api.window.close(e.data.guid);
                return false;
            };
            
            addToDock = function (guid, title) {
                // get number of windows
                var count = ox.api.window.count() + 1;
                // adjust table width
                table.css("width", (Math.min(count, 5) * 20) + "%");
                // add item
                var dock = $("<td/>")
                    .css({
                        minWidth: "100px"
                    })
                    .append(
                        $("<div/>").addClass("ox-dock-tab")
                        .append(
                            $("<div/>")
                                .addClass("ox-window-module")
                                .css({
                                    backgroundImage: "url('" + getFullImgSrc("img/dummy.gif") + "')",
                                    position: "absolute",
                                    top: "6px",
                                    width: "16px",
                                    height: "16px"
                                })
                        ).append(
                            $("<div/>")
                                .addClass("ox-window-title")
                                .css({
                                    position: "absolute",
                                    right: "25px",
                                    left: "32px",
                                    overflow: "hidden"
                                })
                                .text("" + title)
                        ).append(
                            $("<div/>")
                                .addClass("ox-window-close")
                                .css({
                                    backgroundImage: "url('" + getFullImgSrc("img/x.png") + "')",
                                    position: "absolute",
                                    right: "8px",
                                    top: "6px",
                                    width: "14px",
                                    height: "14px"
                                }).
                                bind("click", { guid: guid }, fnClose)
                        )
                        .bind("click", { guid: guid }, fnShow)
                    )
                    .appendTo(row);
                // update width
                table.find("td").css("width", ((100/count) >> 0) + "%");
                // remove close for main dock
                if (guid === "OX.0") {
                    dock.find("div.ox-window-module").remove();
                    dock.find("div.ox-window-close").remove();
                }
                // add
                var w = ox.api.window.get(guid);
                w.dock = dock;
            };
            
            // window factory functions
            // open
            openWindow = function (opt) {
                // show dock?
                if (ox.api.window.count() >= 1) {
                    showDock();
                }
                // inc
                count += 2;
                // locals
                var iframe, lightbox, container;
                // create iframe
                iframe = $("<iframe/>", {
                    src: urlify(opt.url),
                    frameborder: "no",
                    id: opt.guid
                })
                .addClass("ox-embedded-window")
                .css({
                    border: "0px none",
                    width: "100%",
                    height: "100%"
                })
                .one("load", function (e) { // "bind" (instead of "one") might fail, if success handler work with document.write (endless loop in IE)
                    // set guid
                    var win = this.contentWindow;
                    win.guid = opt.guid;
                    // register new window object
                    ox.api.window.register(opt.guid, win, {
                        iframe: $(this),
                        lightbox: lightbox,
                        container: container
                    });
                    // IE7 height fix (cannot handle 100%)
                    if (ox.browser.IE) {
                        $(this).css("height", container.height() + "px");
                    }
                    // remove spinner
                    lightbox.removeClass("busy-spinner-black");
                    // show container
                    container.css("visibility", "visible");
                    // add to list
                    add(opt.guid);
                    // continue
                    opt.success(win, opt.guid);
                    win = null;
                });
                // create lightbox
                lightbox = $("<div/>")
                    .addClass("ox-embedded-decorator busy-spinner-black")
                    .css({
                        zIndex: 19 + count,
                        bottom: dockVisible ? "34px" : "0px"
                    })
                    .bind("click contextmenu", function (e) { /* ctrl+click on mac becomes contextmenu */
                        if (e.ctrlKey) {
                            // close
                            opt.closer(opt);
                        } else {
                            // show core
                            show("OX.0");
                        }
                    })
                    .appendTo(document.body);
                // create container
                var w = opt.options.width;
                container = $("<div/>")
                    .addClass("ox-embedded-container")
                    .css({
                        zIndex: 20 + count,
                        bottom: dockVisible ? "34px" : "0px",
                        marginLeft: (-Math.floor(w / 2)) + "px",
                        width: w + "px",
                        backgroundColor: "white"
                    })
                    .append(
                        // title bar
                        $("<div/>")
                            .addClass("ox-embedded-title")
                            .text("\u00a0")
                    )
                    .append(
                         // close
                         $("<div/>")
                             .addClass("ox-embedded-close")
                             .append(
                                 $("<img/>", { src: getFullImgSrc("img/dummy.gif"), alt: "" })
                                     .bind("click", { guid: opt.guid }, fnClose)
                             )
                    )
                    .append(
                        $("<div/>").addClass("ox-embedded-iframe").append(iframe)
                    )
                    .appendTo(document.body);
                // focus frame
                setFocus(iframe.get(0));
                // prevent leak
                iframe = null;
            };
            
            // close
            closeWindow = function (obj, guid) {
                // close
                obj.iframe.remove();
                obj.container.remove();
                obj.lightbox.remove();
                delete obj.iframe;
                delete obj.container;
                delete obj.lightbox;
                // dec
                count -= 2;
                // remove
                remove(guid);
            };
            
            // select
            selectWindow = function (obj, guid) {
                show(guid);
                obj.window.focus();
            };
            
            addToDock("OX.0", _("Main window"));
            
        } else {
            // show dock
            showDock();
        }
        
        // replace factory
        ox.api.window.setFactory(openWindow, closeWindow, selectWindow, true);
        
        // done with first run
        initialize = false;
    };
    
    // public functions
    return {
        setDockVisible: setDockVisible,
        enable: enable,
        disable: disable,
        force: false
    };
    
}());

// use embedded windows?
register("Ready", function () {
    if (embeddedWindows.force || ox.api.config.get("ui.global.windows.mode.value") === "embedded") {
        embeddedWindows.enable();
    }
});
