/**
 * 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) 2010 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author Viktor Pracht <viktor.pracht@open-xchange.com>
 */

var messagingServices = {
    callbacks: [],
    value: undefined,
    get: function(callback) {
        if (this.callbacks) {
            this.callbacks.push(callback);
        } else {
            callback(this.value);
        }
    },
    set: function(value) {
        if (!this.callbacks) throw "Multiple set calls";
        this.value = value;
        for (var i = 0; i < this.callbacks.length; i++) {
            this.callbacks[i](value);
        }
        this.callbacks = null;
    }
};

register("OX_Configuration_Loaded_Complete", function() {
    
    if (!configGetKey("modules.messaging.module")) return;
    
    // DynamicForm for formDescriptions
    
    function DynamicForm(title, typeController, dataController) {
        this.meta = {};
        function makeDefault(controller) {
            if (typeof controller == "string") {
                return {
                    get: function(data, value) { data[controller] = value; },
                    set: function(data) { return data[controller]; }
                };
            } else {
                return controller;
            }
        }
        this.typeController = makeDefault(typeController);
        this.dataController = makeDefault(dataController);
        ox.UI.Container.call(this);
        this.select = new ox.UI.ComboBox(title);
        var Self = this;
        this.select.changed = function() {
            var type = Self.select.get();
            for (var i = Self.children.length - 1; i > 0; i--) {
                Self.deleteWidget(Self.children[i]);
            }
            if (type && (type in Self.meta)) {
                var defs = Self.meta[type].formDescription;
                for (var i = 0; i < defs.length; i++) {
                    var def = defs[i];
                    var widget = DynamicForm.widgets[def.widget](def);
                    var controller = DynamicForm.controllers[def.widget];
                    Self.addWidget(widget, controller ? controller(def.name)
                                                      : def.name);
                    if ("defaultValue" in def) {
                        widget.default_value = def.defaultValue;
                        widget.set(def.defaultValue);
                    }
                }
            }
        };
        this.addWidget(this.select);
    }
    
    DynamicForm.prototype = extend(ox.UI.Container, {
        addContent:  function(node_id) {
            this.childWidth = this.parent.childWidth;
            this.table = newnode("div");
            this.node = this.parent.addRow(this.table);
            ox.UI.Container.prototype.addContent.apply(this, arguments);
        },
        addRow: ox.Configuration.VSplit.prototype.addRow,
        addCells: ox.Configuration.VSplit.prototype.addCells,
        setMetadata: function(meta) {
            this.meta = meta;
            var ids = [], names = [];
            for (var i in meta) {
                ids.push(i);
                names.push(meta[i].displayName);
            }
            if (ids.length) this.select.default_value = ids[0];
            this.select.setEntries(ids, names);
        },
        set: function(value) {
            this.id = value.id;
            var type = this.typeController.set(value);
            if (type === undefined || type === null) {
                type = this.select.default_value;
            }
            this.select.set(type);
            this.select.setEnabled(!this.immutableType || !this.id); 
            ox.UI.Container.prototype.set.call(this,
                this.dataController.set(value));
        },
        get: function() {
            var type = this.select.get();
            if (!type) return;
            var value = {};
            if (this.id) value.id = this.id;
            this.typeController.get(value, type);
            this.dataController.get(value,
                ox.UI.Container.prototype.get.call(this));
            return value;
        }
    });
    
    DynamicForm.widgets = {
        input: function(def) {
            return new ox.UI.Input(noI18n(def.displayName));
        },
        password: function(def) {
            return new ox.UI.Password(noI18n(def.displayName));
        },
        checkbox: function(def) {
            return new ox.UI.CheckBox(noI18n(def.displayName));
        },
        text: function(def) {
            return new ox.UI.Text(noI18n(def.displayName));
        },
        link: function(def) {
            var link = new ox.UI.Widget();
            link.default_value = "";
            link.addContent = function() {
                this.anchor = newnode("a", 0,
                    { href: this.default_value, target: "_blank" },
                    [document.createTextNode(this.default_value)]);
                this.node = this.parent.addCells(noI18n(def.displayName),
                                                 this.anchor);
                ox.UI.Widget.prototype.addContent.apply(this, arguments);
            };
            link.set = function(value) {
                this.anchor.href = value;
                this.anchor.firstChild.data = value;
            };
            link.get = function() { return this.anchor.firstChild.data; };
            return link;
        }
    };
    
    DynamicForm.controllers = {
        password: function(name) {
            return {
                get: function(data, value) { if (value) data[name] = value; },
                set: function(data) { return data[name]; }
            };
        }
    };
    
    // VSplit
    
    ox.JSON.get(
        AjaxRoot + "/messaging/service?action=all&session=" + session,
        function(reply) {
            var services = {};
            for (var i = 0; i < reply.data.length; i++) {
                services[reply.data[i].id] = reply.data[i];
            }
            messagingServices.set(services);
        });
    
    var node = new ox.Configuration.LeafNode("configuration/messaging",
        newnode("span",0,0,[
            newnode("span", 0, 0, [addTranslated(_("Messaging"))]), 
            newnode("span", { background:"orange", marginLeft:"5px",
                              padding:"2px", MozBorderRadius:"2px",
                              WebkitBorderRadius:"2px", color:"white"
                            }, 0, [addTranslated(_("Preview"))]) 
        ]));
    var split = new ox.Configuration.VSplit(node,
        _("Social Messaging accounts"), 0.3);
    split.init = function() {
        
        split.list = new LiveGrid([{
            text: _("Account"),
            index: "displayName",
            clear: LiveGrid.makeClear(""),
            set: LiveGrid.defaultSet
        }], new Selection());
        split.list.emptylivegridtext = _("No Messaging accounts configured.");

        var name = new ox.UI.Input(_("Name"));
        split.addWidget(name, "displayName");
        var form = new DynamicForm(_("Type"), "messagingService",
            "configuration");
        form.immutableType = true;
        split.addWidget(form, ox.Configuration.Group.NoField);
        messagingServices.get(function(services) {
            form.setMetadata(services);
        });
        
        // Menu
        
        //menuarrows[node.id] = {};
        var menu = MenuNodes.createSmallButtonContext("messaging.account",
            _("Accounts"));
        MenuNodes.createSmallButton(menu, "messaging.account.add", _("Add"),
            getFullImgSrc("img/menu/add_category.gif"),
            getFullImgSrc("img/menu/add_category_d.gif"),
            function() {
                split.addNew({ displayName: _("New messaging service")
                                });
                setFocus(name.formnode);
            });
        MenuNodes.createSmallButton(menu, "messaging.account.remove",
            _("Remove"),
            getFullImgSrc("img/menu/remove_category.gif"),
            getFullImgSrc("img/menu/remove_category_d.gif"), confirmDelete);
        addMenuNode(menu.node, MenuNodes.FIXED, 31);
        changeDisplay(node.id, "messaging.account");
        
        register("OX_SELECTED_ITEMS_CHANGED", function() {
            var deleteenabled = split.list.selection.count > 0;
            menuglobalzaehler = 0;
            //menuarrows[node.id]["messaging.account"] = [];
            menu_display_contents(node.id, "messaging.account", true,
                "messaging.account.add");
            menu_display_contents(node.id, "messaging.account", deleteenabled,
                "messaging.account.remove");
        });

        function confirmDelete() {
            if (!split.list.selection.count) return;
            //#. Social Messaging accounts
            newConfirm(ngettext("Delete Account", "Delete Accounts",
                                split.list.selection.count),
                //#. Social Messaging accounts
                ngettext(
                    "Are you sure you want to delete the selected account?",
                    "Are you sure you want to delete the selected accounts?",
                    split.list.selection.count),
                AlertPopup.YES | AlertPopup.NO, null, null, handleDelete);
        }
        function handleDelete() {
            var accounts = split.list.selection.getSelected();
            var data = new Array(accounts.length);
            for (var i = 0; i < accounts.length; i++) {
                data[i] = {
                    module: "messaging/account", action: "delete",
                    messagingService: accounts[i].messagingService,
                    id: accounts[i].id
                };
            }
            
            ox.JSON.put(AjaxRoot + "/multiple?session=" + session, data,
                function(reply) {
                    split.list.storage.removeIDs(accounts);
                    ox.api.folder.refresh();
                });
        }
      
    };
    
    function jsonToData(json) {
        return {
            id: { id: json.id, messagingService: json.messagingService },
            messagingService: json.messagingService,
            displayName: json.displayName,
            configuration: json.configuration
        };
    }
    
    function dataToJson(data) {
        var json = {
            messagingService: data.messagingService,
            displayName: data.displayName,
            configuration: data.configuration
        };
        if (data.id) {
            json.id = data.id.id;
            json.messagingService = data.id.messagingService;
        }
        return json;
    }
    
    function load(id, cont) {
        ox.JSON.get(AjaxRoot +
            "/messaging/account?action=get&messagingService=" +
            id.messagingService + "&id=" + id.id + "&session=" + session,
            function(reply) { cont(jsonToData(reply.data)); });
    }
    
    split.enableList = function() {
        ox.JSON.get(
            AjaxRoot + "/messaging/account?action=all&session=" + session,
            function(reply) {
                var storage = new Storage(0, [], 0, 0, 0,
                    function(id) { return id.messagingService + "/" + id.id; },
                    function(data) { return data.id; });
                var data = new Array(reply.data.length);
                for (var i = 0; i < data.length; i++) {
                    data[i] = jsonToData(reply.data[i]);
                }
                storage.append(data);
                split.list.enable(storage);
            });
    };
        
    split.load = function(cont) {
        messagingServices.get(function(services) {
            load(split.list.selection.getSelected()[0], cont);
        });
    };
    
    split.save = function(data, cont) {
        if ("id" in data) {
            ox.JSON.put(AjaxRoot +
                "/messaging/account/?action=update&session=" + session,
                dataToJson(data),
                function(reply) {
                    load(data.id, function(loadedData) {
                        split.list.storage.localUpdate([loadedData.id],
                            function(old) { return loadedData; });
                        //oMain-FolderTree.cache.update(null, true, null);
                        ox.api.folder.refresh();
                        cont(loadedData);
                    });
                });
        } else {
            ox.JSON.put(AjaxRoot + "/messaging/account/?action=new&session=" +
                session, dataToJson(data),
                function(reply) {
                    load({
                        id: reply.data,
                        messagingService: data.messagingService
                    }, function(loadedData) {
                        split.list.storage.append([loadedData]);
//                        oMain-FolderTree.cache.update(null, true, null);
                        ox.api.folder.refresh();
                        cont(loadedData);
                    });
                });
        }
    };
    
});