/*
 *  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.Pool
 * $Id: pool.js 79 2007-01-11 12:25:09Z hikarin $
 */

Zeromin.Pool = function(bbs, key) {
    this.bbsID  = bbs.getID();
    this.bbsDir = bbs.getBBS();
    this.cache  = [];
    this.index  = {};
    this.loaded = false;
}

Zeromin.Pool.prototype = {
    "getID": function () { this.bbsID },
    "getBBS": function () { this.bbsDir },
    "getCache": function () { return this.cache; },
    "setCache": function (cache) {
        this.cache = cache;
        return this;
    },
    "setBBS": function (id, bbs) {
        if ( this.bbsDir != bbs ) {
            this.bbsID        = id;
            this.bbsDir       = bbs;
            this.index        = {};
            this.cache.length = 0;
        }
        return this;
    },
    "setIndex": function (key, i) {
        this.index[key] = i || this.cache.length - 1;
    },
    "addCache": function (data) {
        if ( !this.loaded ) return;
        var key = data.key;
        var i   = this.index[key];
        if ( !i ) {
            this.cache.push(data);
            this.setIndex(key);
        }
        return;
    },
    "removeCache": function (keys) {
        if ( !this.loaded ) return;
        var count = 0;
        for ( var key in keys ) {
            if ( !keys[key] ) continue;
            var i = this.index[key];
            if ( i ) {
                delete this.index[key];
                this.cache.splice(i, 1);
                count++;
            }
        }
        return count;
    },
    "get": function (key)  {
        var i = this.index[key];
        return i ? this.cache[i] : { "key": "", "subject": "", "count": 0 };
    },
    "load": function (entriesByPage) {
        var self = this;
        Zeromin.getIO().load(
            [
                { "name" : "C",    "value": "bbs"   },
                { "name" : "M",    "value": "load"  },
                { "name" : "type", "value": "pool"  },
                { "name" : "bbs",  "value": this.bbsID }
            ],
            function (storage) {
                var data = storage.slurp() || [];
                var root = document.getElementById("poolRoot");
                var ls   = $(document.getElementById("poolTable")).empty();
                $("ul.nav-page", root).remove();
                for ( var i in data ) {
                    var item    = data[i];
                    var key     = item.key;
                    var subject = item.subject;
                    var count   = item.count;
                    var tdBase  = document.createElement("td");
                    tdBase.appendChild(
                        $(document.createElement("input")).attr({
                            "type" : "checkbox",
                            "name" : "key",
                            "value": key
                        }).get(0)
                    );
                    var tdPool = document.createElement("td");
                    tdPool.appendChild(
                        document.createTextNode(subject)
                    );
                    var tdKey = document.createElement("td");
                    tdKey.title = Zeromin.getDate(key);
                    tdKey.appendChild(
                        document.createTextNode(String(key))
                    );
                    var tdCount = document.createElement("td");
                    tdCount.appendChild(
                        document.createTextNode(String(count))
                    );
                    var trBase = document.createElement("tr");
                    trBase.appendChild(tdBase);
                    trBase.appendChild(tdPool);
                    trBase.appendChild(tdKey);
                    trBase.appendChild(tdCount);
                    ls.append(trBase);
                    self.setIndex(key, i);
                    self.loaded = true;
                }
                Zeromin.DOM.makePager(ls.parent(),
                    (Zeromin.intval(entriesByPage) || 15));
                Zeromin.DOM.toggleMenu("bbs");
                Zeromin.DOM.renderLeftMenu("leftPoolMenu");
                Zeromin.DOM.setFunction(
                    "POOL - " + Zeromin.getBBS().getName()
                );
                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("poolRoot")),
            function (storage) {
                var removed;
                storage.writeResult(
                    selectedMethod, {
                         "archive": "指定されたプールスレッドを過去ログに変換しました",
                         "restore": "指定されたプールスレッドを復帰させました",
                         "remove":  "指定されたプールスレッドを削除しました"
                    }
                );
                var done = storage.get("done");
                if ( selectedMethod == "restore" ) {
                    var subject = Zeromin.getBBS().getSubject();
                    for ( var i in done ) {
                        subject.addCache(self.get(i));
                    }
                    self.removeCache(done);
                }
                else if ( selectedMethod == "archive" ) {
                    var archive = Zeromin.getBBS().getArchive();
                    for ( var i in done ) {
                        archive.addCache(self.get(i));
                    }
                }
                else if ( selectedMethod == "remove" ) {
                    self.removeCache(done);
                }
                Zeromin.DOM.enableMethodSelector();
            },
            null
        );
    },
    "prepareAP": function () {
        this.executeAP("prepare_ap");
    },
    "executeAP": function(meth) {
        var self = this;
        Zeromin.getIO().load(
            this.toParam((meth || "execute_ap"),
                document.getElementById("threadAPForm")),
            function (storage) {
                var subject = Zeromin.getSubject();
                var threads = storage.get("threads");
                var result  = new String();
                var id2str  = {
                    "date": "「最終書き込み」の条件に一致したため",
                    "pos": "「スレッド位置」の条件に一致したため",
                    "res": "「レス数」の条件に一致したため",
                    "writeable": "「書き込み不可能のスレッド」の条件に一致したため"
                };
                for ( var i in threads ) {
                    var thread = threads[i];
                    var key    = thread[0];
                    var reason = thread[1].reason;
                    var value  = thread[1].value;
                    if ( reason == "date") {
                        value = Zeromin.getDate(value);
                    }
                    result += subject.get(key).subject
                           +  "\n[理由]" + id2str[reason]
                           +  ":" + value + "\n";
                }
                $("textarea#resultOfAP").val(result);
                if ( !meth ) {
                    var done = storage.get("done");
                    for ( var i in done ) {
                        self.addCache(subject.get(i));
                    }
                    subject.removeCache(done);
                    storage.writeStatus("上記条件に該当するスレッドをプーリングしました。");
                }
                else {
                    storage.writeStatus("上記条件でプールされるスレッドを表示しました。");
                }
            },
            null
        );
    },
    "render": function() {
    },
    "toParam": function (meth, query) {
        var a = (query != null) ? $(query).fastSerialize() : [];
        a.push({ "name": "bbs", "value": this.bbsID });
        a.push({ "name": "C",   "value": "pool"     });
        a.push({ "name": "M",   "value": meth       });
        return a;
    },
    "toString": function() { return this.getBBS() }
};
