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

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

/*global ox, jQuery, _, register */

ox.UINotifier = (function ($) {
    
    // vars
    var container;
    var isVisible = {
        log: true,
        info: true,
        error: true,
        ok: true,
        warn: true
    };
    
    /*
     * History
     */
    
    // history object
    var history = [], isNested = ox.api.window.isNested, core;
    
    // nested?
    if (isNested) {
        core = ox.api.window.core;
        // replace with objects from core window
        history = core.ox.UINotifier.history;
        isVisible = core.ox.UINotifier.isVisible;
    }
    
    /*
     * Init
     */
    var init = function () {
        // get offset
        var o = $("#notheader").offset() || { top: 0, left: 0 };
        // create container
        container = $("<div/>", { id: "notificationContainer" }).css({
            position: "absolute",
            top: (o.top + 10) + "px",
            right: "10px",
            width: "450px",
            height: "auto",
            zIndex: 9910 // panel hover is 9900/9901
        }).appendTo(document.body);
        // remove init
        init = $.noop;
    };
    
    /*
     * Template
     */
    var template = $("<div/>").css({
        position: "relative",
        width: "450px",
        height: "60px",
        marginBottom: "10px"
    }).append(
        $("<div/>").css({
            position: "absolute",
            top: "0px",
            right: "0px",
            bottom: "0px",
            left: "0px",
            backgroundColor: "black",
            opacity: 0.75,
            borderRadius: "20px",
            MozBorderRadius: "20px",
            webkitBorderRadius: "20px",
            boxShadow: "5px 5px 15px #111",
            MozBoxShadow: "5px 5px 15px #111",
            webkitBoxShadow: "5px 5px 15px #111"
        })
    ).append(
        $("<div/>").css({
            position: "absolute",
            top: "0px",
            right: "0px",
            bottom: "0px",
            left: "0px",
            backgroundColor: "transparent",
            border: "3px solid #ccc",
            padding: "10px 15px 10px 15px",
            textAlign: "center",
            fontSize: "9pt",
            fontWeight: "bold",
            lineHeight: "1.5em",
            color: "white",
            overflow: "hidden",
            MozBorderRadius: "20px",
            webkitBorderRadius: "20px",
            borderRadius: "20px"
        }).append(
           $("<span/>")
        ).append(
           $("<br/>")
        ).append(
           $("<span/>").css({ color: "white" })
        )
    );
    
    var styles = {
        "log": { color: "#ccc", borderColor: "#ccc #aaa #aaa #ccc" },
        "ok": { color: "#688f42", borderColor: "#82b252 #688f42 #46602d #688f42" },
        "warn": { color: "#ff8700", borderColor: "#ffa400 #ff8700 #ff8700 #ffa400" },
        "error": { color: "#c00", borderColor: "#c00 #800 #800 #a00" }
        
    };
    
    var labels = {
        "log": _("Info"),
        "ok": _("Info"),
        "warn": _("Warning"),
        "error": _("Error")
    };
    
    var out = function (type, text, data) {
        if (isVisible[type]) {
            // always init
            init();
            // clone template
            var node = template.clone(false);
            // customize
            node.children().eq(1).css(styles[type]).children().eq(0).text(labels[type] + ": ").end().eq(2).text(text + "");
            // add 
            container.append(node);
            // adjust height
            var height = Math.max(60, node.children().get(1).scrollHeight + 10);
            node.css("height", height + "px");
            // timeout
            var timer;
            // fader
            var fader = function () {
                if (node) {
                    // clear
                    $(document).add(node).unbind("mousedown", fader);
                    clearTimeout(timer);
                    // fade out
                    node.fadeOut(500, function(){
                        // remove node
                        node.remove();
                        node = null;
                    });
                }
            };
            
            // add to history
            history.push({
                type: type,
                text: text,
                time: ox.util.now(),
                data: data
            });
            
            // fade out by click
            $(document).add(node).bind("mousedown", fader);
            
            // time to live
            if (type === "ok" || type === "log") {
                timer = setTimeout(fader, 5000); // 5 seconds
            }
        }
    };
    
    // public methods/properties
    var notifier = {
        
        log: function (text, data) {
            out("log", text, data);
        },
        
        info: function (text, data) {
            out("log", text, data); // alias for log
        },
        
        error: function (text, data) {
            out("error", text, data);
        },
        
        ok: function (text, data) {
            out("ok", text, data);
        },
        
        warn: function (text, data) {
            out("warn", text, data);
        },
        
        history: history,
        
        isVisible: isVisible,
        
        getVisible: function () {
            return isVisible;
        },
        
        setVisible: function (type, state) {
            if(isVisible.hasOwnProperty(type)) {
                isVisible[type] = state;
            } else return false;
        }
    };
    
    /*
     * Register events
     */
    
    var eventHandler = function (type) {
        return function (priority, message, data) {
            // trigger global event?
            if (type === "error") {
                var trigger = isNested ? core.triggerEvent : triggerEvent;
                trigger("OX_Global_Error",priority, message, data);
            }
            notifier[type](message, data);
        };
    };
    
    register("OX_New_Error", eventHandler("error"));
    register("OX_New_Info", eventHandler("ok"));
    
    // publish
    return notifier;
    
}(jQuery));
