/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is JIM.
 *
 * The Initial Developer of the Original Code is
 * Pawel Chmielowski <prefiks@o2.pl>
 *
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 * Pawel Chmielowski <prefiks@o2.pl>
 *
 * ***** END LICENSE BLOCK ***** */

/**
 * scripts.uiscripts.Main
 *
 *
 */
ML.load("uiscripts/alertmgr.js");

function MainHandler()
{
    this.bundle = getStringBundle("chrome://jim/locale/jim.properties");
    jabberService.setErrorHandler(this);
}

MainHandler.prototype =
{
    startupTimeout: 10000,

    openXMLConsole: function()
    {
        var win = this.__getWindow("jim:xml-logger");
        if (win)
            win.focus();
        else
            open("chrome://jim/content/xmllogger.xul",
                "_blank", "chrome,resizable=yes");
    },

    handleError: function(type, exc)
    {
        processException(type, exc);
    },

    openCommandConsole: function()
    {
        var win = this.__getWindow("jim:command-console");
        if (win)
            win.focus();
        else
            open("chrome://jim/content/command.xul",
                "_blank", "chrome,resizable=yes");
    },

    editAccount: function()
    {
        var el = document.getElementById("profile-name").currentItem;

        if (el != null) {
            var win = this.__getWindow("jim:edit-account");
            if (win)
                win.focus();
            else
                openDialog("chrome://jim/content/editAccount.xul",
                    "_blank", "chrome,all,dialog=yes,modal",
                    el.getAttribute("label"));
        }
    },

    addAccount: function()
    {
        var win = this.__getWindow("jim:add-account");
        if (win)
            win.focus();
        else
            openDialog("chrome://jim/content/addaccount.xul",
                "_blank", "chrome,all,dialog=yes,modal");
    },

    addContact: function()
    {
        var win = this.__getWindow("jim:add-contact");
        if (win)
            win.focus();
        else
            openDialog("chrome://jim/content/addcontact.xul",
                "_blank", "chrome,all,dialog=yes,modal");
    },

    removeAccount: function()
    {
        var el = document.getElementById("profile-name").currentItem;

        if (el != null) {
            var win = this.__getWindow("jim:remove-account");
            if (win)
                win.focus();
            else
                openDialog("chrome://jim/content/removeAccount.xul",
                    "_blank", "chrome,all,dialog=yes,modal",
                    el.getAttribute("label"));
        }
    },

    profileChanged: function()
    {
        var el = document.getElementById("profile-name").currentItem, v;
        var info;
            
        if (!el)
            return;
        info = jabberService.core.highlevel.accounts.getAccountInfo(
            el.getAttribute("label"));

        if (info == null || info.password != null)
            document.getElementById("password-box").setAttribute("style",
                "visibility: hidden;");
        else
            document.getElementById("password-box").setAttribute("style",
                "visibility: visible;");
    },

    editVCard: function()
    {
        var win = this.__getWindowSpec("jim:vcard", jabberService.core.uidShort);

        if (win)
            win.focus();
        else
            openDialog("chrome://jim/content/vcard.xul", 
                "_blank", "chrome,all,dialog=no",
                jabberService.core.uidShort);
    },

    showAll: function(from)
    {
        var el = document.getElementById("commands.menu.jim.showAll");
        var v = el.getAttribute("checked") == "false";
        
        el.setAttribute("checked", v ? "true" : "false");
        document.getElementById('user-list').showAll = v;
    },

    setShow: function(type, show, status)
    {
        jabberService.core.highlevel.users.setPresence(type, show, status);
    },

    menuClick: function(menu, type, show, status)
    {
        menu.removeAttribute("open");
        menu.removeAttribute("_moz-menuactive");
        setTimeout(function() { menu.parentNode.hidePopup() }, 0);

        if (type == "disconnected")
            jabberService.disconnect(status);
        else
            this.setShow(type, show, status);
    },

    customStatus: function(type, show)
    {
        var win = this.__getWindow("jim:status-text");
        if (win)
            win.focus();
        else
            openDialog("chrome://jim/content/statustext.xul", 
                "_blank", "chrome,all,dialog=no", type, show);
    },

    registerAgent: function(el)
    {
        var jid = el.getAttribute("jid");
        alert("reg "+jid);
    },

    searchAgent: function(el)
    {
        var jid = el.getAttribute("jid");
        var win = this.__getWindowSpec("jim:search", jid);

        if (win)
            win.focus();
        else
            openDialog("chrome://jim/content/search.xul", 
                "_blank", "chrome,all,dialog=yes", jid);
    },

    doConnect: function()
    {
        var el = document.getElementById("profile-name").currentItem, v;
        var password = document.getElementById('password').value;
        var info;
            
        if (!el)
            return;

        info = jabberService.core.highlevel.accounts.getAccountInfo(
            el.getAttribute("label"));

        if (!info)
            return;

        jabberService.connect(info.server, info.port, info.useSSL);
        jabberService.core.iq.auth.authenticate(info.username, info.password ||
            password, info.resource);
        this.setCurrentDeck(2);
    },

    onLoad: function()
    {
        var el = document.getElementById("profile-name");
        el.database.AddDataSource(jabberService.core.highlevel.accounts.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-avaialable-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-dnd-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-away-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-xa-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-chat-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-unavailable-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("popup-user-show-disconnected-popup");
        el.database.AddDataSource(jabberService.core.highlevel.statustext.rdf.DS);
        el.builder.rebuild();

        el = document.getElementById("services-to-register");
        el.database.AddDataSource(jabberService.localRDF.DS);
        el.builder.rebuild();

        el = document.getElementById("services-to-search");
        el.database.AddDataSource(jabberService.localRDF.DS);
        el.builder.rebuild();

        el = document.getElementById("this-user");
        el.database.AddDataSource(jabberService.localRDF.DS);
        el.builder.rebuild();

        this.observer = new DataSourceObserver();
        jabberService.core.highlevel.accounts.rdf.DS.AddObserver(this.observer);

        el = document.getElementById("commands.menu.jim.showAll");
        
        document.getElementById('user-list').showAll =
            el.getAttribute("checked") == "true";

        jabberService.addObserver(this);
        jabberService.core.addObserver(this);
        jabberService.core.iq.auth.addObserver(this);
        jabberService.core.highlevel.users.addObserver(this);
        jabberService.core.highlevel.avatars.addObserver(this);
    },

    onUnload: function()
    {
        this.updateTaskbarIcon(false);
        jabberService.core.highlevel.accounts.rdf.DS.RemoveObserver(this.observer);
        jabberService.clean();
    },

    onUsersChanged: function(users, userid, resourceid)
    {
        var resource, user, show;
        var win;

        if (!resourceid || this.startup)
            return;

        resource = jabberService.core.highlevel.users.
            getInfoByResourceID(resourceid);
        user = jabberService.core.highlevel.users.
            getInfoByUserID(userid);

        if (resource.localizedName)
            alertMgr.showAlert(resource.localizedName, 
                resource.showTextual, resource.show, resource.statusTextual,
                jabberService.core.highlevel.avatars.
                    getAvatarByResourceId(resourceid) ||
                jabberService.core.highlevel.avatars.
                    getAvatarByResourceId(userid),
                resource.statusIcon);
        else
            alertMgr.showAlert(user.name, 
                user.showTextual, "unavailable", user.statusTextual,
                jabberService.core.highlevel.avatars.
                    getAvatarByResourceId(userid),
                user.statusIcon);
    },

    onAvatarChanged: function(users, userid, resourceid)
    {
        var win, resource;

        if (!resourceid)
            return;

        resource = jabberService.core.highlevel.users.
            getInfoByResourceID(resourceid);

        if (alertMgr.isOpened(resource.localizedName)) {
            alertMgr.updateAlert(null, null, null, null,
                jabberService.core.highlevel.avatars.
                    getAvatarByResourceId(resourceid));
        } else {
            this.onUsersChanged(users, userid, resourceid);
        }
    },

    onMessage: function(tag)
    {
        var thread = tag.getElementsByTagNameNS("jabber:client", "thread").item(0);
        var win;
        
        if (thread)
            win = this.__getWindowSpec("jim:chat", domToText(thread), "thread");
        else
            win = this.__getWindowSpec("jim:chat", tag.getAttribute('from'));

        if (!win)
            openDialog("chrome://jim/content/chat.xul", 
                "_blank", "chrome,all,dialog=no",
                tag.getAttribute('from'), tag);
    },

    onIQAuth: function()
    {
        this.setCurrentDeck(1);
    },

    onIQError: function(tag)
    {
        if (this.getCurrentDeck() == 2) {
            var errTag = tag.getElementsByTagName("error")[0];

            document.getElementById("jim-main-error").value =
                this.bundle.formatStringFromName(
                    "error", [errTag.getAttribute("code"), domToText(errTag)], 2);

            this.setCurrentDeck(3);
        }
    },

    onIQAuthError: function(errorCode, errorText)
    {
        document.getElementById("jim-main-error").value =
            this.bundle.formatStringFromName(
                "error", [errorCode, errorText], 2);

        this.setCurrentDeck(3);
    },

    onConnect: function(status)
    {
        this.startup = true;
    },

    onFirstResponse: function()
    {
        window.setTimeout(function(_this) { _this.startup = false; }, this.startupTimeout, this);
        this.updateTaskbarIcon(true);
    },

    onDisconnect: function(status)
    {
        this.updateTaskbarIcon(false);

        if (this.getCurrentDeck() == 2) {
            document.getElementById("jim-main-error").value =
                this.bundle.formatStringFromName(
                    "error", [status, statusCodeToString(status)], 2);
            this.setCurrentDeck(3);
        } else
            this.setCurrentDeck(0);
    },

    getCurrentDeck: function()
    {
        return document.getElementById("main-deck").selectedIndex;
    },

    setCurrentDeck: function(index)
    {
        if (index == 1) {
            document.getElementById("tools-menubar").
                setAttribute("hidden", "true");
        } else {
            document.getElementById("tools-menubar").
                removeAttribute("hidden");
        }
        document.getElementById('main-deck').selectedIndex = index;
    },

    updateTaskbarIcon: function(value)
    {
        var wmediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].
            getService(Components.interfaces.nsIWindowMediator);
        var it, win, el;

        it = wmediator.getEnumerator(null);

        while (it.hasMoreElements()) {
            win = it.getNext();
            el = win.document.getElementById("jim-statubar-icon");
            if (el)
                el.setAttribute("connected", value ? "true":"false");
        }
    },

    __getWindow: function(windowType)
    {
        var wmediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].
            getService(Components.interfaces.nsIWindowMediator);

        return wmediator.getMostRecentWindow(windowType);
    },

    __getWindowSpec: function(type, val, attr)
    {
        var wmediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].
            getService(Components.interfaces.nsIWindowMediator);
        var it, win;

        if (!attr)
            attr = "contact";

        it = wmediator.getEnumerator(type);

        while (it.hasMoreElements()) {
            win = it.getNext();
            if (win[attr] == val)
                return win;
        }
        return null;
    }
};

function DataSourceObserver()
{
    this.batchMode = false;
}

DataSourceObserver.prototype =
{
    onAssert: function(dataSource, source, property, target)
    {
        if (!this.batchMode)
            mainHandler.profileChanged();
    },

    onUnassert: function(dataSource, source, property, target)
    {
        if (!this.batchMode)
            mainHandler.profileChanged();
    },

    onChange: function(dataSource, source, property, oldTarget, newTarget)
    {
        if (!this.batchMode)
            mainHandler.profileChanged();
    },

    onMove: function(dataSource, oldSource, newSource, property, target)
    {
        if (!this.batchMode)
            mainHandler.profileChanged();
    },

    beginUpdateBatch: function(datasource)
    {
        this.batchMode = true;
    },


    endUpdateBatch: function(dataSource)
    {
        this.batchMode = false;
        mainHandler.profileChanged();
    }
}

var mainHandler = new MainHandler();