/*
 *  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.BBS
 * $Id: bbs.js 139 2007-01-28 11:54:38Z hikarin $
 */

Zeromin.BBS = function(id, bbs) {
    this.bbsID    = id;
    this.bbsDir   = bbs;
    this.cache = [];
    this.index = {};
}

Zeromin.BBS.prototype = {
    "getID": function () { return this.bbsID },
    "getBBS": function () { return this.bbsDir },
    "getCache": function () { return this.cache; },
    "setCache": function (cache, add) {
        add ? this.cache.push(cache) : this.cache = cache;
        return this;
    },
    "setIndex": function (key, i) {
        this.index[key] = i || this.cache.length - 1;
    },
    "changeCategory": function (data) {
        var count = 0;
        for ( var id in data ) {
            var cat = data[id];
            if ( !cat ) continue;
            var i = this.index[id];
            if ( i ) {
                this.cache[i].category = cat;
                count++;
            }
        }
        return count;
    },
    "removeCache": function (data) {
        var count = 0;
        for ( var removedID in data ) {
            if ( !data[removedID] ) continue;
            var i = this.index[removedID];
            if ( i ) {
                delete this.index[removedID];
                this.cache.splice(i, 1);
                count++;
            }
        }
        return count;
    },
    "get": function (id) {
        var cache = this.cache;
        var i     = this.index[id];
        return i ?
            cache[i] :
            {
                "id":       "",
                "name":     "",
                "dir":      "",
                "category": ""
            };
    },
    "setBBS": function (id, bbs) {
        this.bbsID  = id;
        this.bbsDir = bbs;
        return this;
    },
    "getName": function (id) {
        return this.get(id || this.bbsID).name;
    },
    "load": function (entriesByPage) {
        var self = this;
        Zeromin.getIO().load(
            this.toParam("load", null),
            function (storage) {
                var data = storage.slurp() || [];
                var cat  = Zeromin.getCategory();
                var root = document.getElementById("bbsRoot");
                var ls   = $(document.getElementById("bbsTable")).empty();
                $("ul.nav-page", root).remove();
                for ( var i in data ) {
                    var item   = data[i];
                    var id     = item.id;
                    var dir    = item.dir;
                    var tdBase = document.createElement("td");
                    tdBase.appendChild(
                        $(document.createElement("input")).attr({
                            "type" : "checkbox",
                            "name" : "bbs",
                            "value": id
                        }).get(0)
                    );
                    var lnk = $(document.createElement('a'));
                    lnk.href("javascript:Zeromin.getBBS().getSubject("
                        + id + ",\"" + dir + "\").load()");
                    lnk.append(document.createTextNode(item.name));
                    var tdName = document.createElement("td");
                    tdName.appendChild(lnk.get(0));
                    var tdCat = document.createElement("td");
                    tdCat.appendChild(
                        document.createTextNode(cat.getName(item.category))
                    );
                    var tdDir = document.createElement("td");
                    tdDir.appendChild(
                        document.createTextNode(dir)
                    );
                    var trBase = document.createElement("tr");
                    trBase.appendChild(tdBase);
                    trBase.appendChild(tdName);
                    trBase.appendChild(tdCat);
                    trBase.appendChild(tdDir);
                    ls.append(trBase);
                    self.setIndex(id, i);
                }
                cat.renderSelectBox();
                Zeromin.DOM.makePager(ls.parent(),
                    (Zeromin.intval(entriesByPage) || 10));
                Zeromin.DOM.renderLeftMenu("leftBBSMenu");
                Zeromin.DOM.toggleMenu("global");
                Zeromin.DOM.setFunction("BBS - list");
                Zeromin.DOM.statusOK("掲示板一覧を表示しました", 1000);
                $(".Container", document).hide();
                $(root).show();
            },
            this
        );
    },
    "sendCommand": function(o) {
        var self           = this;
        var selectedMethod = (typeof o == String ? o : o.value);
        if (selectedMethod == "null") return;
        else if (selectedMethod == "remove") {
            var message = "削除すると二度と復活することが出来なくなります。\n"
                        + "指定された掲示板を削除しますか？";
            if (confirm(message) == false) return;
        }
        Zeromin.DOM.disableMethodSelector();
        Zeromin.getIO().load(
            this.toParam(selectedMethod, document.getElementById("bbsRoot")),
            function (storage) {
                storage.writeResult(
                    selectedMethod, {
                         "update": "掲示板情報を更新しました",
                         "update_index": "掲示板のインデックスを更新しました",
                         "repair_upload_file_table": "ファイルテーブルを修復しました",
                         "update_subject": "サブジェクトを更新しました",
                         "recreate_subject": "サブジェクトを再生成しました",
                         "change_category": "カテゴリを変更しました",
                         "update_bbsmenu": "BBSメニューを更新しました",
                         "repair_bbs_table": "掲示板情報を修復しました",
                         "remove": "掲示板を削除しました"
                    }
                );
                switch ( selectedMethod ) {
                    case "remove":
                    self.removeCache(storage.get("done"));
                    break;
                    case "change_category":
                    self.changeCategory(storage.get("done"));
                    break;
                    case "update_subject":
                    case "recreate_subject":
                    self.getSubject().setCache(null);
                    break;
                }
                Zeromin.DOM.enableMethodSelector();
            },
            null
        );
    },
    "create": function() {
        var self = this;
        var param = this.toParam(
            "create",
            document.getElementById("bbsCreate")
        );
        var bbs = Zeromin.DOM.deserialize(param);
        Zeromin.getIO().load(
            param,
            function (storage) {
                if ( storage.isReturnedSuccess() ) {
                    var id = storage.get("id");
                    self.setCache({
                        "id":       id,
                        "name":     bbs.BBS_TITLE,
                        "dir":      bbs.dir,
                        "category": bbs.category
                    }, true);
                    self.setIndex(id);
                }
                storage.writeStatus(
                    "掲示板を作成しました", { "2": "掲示板名がありません",
                        "3": "副掲示板名がありません",
                        "4": "ディレクトリ名がありません",
                        "5": "ディレクトリ名に不正な文字列があります",
                        "6": "ディレクトリ名に予約語が含まれています",
                        "7": "既に掲示板が存在するか、システム設定が間違っています"
                    }
                );
            },
            null
        );
    },
    "getArchive": function (id, bbs, entriesByPage) {
        var archive = Zeromin.getArchive();
        if ( !archive ) {
            archive = new Zeromin.Archive(this);
            Zeromin.setInstance("Archive", archive);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            archive.setBBS(id, bbs);
        }
        else {
            archive.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? archive.load(entriesByPage) : archive;
    },
    "getFilterIP": function (id, bbs, entriesByPage) {
        var ip = Zeromin.getFilterIP();
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            ip.setBBS(id, bbs);
        }
        else {
            ip.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? ip.load(entriesByPage): ip;
    },
    "getFilterHost": function (id, bbs, entriesByPage) {
        var host = Zeromin.getFilterHost();
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            host.setBBS(id, bbs);
        }
        else {
            host.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? host.load(entriesByPage): host;
    },
    "getFilterNGWord": function (id, bbs, entriesByPage) {
        var ngword = Zeromin.getFilterNGWord();
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            ngword.setBBS(id, bbs);
        }
        else {
            ngword.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? ngword.load(entriesByPage) : ngword;
    },
    "getLogAction": function (id, bbs, entriesByPage) {
        var logAction = Zeromin.getLogAction();
        if ( !logAction ) {
            logAction = new Zeromin.Log.Action(this);
            Zeromin.setInstance("Log.Error", logAction);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            logAction.setBBS(id, bbs);
        }
        else {
            logAction.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? logAction.load(entriesByPage) : logAction;
    },
    "getLogError": function (id, bbs, entriesByPage) {
        var logError = Zeromin.getLogError();
        if ( !logError ) {
            logError = new Zeromin.Log.Error(this);
            Zeromin.setInstance("Log.Error", logError);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            logError.setBBS(id, bbs);
        }
        else {
            logError.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? logError.load(entriesByPage) : logError;
    },
    "getLogThread": function (id, bbs, entriesByPage) {
        var logThread = Zeromin.getLogThread();
        if ( !logThread ) {
            logThread = new Zeromin.Log.Thread(this);
            Zeromin.setInstance("Log.Thread", logThread);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            logThread.setBBS(id, bbs);
        }
        else {
            logThread.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? logThread.load(entriesByPage) : logThread;
    },
    "getMetadata": function (id, bbs, metadataId) {
        var metadata = Zeromin.getMetadata();
        if ( !metadataId ) metadataId = 1;
        if ( !metadata ) {
            metadata = new Zeromin.Metadata(this, metadataId);
            Zeromin.setInstance("Metadata", metadata);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            metadata.setBBS(id, bbs);
            metadata.setID(metadataId);
        }
        else {
            metadata.setBBS(this.bbsID, this.bbsDir);
            metadata.setID(metadataId);
        }
        metadata.load(metadataId);
    },
    "getPlugin": function (id, bbs, entriesByPage) {
        var plugin = Zeromin.getPlugin();
        if ( !plugin ) {
            plugin = new Zeromin.Plugin(this);
            Zeromin.setInstance("Plugin", plugin);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            plugin.setBBS(id, bbs);
        }
        else {
            plugin.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? plugin.load(entriesByPage) : plugin;
    },
    "getPool": function (id, bbs, entriesByPage) {
        var pool = Zeromin.getPool();
        if ( !pool ) {
            pool = new Zeromin.Pool(this);
            Zeromin.setInstance("Pool", pool);
        }
        if ( id != null && bbs != null ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            pool.setBBS(id, bbs);
        }
        else {
            pool.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? pool.load(entriesByPage) : pool;
    },
    "getSetting": function (id, bbs, renderType) {
        var setting = Zeromin.getSetting();
        if ( !setting ) {
            setting = new Zeromin.Setting(this);
            Zeromin.setInstance("Setting", setting);
        }
        if ( id && bbs ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            setting.setBBS(id, bbs);
        }
        else {
            setting.setBBS(this.bbsID, this.bbsDir);
        }
        setting.load(renderType);
    },
    "getSubject": function (id, bbs, entriesByPage) {
        var subject = Zeromin.getSubject();
        if ( !subject ) {
            subject = new Zeromin.Subject(this);
            Zeromin.setInstance("Subject", subject);
        }
        if ( id && bbs ) {
            this.bbsID  = id;
            this.bbsDir = bbs;
            subject.setBBS(id, bbs);
        }
        else {
            subject.setBBS(this.bbsID, this.bbsDir);
        }
        return entriesByPage ? subject.load(entriesByPage) : subject;
    },
    "getLog": function (id, bbs) {
        var logger = Zeromin.getLogger();
        if ( !logger ) {
            logger = new Zeromin.Logger(this);
            Zeromin.setInstance("Logger", logger);
        }
        if ( id && bbs ) {
           this.bbsID  = id;
           this.bbsDir = bbs;
           logger.setBBS(id, bbs);
        }
        else {
            logger.setBBS(this.bbsID, this.bbsDir);
        }
        logger.load();
    },
    "render": function (renderType) {
        Zeromin.DOM.renderLeftMenu("leftBBSMenu");
        Zeromin.DOM.toggleMenu("global");
        $(".Container", document).hide();
        switch (renderType) {
            case "selectbox":
            this.renderSelectBox();
            break;
            case "create":
            default:
            Zeromin.DOM.setFunction("BBS - create");
            Zeromin.getCategory().renderSelectBox();
            this.renderSelectBox("しない");
            $(document.getElementById("bbsCreate")).show();
            break;
        }
    },
    "renderSelectBox": function (nullName) {
        var self = this;
        Zeromin.getIO().load(
            this.toParam("load", null),
            function (storage) {
                var data = storage.slurp();
                var cat = Zeromin.getCategory();
                var sel = $("select.bbsSelect").empty();
                if (nullName) {
                    var opt = document.createElement("option");
                    opt.appendChild(document.createTextNode(nullName));
                    opt.value = "null";
                    sel.append(opt);
                }
                for ( var i in data ) {
                    var item = data[i];
                    var opt = document.createElement("option");
                    opt.value = item.id;
                    opt.appendChild(document.createTextNode(item.name));
                    sel.append(opt);
                }
                Zeromin.DOM.hideState();
            },
            this
        );
    },
    "toParam": function (meth, query) {
        var a = (query != null) ? $(query).fastSerialize() : [];
        a.push({ "name": "C", "value": "bbs" });
        if ( meth ) a.push({ "name": "M", "value": meth });
        return a;
    }
};
