/*
 *  Copyright 2007 hkrn <hikarin@users.sourceforge.jp>
 *
 *  Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * Zeromin.Plugin
 * $Id: plugin.js 79 2007-01-11 12:25:09Z hikarin $
 */

Zeromin.Plugin = function(id, bbs, key) {
    this.bbsID   = id  || 0;
    this.bbsDir  = bbs || '';
    this.key     = key || 0;
    this.cache   = null;
    this.plugins = {};
    this.loaded  = false;
}

Zeromin.Plugin.prototype = {
    "getID": function () { return this.bbsID },
    "getBBS": function () { return this.bbsDir },
    "getCache": function () { return this.cache; },
    "setCache": function (cache, add) {
        add ? this.cache.unshift(cache) : this.cache = cache;
        return this;
    },
    "get": function(id) {
        var cache  = this.cache;
        var plugin = cache[id];
        return plugin ? plugin
            : {
                "class": "",
                "method": "",
                "type": "",
                "enabled": 0
        };
    },
    "removeCache": function (data) {
        var count = 0;
        for ( var removedID in data ) {
            if ( !data[removedID] ) continue;
            var i = this.cache[removedID];
            if ( i ) {
                delete this.cache[removedID];
                count++;
            }
        }
        return count;
    },
    "setBBS": function (id, bbs) {
        this.key = 0;
        if ( this.bbsDir != bbs ) {
            this.bbsID   = id;
            this.bbsDir  = bbs;
            this.cache   = null;
            this.plugins = {};
            this.loaded  = false;
        }
        return this;
    },
    "setKey": function (key) {
        if ( this.key != key ) {
            this.key = key;
        }
        return this;
    },
    "load": function (entriesByPage, searchPlugin) {
        var self = this;
        var topmenu, leftmenu;
        if ( this.key ) {
            topmenu  = "thread";
            leftmenu = "leftThreadMenu";
            $("select[@name='M']",
                document.getElementById("pluginRoot")).hide();
        }
        else if ( this.bbsID ) {
            topmenu  = "bbs";
            leftmenu = "leftBBSPluginMenu";
            $("select[@name='M']",
                document.getElementById("pluginRoot")).show();
        }
        else {
            topmenu  = "global";
            leftmenu = "leftGlobalPluginMenu";
            $("select[@name='M']",
                document.getElementById("pluginRoot")).show();
        }
        if ( !searchPlugin ) searchPlugin = "null";
        Zeromin.getIO().load(
            this.toParam("load"),
            function (storage) {
                var data = storage.read() || [];
                var root = document.getElementById("pluginRoot");
                $("ul.nav-page", root).remove();
                var ls   = $(document.getElementById("pluginTable")).empty();
                var bbs  = self.bbsID || 0;
                var key  = self.key   || 0;
                if ( searchPlugin != "null" ) {
                    var tmp = {};
                    for ( var id in data ) {
                        var plugin = data[id];
                        if ( plugin["class"] == searchPlugin ) {
                            tmp[id] = plugin;
                        }
                    }
                    data = tmp;
                }
                for ( var id in data ) {
                    var item   = data[id];
                    var cls    = item["class"];
                    var tdBase = document.createElement("td");
                    if ( !key ) {
                        tdBase.appendChild(
                            $(document.createElement("input")).attr({
                                "type"   : "checkbox",
                                "name"   : "id",
                                "value"  : id,
                                "checked": (item.enabled ? true : false)
                            }).get(0)
                        );
                    }
                    var lnk = $(document.createElement('a'));
                    lnk.href(
                        "javascript:Zeromin.getPlugin().renderConfig(\""
                        + id + "\",\"" + bbs + "\",\"" + key + "\")"
                    );
                    lnk.append(document.createTextNode(cls));
                    var tdClass = document.createElement("td");
                    tdClass.appendChild(lnk.get(0));
                    var tdMethod = document.createElement("td");
                    tdMethod.appendChild(
                        document.createTextNode(item["method"])
                    );
                    var tdCallFrom = document.createElement("td");
                    tdCallFrom.appendChild(
                        document.createTextNode(item.type)
                    );
                    var trBase = document.createElement("tr");
                    trBase.appendChild(tdBase);
                    trBase.appendChild(tdClass);
                    trBase.appendChild(tdMethod);
                    trBase.appendChild(tdCallFrom);
                    ls.append(trBase);
                    if ( !self.loaded ) self.plugins[cls] = id;
                }
                if ( !self.loaded ) {
                    self.renderSelectBox("以下のプラグインで絞りこむ");
                    self.loaded = true;
                }
                Zeromin.DOM.makePager(ls.parent(),
                    (Zeromin.intval(entriesByPage) || 15));
                Zeromin.DOM.renderLeftMenu(leftmenu);
                Zeromin.DOM.toggleMenu(topmenu);
                Zeromin.DOM.setFunction("PLUGIN - list");
                Zeromin.DOM.statusOK("プラグイン一覧を表示しました", 1000);
                Zeromin.DOM.changePage(root);
            },
            this
        );
    },
    "save": function (methodValue) {
        if ( methodValue == "null" ) return false;
        var param;
        var root = document.getElementById("pluginRoot");
        if ( methodValue == "search" ) {
            param = this.toParam(methodValue, root);
        }
        else {
            param = this.toComplicatedParam(methodValue, root);
        }
        var self  = this;
        var plugin = Zeromin.DOM.deserialize(param);
        Zeromin.DOM.disableMethodSelector();
        Zeromin.getIO().load(
            param,
            function (storage) {
                if ( storage.isReturnedSuccess() ) {
                    if ( methodValue == "search" ) {
                        var found = storage.get().found;
                        Zeromin.DOM.statusOK(
                            found + "個のプラグインが新規追加されました",
                            1000
                        );
                        if ( found ) {
                            self.setCache(null);
                        }
                    }
                    else {
                        var res = storage.get("content");
                        if ( res != null ) {
                            var enabled  = Zeromin.intval(res.enable);
                            var disabled = Zeromin.intval(res.disable);
                            Zeromin.DOM.statusOK(
                                  String(enabled)
                                + "個のプラグインを有効に、"
                                + String(disabled)
                                + "個のプラグインを無効にしました",
                                1000
                            );
                            for ( var i in plugin ) {
                                if (/^p(\d+)$/.test(i)) {
                                    self.cache[RegExp.$1].enabled =
                                        plugin[i] ? true : false;
                                }
                            }
                        }
                    }
                }
                Zeromin.DOM.enableMethodSelector();
            },
            null
        );
    },
    "saveConfig": function () {
        Zeromin.getIO().load(
            this.toParam("config",
                document.getElementById("pluginConfigRoot")),
            function (storage) {
                storage.writeStatus(
                    "プラグインの設定を保存しました",
                    { "2": "指定されたプラグインのIDは存在しません" }
                );
            },
            null
        );
    },
    "render": function (renderType) {},
    "renderConfig": function (pluginId, bbs, key) {
        var self = this;
        Zeromin.getIO().load(
            [
                { "name": "C",    "value": "plugin" },
                { "name": "M",    "value": "config" },
                { "name": "type", "value": "load"   },
                { "name": "id",   "value": pluginId },
                { "name": "bbs",  "value": bbs      },
                { "name": "key",  "value": key      }
            ],
            function (storage) {
                if ( storage.get("rendererable") ) {
                    try {
                        eval(storage.get("javascript"));
                        $(document.getElementById("pluginConfigHTML")).html(
                            storage.get("html"));
                        var info = self.get(pluginId);
                        Zeromin.DOM.setFunction(
                            "PLUGIN - "
                            + info["class"] + "::"
                            + info["method"] + "()"
                        );
                        Zeromin.DOM.hideState();
                        Zeromin.DOM.changePage(
                            document.getElementById("pluginConfigRoot"));
                    } catch(e) {
                        Zeromin.DOM.statusNG(
                            "設定項目構築中にエラーが発生しました<br />"
                            + e.toString()
                        );
                    }
                }
                else {
                    Zeromin.DOM.statusNG("指定されたプラグインの設定項目はありません");
                }
            },
            null
        );
    },
    "renderSelectBox": function (nullName) {
        var sel = $("select.pluginSelect").empty();
        if (nullName) {
            var opt = document.createElement("option");
            opt.appendChild(document.createTextNode(nullName));
            opt.value = "null";
            sel.append(opt);
        }
        var data = this.plugins;
        var tmp  = [];
        for ( var i in data ) { tmp.push(i) }
        var plugin = tmp.sort();
        for ( var i in plugin ) {
            var opt   = document.createElement("option");
            var cls   = plugin[i]
            opt.value = cls;
            opt.appendChild(document.createTextNode(cls));
            sel.append(opt);
        }
    },
    "toComplicatedParam": function(meth, query) {
        var a;
        if ( query != null ) {
            var q = $(query);
            a = q.fastSerialize();
            q.find("input[@name='id']").each(function(){
                a.push({ "name": "plugin", "value": this.value });
            });
        }
        else {
            a = [];
        }
        a.push({ "name": "C",   "value": "plugin"   });
        a.push({ "name": "M",   "value": meth       });
        a.push({ "name": "bbs", "value": this.bbsID });
        return a;
    },
    "toParam": function (meth, query) {
        var a = (query != null) ? $(query).fastSerialize() : [];
        a.push({ "name": "C",   "value": "plugin"   });
        a.push({ "name": "M",   "value": meth       });
        a.push({ "name": "bbs", "value": this.bbsID });
        a.push({ "name": "key", "value": this.key   });
        return a;
    },
    "toString": function() { return "" }
};
