/**
 * 
 * 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>
 * 
 */

(function () {

    /* ref to jquery */
    var $ = jQuery;

    /* bug report */
    var bug = { info: [], steps: [] };
    
    /* Add console */
    var con = {};
    var height = 200;
    
    var container = $("<div/>", { id: "audit-console" }).css({
        position: "absolute",
        bottom: "0px",
        left: "0px",
        right: "0px",
        height: height + "px",
        overflow: "auto",
        backgroundColor: "#111",
        zIndex: 65000,
        borderTop: "10px solid #333",
        fontSize: "9pt",
        color: "white",
        padding: "10px 10px 0px 10px"
    }).appendTo(document.body);
    
    /* report button */
    
    var popupDecorator = $("<div/>").css({
        position: "absolute",
        top: "0px",
        right: "0px",
        bottom: "0px",
        left: "0px",
        backgroundColor: "#800",
        zIndex: 65001,
        display: "none",
        opacity: 0.7
    }).bind("click", function (e) {
        popupDecorator.hide();
        popup.hide();
        
    });

    var popup = $("<div/>").css({
        position: "absolute",
        top: "100px",
        right: "100px",
        bottom: "100px",
        left: "100px",
        backgroundColor: "#111",
        border: "10px solid #333",
        padding: "0px",
        zIndex: 65002,
        display: "none"
    }).append(
        $("<textarea/>", { width: "100%", height: "100%" }).css({
            backgroundColor: "white",
            fontSize: "9pt",
            fontFamily: "Mono, monospace, Arial, sans-serif",
            fontWeight: "normal"
        })
    );

    container.append(
        $("<button/>").
        css({ color: "black", width: "130px", margin: "0px 0px 5px 0px" }).
        text("Report bug").
        bind("click", function (e) {
            // show textarea
            popupDecorator.appendTo(document.body).show();
            popup.appendTo(document.body).show();
            
            // generate text
            var text = bug.info.join("\n") + "\n\nSteps:\n";
            var i = 0, steps = bug.steps, $i = steps.length;
            for (; i < $i; i++) {
                text += (i+1) + ". " + steps[i] + "\n";
            }
            popup.find("textarea").text(text).focus();
        })
    );
    
    container.append($("<br/>"));
    
    /* clear button */
    container.append(
        $("<button/>").
        css({ color: "black", width: "130px", margin: "0px 0px 5px 0px" }).
        text("Clear console").
        bind("click", function (e) {
            clearConsole();
        })
    );
    
    var node = $("<div/>").css({
        position: "absolute",
        top: "5px",
        bottom: "5px",
        left: "150px",
        right: "0px",
        overflow: "auto",
        fontSize: "9pt",
        color: "white",
        padding: "10px 10px 0px 10px"
    }).appendTo(container);

    /* shift UI? */
    var shiftUI = function () {
        $("#loginScreen").css({ width: "auto", height: "auto", top: "0px", right: "0px", bottom: height + 20 + "px", left: "0px" });
        $("#everything").css({ bottom: height + 20 + "px" });
    };
    
    con.scroll = function () {
        node[0].scrollTop = node[0].scrollHeight;
    };
    
    con.add = function (text) {

        shiftUI();
        
        /* add request part */
        var request = $("<div/>").css({
            color: "#888",
            cursor: "pointer",
            backgroundColor: "#333",
            MozBorderRadius: "5px",
            webkitBorderRadius: "5px",
            marginBottom: "2px",
            padding: "2px 5px 2px 5px",
            whiteSpace: "nowrap",
            overflow: "hidden"
        }).appendTo(node);

        /* split URL/params */
        var url = (text + "").split(/\?/);
        request.append($("<span/>").text(url[0] + ""));
        if (url.length > 1) {
            request.append($("<i/>").css({ color: "#666" }).text("?" + url[1]));
        }
        
        /* add response part */
        var response = $("<div/>").css({
            padding: "2px",
            margin: "10px 10px 10px 10px",
            backgroundColor: "lightyellow",
            color: "black",
            borderTop: "1px solid #ccc",
            lineHeight: "1.5em",
            display: "none"
        }).appendTo(request);

        request.click(function () {
            response.toggle();
        });
        
        con.scroll();

        /* return nodes */
        return {
            request: request,
            response: response
        };
    };
    
    if (!JSON || !JSON.prototype || !jQuery) {
        return;
    }

    /* override JSON */
    var add = JSON.prototype.add;
    JSON.prototype.add = function (r) {
        /* add nodes */
        var nodes = con.add(r.method + " " + r.uri);
        var t0 = (new Date()).getTime();
        /* wrap success callback */
        var success = r.cb;
        r.cb = function (response, textStatus, xhr) {
            var t1 = (new Date()).getTime();
            $("<span/>").css("color", "#888").text(" " + (t1-t0) + "ms").insertBefore(nodes.response);
            nodes.request.css("color", "#aaa");
            nodes.response.text(JSON.serialize(response));
            return success ? success.apply(this, arguments) : undefined;
        };
        /* wrap error callback */
        var error = r.errorHandler;
        r.errorHandler = function (response, status) {
            var t1 = (new Date()).getTime();
            $("<span/>").css("color", "#a00").text(" " + (t1-t0) + "ms").insertBefore(nodes.response);
            nodes.request.css("color", "#FF9D00");
            nodes.response.text(JSON.serialize(response));
            return error ? error.apply(this, arguments) : undefined;
        };
        /* call original function */
        add.call(this, r);
    };
    
    /* hook into jQuery */
    var ajax = $.ajax;
    $.ajax = function (options) {
        /* add nodes */
        var nodes = con.add((options.type || "GET").toUpperCase() + " " + options.url);
        var t0 = (new Date()).getTime();
        /* wrap success callback */
        var success = options.success;
        options.success = function (response, textStatus, xhr) {
            var t1 = (new Date()).getTime();
            $("<span/>").css("color", "#888").text(" " + (t1-t0) + "ms").insertBefore(nodes.response);
            nodes.request.css("color", "#aaa");
            if (options.dataType === "json") {
                nodes.response.text(JSON.serialize(response));
            }
            return success ? success.apply(this, arguments) : undefined;
        };
        /* call original function */
        ajax.call($, options);
    };
    
    con.log = function (type, text) {

        /* add */
        var div = $("<div/>").css({
            color: "#fff",
            MozBorderRadius: "5px",
            webkitBorderRadius: "5px",
            marginBottom: "2px",
            padding: "2px 5px 2px 5px"
        }).appendTo(node);
        
        div.text(text + "");
        
        switch (type) {
        case "module":
            div.css("backgroundColor", "#3A6187").text("Changed module: " + text);
            break;
        case "view":
            div.css("backgroundColor", "#2C4966").text("Changed view: " + text);
            break;
        case "folder":
            div.css("backgroundColor", "#527A3B").text("Changed folder: " + text);
            break;
        case "useraction":
            div.css("backgroundColor", "#6A2673").text("User action: " + text);
            break;
        case "window-open":
            div.css("backgroundColor", "#694D65").text("Window (Open): " + text);
            break;
        case "window-ready":
            div.css("backgroundColor", "#694D65").text("Window (Ready): " + text);
            break;
        case "window-close":
            div.css("backgroundColor", "#694D65").text("Window (Close): " + text);
            break;
        default:
            div.css("backgroundColor", "#555").text("" + text);
            break;
        }
        
        con.scroll();
    };
    
    /* hooks */
    ox.UIController.dispatcher.bind("modulechange", function (e) {
        con.log("module", e.module);
    });
    ox.UIController.dispatcher.bind("folderchange", function (e) {
        con.log("folder", e.folder);
    });
    register("OX_View_Changed", function (e) {
        con.log("view", e.path.join(" / "));
    });
    register("User_Action", function (e) {
        con.log("useraction", e.text);
        bug.steps.push(e.text);
    });
    register("OX_Window_Open", function (e) {
        con.log("window-open", "GUID: " + e.guid + " URL: " + e.url);
    });
    register("OX_Window_Ready", function (e) {
        con.log("window-ready", "GUID: " + e.handle + " Module: " + e.type + " Title: " + e.title);
    });
    register("OX_Window_Close", function (e) {
        con.log("window-close", "GUID: " + e.handle);
    });
    
    var init = function () {
        
        bug.info.push("Automatic bug report for " + oxProductInfo.pversion);
        con.log("info", "Date: " + new Date());
        bug.info.push("Reported on " + new Date());
        con.log("info", "Browser: " + navigator.userAgent);
        bug.info.push("With " + navigator.userAgent);
        con.log("info", "Host: " + window.location.href);
        bug.info.push("On " + window.location.href);
        con.log("info", "Version (UI): " + oxProductInfo.pversion);
        
        var onLogin = function () {
            
            // backend version
            con.log("info", "Version (Server): " + ox.api.config.get("serverVersion"));
            // language
            var language = config.language + "";
            con.log("info", "Language: " + language);
            // landing page
            var page = ox.api.config.get("gui.global.landing_page.module", "");
            con.log("info", "Landing page: " + page);
            // tree
            var tree = (ox.api.config.get("modules.folder.tree") === 1 ? "New" : "Classic");
            con.log("info", "Tree: " + tree);
            // expert mode
            var expert = (ox.api.config.get("gui.global.expert_tree") === 1 ? "Yes" : "No");
            con.log("info", "Expert: " + expert);
            // modules
            var modules = ox.util.keys(config.modules, false).join(", ");
            con.log("info", "Modules: " + modules);
            
            // info
            bug.info.push("");
            bug.info.push("Modules: " + modules);
            bug.info.push("");
            bug.info.push("Landing page: " + page + ", Language: " + language + ", Tree: " + tree + ", Expert mode: " + expert);
            
            unregister("OX_Login", onLogin);
        };
        
        register("OX_Login", onLogin);
    };
    
    var clearConsole = function () {
        node.empty();
        bug.steps = [];
    };
    
    clearConsole();
    init();
    
    shiftUI();
    
}());