/**
 * 
 * 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 Stefan Preuss <stefan.preuss@open-xchange.com>
 * 
 */

// global var which holds a common storage with all accounts
// needed later for folder subscribe and updates
var mail_accounts;

register("OX_Configuration_Loaded", function () {	
	mail_accounts = new Storage(0, [], 0, 0, 0, 0, function(data) { return data.id; });
		
    var account_folders = {};
    function updateAccountFolders() {
        account_folders = {};
        mail_accounts.newIterate(mail_accounts.ids, emptyFunction,
            function(index, account) {
                for (var i in { trash: 1, sent: 1, drafts: 1, spam: 1 }) {
                    var fullname = account[i + "_fullname"];
                    if (fullname) account_folders[fullname] = i;
                }
            });
    }
	
	function loadAccounts(cb) {
	    // load all mail accounts
	    ox.api.account.all(function (data) {
            mail_accounts.remove(0, mail_accounts.ids.length);
            var nData = [];
            for (var i in data) {
            	nData.push(fixObject(data[i]));
            }
            mail_accounts.append(nData);
            updateAccountFolders();
            var oldStdFolder = window.isStdFolder || function() {
                return false;
            };
            window.isStdFolder = corewindow == window ? function(type) {
                return account_folders[activefolder] == type || oldStdFolder(type);
            } : function(type) {
                return account_folders[url.folder] == type || oldStdFolder(type);
            };
            ox.util.call(cb);
        });
	}
	// load 
	
	if (configGetKey("modules.mail.module") != null) {
		loadAccounts(null);
	}

	// if not enabled we won't continue
	if (configGetKey("modules.mail.module") == null) return;
		
	var node = new ox.Configuration.LeafNode("configuration/mail/accounts", 
			newnode("span",0,0,[ newnode("span",0,0,[ document.createTextNode(_("Accounts")) ])]));
	var split = new ox.Configuration.VSplit(node, _("E-Mail Accounts"), 0.28, true);
	
	/*
     * fix some properties
     */
    function fixObject (data) {
        // fix
        var copy = ox.util.clone(data);
        copy.password = null;
        copy.pop3_expunge_on_quit = !copy.pop3_expunge_on_quit;
        return copy;
    }
    
    // Helper
    function addCheckBox(accountId) {
        var checkbox = newnode("input", 0, { type: "checkbox" });
        addDOMEvent(checkbox, "click", (function() {
            return function() {
                if (typeof(accountId) != "undefined") {
                    // talk with server
                    var data = { "id": accountId, "unified_inbox_enabled": !!checkbox.checked };
                    ox.JSON.put(AjaxRoot + "/account?action=update&session=" +
                        session, data, function(reply) {
                            // notify
                            // ox.Configuration.info(_("Your settings have been saved."));
                            // updating folder tree
                    		ox.api.folder.refresh();
                            // update right checkbox (only)
                            var enabled = reply.data.unified_inbox_enabled;
                            unifiedCheckbox.set(enabled);
                            // stop asking if nothing was changes
                            split.original.unified_inbox_enabled = enabled;
                            // thx to preuss' "brilliant" idea
                            mail_accounts.data.data[accountId].unified_inbox_enabled = enabled;
                            updateAccountFolders();
                    });
                }
            }
        })());
        return checkbox;
    }

    var unifiedCheckbox;
    
	/** Init function **/
	split.init = function() {
	    var selection = new Selection();
	    var grid = new LiveGrid([
	        // Acount name
	        { 
	            text: _("Account name"),
	            clear: LiveGrid.makeClear(""),
	            set: function(div, data) {
	                if (div.firstChild)
	                    div.firstChild.data = data.name || "";
	                else
	                    div.appendChild(document.createTextNode(data.name || ""));
	            }
	        },
	        // Unified INBOX flag
	        {
	            text: _("Use Unified Mail")/* i18n */,
	            width: "12em",
	            clear: emptyFunction,
	            set: function(div, data) {
	                if (!div.firstChild) {
	                    div.appendChild(addCheckBox(data.id));
	                }
	                div.firstChild.checked = data.unified_inbox_enabled || false;
	            }
	        }
	    ], selection);
	    grid.emptylivegridtext = _("No accounts available");
	    
	    split.list = grid;
	    
	    split.enableList = function() {
	    	loadAccounts(
	    			function() {
		            	grid.enable(mail_accounts);
	    			}
	    	);
	    };
	    
	    split.save = function(data, cont) {
	    	var nData = clone(data);
	    	
	    	// remove some fields if required
	    	if (!trimStr(nData.password).length) {
	    		delete(nData.password);
	    	}
	    	if (!nData.transport_credentials) {
	    		delete(nData.transport_login);
	    		delete(nData.transport_password);
	    	}
	    	delete(nData.transport_credentials);
	    	
            if ("pop3_expunge_on_quit" in nData) {
                nData.pop3_expunge_on_quit = !nData.pop3_expunge_on_quit;
            }
            if ("mail_port" in nData) {
                nData.mail_port = parseInt(nData.mail_port);
            }
            if ("transport_port" in nData) {
                nData.transport_port = parseInt(nData.transport_port);
            }
            nData.transport_protocol = "smtp";
	    	if (nData["mail_protocol"] == "pop3") {
	    		nData.pop3_storage = "mailaccount";
	    	}
	    	
	    	if ("id" in data) {
	    		for (var i in nData) {
	        		if (nData[i] == undefined || nData[i] == "undefined") nData[i]=null; //delete(nData[i]);
	        	}
	            ox.JSON.put(AjaxRoot + "/account?action=update&session=" +
	                        session, nData, function(reply) {
	            				mail_accounts.localUpdate([data.id], function(old) {
	                                if (!equals(reply.data, old)) return reply.data;
	                            });
	            				updateAccountFolders();
	                            ox.Configuration.info(
	                                _("Your settings have been saved."));
	                            // updating folder tree
	                            ox.api.folder.refresh();
	            	            reply.data.pop3_expunge_on_quit=!reply.data.pop3_expunge_on_quit;
	            	            cont(reply.data);
	                        });
	        } else {
	        	nData.spam_handler = "NoSpamHandler";
	        	// create account
	        	ox.api.account.create({
	        	    data: nData,
	        	    success: handleNew,
	        	    error: function (error) {
	        	        triggerEvent("OX_New_Error", 4, _("Syntax error in server reply: no error provided"));
	        	    }
	        	})
	        	// TODO: remove
//	            ox.JSON.put(AjaxRoot + "/account?action=new&session=" +
//	                        session, nData, handleNew);
	        }
	    	
	    	function handleNew(data) {
	    		
	    	    // fix (already done by api call) TODO: remove
	    	    // data.pop3_expunge_on_quit=!data.pop3_expunge_on_quit;
	    	    
	    	    // add
	    		mail_accounts.append([data]);
	            ox.Configuration.info(_("Your settings have been saved."));
	            newAlert(_("Info"), _("You have set up an external E-Mail account. The sole responsibility for the availability of the external E-Mail account lies with the service provider."),
	            		function() {
		            		globalalert.SHOWAGAIN=null;
		            		cont(data);
		            		split.onNew();
	            		}
	            );

	            // updating folder tree
	            ox.api.folder.dispatcher.trigger("modify");
	            // ox.api.folder.refresh();
	        }
	    }
	    
	    split.load = function(cont) {
	    	split.right.scrollTop = 0;
	    	mail_accounts.newIterate(selection.getSelected(), emptyFunction,
	            function(i, data) {
	                if (data.errormsg) return cont();
	                var d = clone(data);
	                cont(d);
	            });
	    };
	    
	    split.onNew = function() {	    	
	    	split.right.scrollTop = 0;
	    	this.addNew({ name: _("New account") });
	    };
	    
	    
	    /*** menu items ***/
	    //menuarrows[node.id] = {};
	    
	    var accountsmenu = MenuNodes.createSmallButtonContext("mail.accounts",
	        _("Accounts"));
	    MenuNodes.createSmallButton(accountsmenu, "mail.accounts.delete",
	        _("Delete"), getFullImgSrc("img/menu/delete.gif"),
	        getFullImgSrc("img/menu/delete.gif"), confirmDelete);
	    function confirmDelete() {
	        if (!selection.count) return;
	        newConfirm(ngettext("Delete Account", "Delete Accounts", selection.count),
	            ngettext("Are you sure you want to delete the selected account?",
	                     "Are you sure you want to delete the selected accounts?",
	                     selection.count),
	            AlertPopup.YES | AlertPopup.NO, null, null, handleYes);
	    }
	    function handleYes() {
	    	mail_accounts.newIterate(selection.getSelected(), emptyFunction, handleDelete);
	    }
	    function handleDelete(idx, data) {
	        // cont
	        var cont = function () {
                grid.deleteIDs([data.id]);
                // affects current mail folder?
                var folder = ox.UIController.getFolder("mail"), cache = ox.api.cache;
                // is removed?
                if (folder !== undefined && !cache.folder0.contains(folder) && !cache.folder1.contains(folder)) {
                    // unset folder
                    ox.UIController.unsetFolder("mail");
                }
                // updating folder tree
                ox.api.folder.dispatcher.trigger("modify");
            };
	        // remove account
	        ox.api.account.remove({
	            id: data.id,
	            success: cont
	        });
	        
	    }
	    addMenuNode(accountsmenu.node, MenuNodes.FIXED, 31);
	    changeDisplay(node.id, "mail.accounts");
	    
	    register("OX_SELECTED_ITEMS_CHANGED", function() {	    	
	        var deleteenabled = selection.count >= 1;
	        if (!configGetKey("modules.mailaccount.module")) {
	        	deleteenabled = false;
	        }
	        if (grid.storage) {
	            grid.storage.newIterate(selection.getSelected(), emptyFunction, emptyFunction, updateMenu);
	        } else updateMenu();	        
	        function updateMenu() {
	            menuglobalzaehler = 0;
	            //menuarrows[node.id]["mail.accounts"] = [];
	            menu_display_contents(node.id, "mail.accounts", deleteenabled, "mail.accounts.delete");
	        }
	    });
	    
	    // need to wait that panel has been initialized
	    setTimeout(function() {
	    	menu_display_contents(node.id, "mail.accounts", false, "mail.accounts.delete");
	    	
	    	// disable new button when no multiple-accounts are allowed
	    	if (!configGetKey("modules.mailaccount.module")) {
	    		menu_display_contents("configuration/modules/0", "menu_new", false, "menu_big_new");
	    		
	    		// register to new button
		    	register("OX_NEW", function(enabled) {
		    		//trigger upsell event
		    		triggerEvent("Feature_Not_Available", "configuration/mail/accounts/new");
		    	});
	    	}
	    }, 0);
	    
	    /*** new/edit fields on the right side ***/
	    
	    /*** blank line ***/
	    var lb = function() { ox.UI.Widget.call(this); };
	    lb.prototype = extend(ox.UI.Widget, {
	        addContent: function() {
	           this.node = this.parent.addRow(newnode("br", null, false));
            }
	    });
        
        function disabler(widget) {
            return {
                get: ox.Configuration.Group.NoField.get,
                set: function(data) {
                    widget.setEnabled(data.id !== 0);
                    return data;
                }
            };
        }
        
        /*** ACCOUNT SETTINGS ***/
	    var account = new ox.Configuration.Group(_("Account Settings"));
	    var name = new ox.UI.Input(_("Account Name"));
	    account.addWidget(name, "name");
	    var primary_address = new ox.UI.Input(_("E-Mail Address"));
	    account.addWidget(primary_address, "primary_address");
	    var personal = new ox.UI.Input(_("Your name"));
	    account.addWidget(personal, "personal");
	    unifiedCheckbox = new ox.UI.CheckBox(_("Use Unified Mail for this account"));
	    account.addWidget(unifiedCheckbox, "unified_inbox_enabled");
	    account.addWidget(new lb());
        split.addWidget(account, {
            get: ox.Configuration.Group.NoField.get,
            set: function(data) {
                name.setEnabled(data.id !== 0);
                primary_address.setEnabled(data.id !== 0);
                return data;
            }
        });
	    
	    /*** SERVER SETTINGS ***/
	    var mail = new ox.Configuration.Group(_("Server Settings")); 
        split.addWidget(mail, disabler(mail));
	    
	    function changePort() {
	    	switch(mail_protocol.get()) {
	        	case "imap": 
	        		if (mail_secure.get()) {
	    	    		mail_port.set("993");
	    	    	} else {
	    	    		mail_port.set("143");	    	
	    	    	}
	        		mail_pop_note.setVisible(false);
	        		pop_refresh_rate.setVisible(false);
	        		pop_expunge_on_quit.setVisible(false);
	        		pop_delete_write_through.setVisible(false);
	        		break;
	        	case "pop3":
	        		if (mail_secure.get()) {
	    	    		mail_port.set("995");
	    	    	} else {
	    	    		mail_port.set("110");	    	
	    	    	}
	        		mail_pop_note.setVisible(true);
	        		pop_refresh_rate.setVisible(true);
	        		pop_expunge_on_quit.setVisible(true);
	        		pop_delete_write_through.setVisible(true);
	        		break;
	    	}
	    }

	    
	    var mail_protocol = new ox.UI.ComboBox(_("Server Type"));
	    mail_protocol.width = "18.5em";
	    mail_protocol.setEntries(["imap","pop3"], [_("IMAP Mail Server"),_("POP3 Mail Server")]); 
	    mail_protocol.changed = changePort;
	    mail_protocol.default_value = "imap";
	    mail.addWidget(mail_protocol, "mail_protocol");
	    
	    var mail_pop_note = new ox.UI.Text(_("Please note: All messages received from the POP3 account will be stored to a folder on your local IMAP account."));
	    mail_pop_note.disable();
	    mail_pop_note.setVisible(false);
	    mail.addWidget(mail_pop_note, ox.Configuration.Group.NoField);
	    
	    var mail_secure = new ox.UI.CheckBox(_("Use SSL connection"));
	    mail.addWidget(mail_secure, "mail_secure");
	    mail_secure.changed = changePort;
	    
	    var mail_server = new ox.UI.Input(_("Server Name")); 
	    mail.addWidget(mail_server, "mail_server");
	    var mail_port = new ox.UI.Input(_("Server Port"));
	    mail_port.default_value = "143";
	    mail.addWidget(mail_port, "mail_port");
	    
	    var login = new ox.UI.Input(pgettext("username", "Login"));
	    mail.addWidget(login, "login");
	    var password = new ox.UI.Password(_("Password"));
	    mail.addWidget(password, "password");
	    
	    var pop_refresh_rate = new ox.UI.ComboBox(_("Check for new messages every 'n' minutes"));
	    pop_refresh_rate.width = "5em";	    
	    pop_refresh_rate.setEntries(["3","5","10","15","30","60","360"], ["3","5","10","15","30","60","360"]);
	    pop_refresh_rate.setVisible(false);
	    mail.addWidget(pop_refresh_rate, "pop3_refresh_rate"); 
	    
	    var pop_expunge_on_quit = new ox.UI.CheckBox(_("Leave messages on server"));
	    pop_expunge_on_quit.setVisible(false);
	    pop_expunge_on_quit.changed = function() {
	    	if (pop_expunge_on_quit.get() == false) {
	    		pop_delete_write_through.set(false);
	    	}
	    	pop_delete_write_through.setEnabled(pop_expunge_on_quit.get());	    	
	    }
	    mail.addWidget(pop_expunge_on_quit, "pop3_expunge_on_quit");
	    
	    var pop_delete_write_through = new ox.UI.CheckBox(_("Deleting messages on local storage also deletes them on server"));
	    pop_delete_write_through.setEnabled(false);
	    mail.addWidget(pop_delete_write_through, "pop3_delete_write_through");
	    
	    mail.addWidget(new lb());
	    
	    /*** TRANSPORT SETTINGS ***/
	    var transport = new ox.Configuration.Group(_("Outgoing Server Settings (SMTP)"));
	    split.addWidget(transport, disabler(transport));
	    
	    var transport_secure = new ox.UI.CheckBox("Use SSL connection");
	    transport.addWidget(transport_secure, "transport_secure");
	    transport_secure.changed = function() {
	    	if (transport_secure.get()) transport_port.set("465");
	    	else transport_port.set("25");
	    };
	    
	    transport.addWidget(new ox.UI.Input(_("Server Name")), "transport_server");
	    
	    var transport_port  = new ox.UI.Input(_("Server Port"));
	    transport_port.default_value = "25";
	    transport.addWidget(transport_port, "transport_port");
	    
	    var transport_credentials = new ox.UI.CheckBox(_("Use username and password"));
	    transport.addWidget(transport_credentials, "transport_credentials");
	    transport_credentials.changed = function(bool) {
	    	var bool = transport_credentials.get();
	    	transport_login.setEnabled(bool);
	    	transport_password.setEnabled(bool);
	    };
	    
	    var transport_login = new ox.UI.Input(pgettext("username", "Login"));	    
		transport.addWidget(transport_login, "transport_login");		
		transport_login.disable();
		
		var transport_password = new ox.UI.Password(_("Password"));
		transport.addWidget(transport_password, "transport_password");
		transport_password.disable();
		
	    split.addWidget(new lb());
	    
	    /*** FOLDER SETTINGS ***/	    
	    var folder = new ox.Configuration.Group(_("Folder Settings"));
	    split.addWidget(folder, {
            get: ox.Configuration.Group.NoField.get,
            set: function(data) {
                folder.setVisible(Boolean(data.id));
                return data;
            }
        });
	    	    
	    var sent_fullname = new temporary.MailFolderSelection(_("Sent folder"));        
	    sent_fullname.width = "30em";
	    folder.addWidget(sent_fullname, "sent_fullname");
        
        var trash_fullname = new temporary.MailFolderSelection(_("Trash folder"));        
        trash_fullname.width = sent_fullname.width;
        folder.addWidget(trash_fullname, "trash_fullname");
        
        var drafts_fullname = new temporary.MailFolderSelection(_("Drafts folder"));        
        drafts_fullname.width = sent_fullname.width;
        folder.addWidget(drafts_fullname, "drafts_fullname");
        
        var spam_fullname = new temporary.MailFolderSelection(_("Spam folder"));        
        spam_fullname.width = sent_fullname.width;
        folder.addWidget(spam_fullname, "spam_fullname");
	    
        folder.addWidget(new lb());
        
        /*** BUTTONS ***/
	        
	    var buttons = new ox.Configuration.HLayout();
	    
	    var check_button = new ox.UI.Button(_("Check connection"));
	    check_button.click = function() { 
	    	newAlert(_("Info"), _("Please wait while checking the connection ... This may take a while ..."));
	    	$(globalalert.visibleButtons[0].id).style.display="none";
	    	var data = clone(split.get());
	    	if (selection.getSelected().length == 1) {
	    		data.id = selection.getSelected()[0];
	    		delete(data.password);
	    	}
	    	data.tree = false;
	    	ox.JSON.put(AjaxRoot + "/account?action=validate&session=" + session, data, 
	    			function(reply) {	    				
        				newAlert(_("Info"), reply.data ? _("The connection was successful.") : _("Connection failed! Please check your settings."));
                    },
                    function(reply) {
                    	newAlert(_("Error"), _("Connection failed! Please check your settings: ") + formatError(reply));
                    	return true;
                    });
	    };
        buttons.addWidget(check_button);
        split.addWidget(buttons, {
            get: emptyFunction,
            set: function(data) { check_button.setEnabled(data.id !== 0); }
        });
	    
	    var save_button = new ox.UI.Button(_("Save"));
	    save_button.click = function(data, pata) {
	    	function fail(field) {
	    		setTimeout(function() { 
	    		    //#. %1$s is the field name.
	    		    //#, c-format
	    			triggerEvent("OX_New_Error", 4, format(_("The mandatory field %1$s is not defined."), field)); 
	    		}, 0);
	    		return;
	    	}
	    	if (name.get() == "") {
	    		name.formnode.focus();
	    		return fail(_("Account Name"));
	    	} else if (primary_address.get() == "") {	  
	    		primary_address.formnode.focus();
	    		return fail(_("E-Mail Address"));	 
	    	} else if (mail_server.get() == "") {
	    		mail_server.formnode.focus();
	    		return fail(_("Server Name"));
    		} else if (login.isEnabled && login.get() == "") {
	    		login.formnode.focus();
	    		return fail(_("Login"));
    		} else if (!split["id"] && password.isEnabled && password.get() == "") {
    			password.formnode.focus();
	    		return fail(_("Password"));
    		}
	    	split.saveView(); 	    	
	    };
	    buttons.addWidget(save_button);
	
	    var cancel_button = new ox.UI.Button(_("Cancel"));
	    cancel_button.click = function() { split.cancelView(); };
	    buttons.addWidget(cancel_button);
	    
	    //split.disable();
	}
});