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

/**
 * services.highlevel.HLIconStyles
 *
 *
 */
ML.load("io/file.js");
ML.load("xml/xmldomparser.js");

/**
 * HLIconStyles
 *   Service which controls information about iconstyles
 *
 * Constructors:
 *   HLIconStyles(jabberService) - constructor
 *
 * Method:
 *   getIcons(style)
 *   installStyle(name, file)
 *   removeStyle(name)
 *
 */

function HLIconStyles(jabberService)
{
    var file, rdf, nodes, node;
    var stylesDir;

    this.jabberService = jabberService;
    this.iconstyles = [];
    this.__iconstyles = { };

    if (!(stylesDir = new File(jabberService.settingsDirectory,
        "iconstyles")).exists)
        stylesDir.createDirectory(0700);

    this.stylesDir = stylesDir.path;

    file = new File(jabberService.settingsDirectory, "iconstyles.rdf");

    this.rdf = new FileRDF(file, JIM_NAMESPACE_URI+"rdf/iconstyles#", "is");

    nodes = this.rdf.getContainer("rdf:jim-iconstyles", "seq").
        getElements();

    while (nodes.hasNext()) {
        node = nodes.getNext();

        this.iconstyles.push(node.getTarget("name").value);
        this.__iconstyles[node.getTarget("name").value] =
        { 
            url: node.getTarget("url").value,
            internal: false
        };
    }

    rdf = new FileRDF("chrome://jim/content/data/iconstyles/iconstyles.rdf",
        JIM_NAMESPACE_URI+"rdf/iconstyles#");

    nodes = rdf.getContainer("rdf:jim-iconstyles").getElements();
    while (nodes.hasNext()) {
        node = nodes.getNext();

        this.iconstyles.push(node.getTarget("name").value);
        this.__iconstyles[node.getTarget("name").value] =
        { 
            url: node.getTarget("url").value,
            internal: true
        };
    }

    node = this.rdf.getResource("rdf:jim-iconstyle")

    if (node && (node = node.getTarget("default")))
        this.__defaultstyle = node.value;
    else
        this.defaultstyle = rdf.getResource("rdf:jim-iconstyle").
            getTarget("default").value;
}

HLIconStyles.prototype =
{
    get defaultstyle ()
    {
        return this.__defaultstyle;
    },

    set defaultstyle (value)
    {
        this.rdf.getResource("rdf:jim-iconstyle").setAssertion("default", value, true);

        return this.__defaultstyle = value;
    },

    getIcons: function(style)
    {
        var r, data, parser;
        var info, icons, texts, automaton;
        var i, tags, j, tags2;
        var tOn = function(v) { return v == null ? v : domToText(v) }
        var url;

        if (!this.__iconstyles[style])
            return [];
        
        if (this.__iconstyles[style].icons)
            return this.__iconstyles[style].icons;

        if (!(url = this.__iconstyles[style].url))
            return [];
        debugger;

        r = new Reader(url+"icondef.xml");
        parser = new XMLDOMParser();
        r.open();
        data = r.read();
        r.close();
        data = parser.parseFully(data);

        icons = this.__iconstyles[style].icons = [];
        info = this.__iconstyles[style].info = { };
        texts = this.__iconstyles[style].texts = { };

        info.name = tOn(data.getElementsByTagName("name")[0]);
        info.version = tOn(data.getElementsByTagName("version")[0]);
        info.description = tOn(data.getElementsByTagName("description")[0]);
        info.creation = tOn(data.getElementsByTagName("creation")[0]);
        info.url = tOn(data.getElementsByTagName("url")[0]);
        info.home = tOn(data.getElementsByTagName("home")[0]);

        tags = data.getElementsByTagName("author");
        info.authors = [];
        for (i = 0; i < tags.length; i++)
            info.authors[i] = { jid: tags[i].getAttribute('jid'), name: domToText(tags[i]) };

        tags = data.getElementsByTagName("icon");

        for (i = 0; i < tags.length; i++) {
            icons[i] = {};
            icons[i].graphics = [];
            icons[i].sounds = [];
            icons[i].texts = [];

            tags2 = tags[i].getElementsByTagName("text");
            for (j = 0; j < tags2.length; j++) {
                icons[i].texts[j] = { lang: tags2[j].getAttribute('xml:lang'), text: domToText(tags2[j]) };
                texts[domToText(tags2[j])] = icons[i];
            }

            tags2 = tags[i].getElementsByTagName("graphic");
            for (j = 0; j < tags2.length; j++)
                icons[i].graphics[j] = { mime: tags2[j].getAttribute('mime'), url: url+domToText(tags2[j]) };

            tags2 = tags[i].getElementsByTagName("sounds");
            for (j = 0; j < tags2.length; j++)
                icons[i].sounds[j] = { mime: tags2[j].getAttribute('mime'), url: url+domToText(tags2[j]) };

            icons[i].x = tags[i].getElementsByTagName("x");
        }

        r = [];

        for (i in texts)
            r.push(i);
        r.sort(function (a,b) { return b.length - a.length});

        j = r[0];
        
        for (i = 1; i < r.length; i++)
            j += "|" + r[i].replace(/(\^|\$|\*|\+|\?|\.|\(|\)|\\|\||\{|\}|\[|\]|:)/g, "\\$1");

        this.__iconstyles[style].regexp = new RegExp(j, "g");

        return icons;
    },

    getInfo: function(style)
    {
        if (this.__iconstyles[style].icons);
            return this.__iconstyles[style].info;

        this.getIcons();
        return this.__iconstyles[style].info;
    },

    placeIcons: function(style, text)
    {
        var res;
        var beg, texts;

        this.getIcons(style);

        if (!this.__iconstyles[style]) {
            return text;
        }

        beg = 0;
        res = [];
        texts = this.__iconstyles[style].texts;

        text.replace(this.__iconstyles[style].regexp, function(found, pos) {
            res.push(text.slice(beg, pos));
            res.push([texts[found], found]);
            beg = pos+found.length;
            return found;
        });
        res.push(text.substring(beg));

        return res;
    },

    installStyle: function(jarfile) {
        var zipc = Components.classes["@mozilla.org/libjar/zip-reader-cache;1"].
            getService(Components.interfaces.nsIZipReaderCache);
        var it, zipr

        zipc.init(1);
        zipr = zipc.getZip(jarfile.file);

        it = zipr.findEntries("*/");

        if (it.hasMoreElements()) {
            if (name)
                throw "InvalidArchiwe";
            name =  it.getNext().
                QueryInterface(Components.interfaces.nsIZipEntry).name;
            name = name.substr(0, name.length-1);
        } else
            throw "InvalidArchiwe";
        if (!name)
            throw "InvalidArchiwe";
        
    },

    __installStyle: function(styleName, file, copy)
    {
        var res = this.rdf.getResource();

        this.iconstyles.push(res.value) = file.uri.spec;
        this.__iconstyles[res.value] = { 
            url: file.uri.spec,
            internal: false
        };

        this.rdf.getContainer("rdf:jim-iconstyles").
            appendElement(res);
        res.setAsertion("url", file.uri.spec, true);
        res.setAsertion("name", styleName, true);
    },

    removeStyle: function(name)
    {
        this.rdf.getContainer("rdf:jim-iconstyles").
            removeElement(name, true, true);
    },
}
