// ----------------------------------------------------------------------------
// MJL
// ----------------------------------------------------------------------------
MJL.event.add(window, "load", function(event) {

    // image + document
    // -----------------------------------------------------------------
    // 画像とテキストの並列処理を行う関数を返す高階関数
    function getImgParallelStyler(side) {
        return function() { // 実行関数
            var obj = $(this);
            var imgBlock = $("div.img:first-child", obj);
            var imgWidth = $("p.img img", imgBlock).width(); // 画像幅
            imgBlock.css("width", imgWidth +"px"); // 画像幅を強制
            $("div.column", obj).css("margin-"+ side, imgBlock[0].offsetWidth +"px");
        };
    }
    // 処理
    $("#main div.doc-img").each(function() {
        $(".img-parallel.img-l").each(getImgParallelStyler("left"));
        $(".img-parallel.img-r").each(getImgParallelStyler("right"));
    });

    // window
    // -----------------------------------------------------------------
    MJL.enable.window("qrcord", {
        width : 320,
        height : 320
    });

    // rollover
    // -----------------------------------------------------------------
    MJL.enable.rollover("roll", {disable: "unroll"});

    // flash
    // -----------------------------------------------------------------
    MJL.enable.flash("flash", {version: 10});

    // tab
    // -----------------------------------------------------------------
    MJL.enable.tab("tabs");

    // height equalizer
    // -----------------------------------------------------------------
    MJL.enable.heightEqualizer("lyt-2col-01", {
        groupBy: 2,
        collect: function(parent) {
            return MJL.getElementsByClassName(parent, "equalize");
        }
    });
    MJL.enable.heightEqualizer("lyt-2col-02", {
        groupBy: 2,
        collect: function(parent) {
            return MJL.getElementsByClassName(parent, "equalize");
        }
    });
    MJL.enable.heightEqualizer("lyt-3col-01", {
        groupBy: 3,
        collect: function(parent) {
            return MJL.getElementsByClassName(parent, "equalize");
        }
    });
    MJL.enable.heightEqualizer("list-link-2col", {groupBy: 2});
    MJL.enable.heightEqualizer("list-link-3col", {groupBy: 3});
    MJL.enable.heightEqualizer("list-link-4col", {groupBy: 4});
    MJL.enable.heightEqualizer("nav-contents-01", {groupBy: 2});

}, false);


// ----------------------------------------------------------------------------
// jQuery
// ----------------------------------------------------------------------------
$(function() {

    // global navigation
    // -----------------------------------------------------------------
    (function() {
        var cat = $('head').attr('id'),
            gn = $('li#ng-'+ cat);
        // head に id がある 且つ それに紐付いたグローバルナビ項目があれば発動
        if (cat && (gn.length > 0)) {
            $(gn[0]).addClass('unroll'); // MJL.enable.rollover を OFF
            var src = $('a img', gn[0]).attr('src'),
                _src = src.replace('.jpg', '_o.jpg');
            $('a img', gn[0]).attr('src', _src); // カレントに置き換える
        }
    })();

    // placeholder
    // -----------------------------------------------------------------
    (function() {
        $('#site-search .placeholder').each(function() {
            var root  = $(this),                      // 包含ブロック
                lab   = $('label', root),             // label 要素
                input = $('#'+lab.attr('for'), root); // label に関連づいた要素
            // アクティブにしてから
            root.addClass('run');
            // 位置取得
            var rpos = root.offset(),  // 包含ブロック
                ipos = input.offset(); // input
            // label 要素 設定
            lab.css({
                // input 左上を原点として位置あわせ
                // input の padding と border も加算して最適位置にする
                top  : Math.abs(
                      ipos.top - rpos.top
                    + (parseInt(input.css('borderTopWidth'), 10) || 0)
                    + (parseInt(input.css('paddingTop'), 10) || 0)
                ),
                left : Math.abs(
                      ipos.left - rpos.left
                    + (parseInt(input.css('borderLeftWidth'), 10) || 0)
                    + (parseInt(input.css('paddingLeft'), 10) || 0)
                ),
                // line-height もあわせないとうまく位置が揃わない
                lineHeight : input.css('lineHeight')
            }).click(function() {
                lab.hide();
                // label の文言を範囲選択した場合にフォーカスしない問題に対応
                input.trigger('focus');
            });
            // input 要素 設定
            input.focus(function() {
                // label 消去
                lab.hide();
            }).blur(function() {
                // 内容がなければ label を出す
                !$.trim(input.val()) && lab.show();
            });
            // ロード時に内容があれば label を隠す (例: ヒストリ遷移)
            $.trim(input.val()) && lab.hide();
        });
    })();

});


// ----------------------------------------------------------------------------
// MJL Extensions
// ----------------------------------------------------------------------------
(function(window, document) {
    // アクティブタブ class 属性値
    var active = "active";
    // isZoomed 用ズーム基準要素取得
    var getZoomObj = function() {
        return document.getElementById("str-contents") || document.body;
    };

    // isSameNode: 同一ノードの是非を取得
    MJL.isSameNode = document.isSameNode ? function(n1, n2) {
        return n1.isSameNode(n2); // W3C DOM
    } : function(n1, n2) {
        return (n1 == n2);        // Trident etc.
    };

    // --------------------------------
    // event
    // --------------------------------
    // 発送 (= fire)
    MJL.event.dispatch = document.createEvent ? (function() {   // W3C DOM
        // DOM Events レベル
        // BUG Fx2: DOM3 は未サポート部分が多い為使わない
        var level = (MJL.ua.gecko && MJL.ua.version < 3) ? "DOM2" : "DOM3";
        // event オブジェクト初期化
        var initEvent = function(event, init, type, options) {
            event[init].apply(event, [type].concat(options));
        };

        // Sf2 専用設定
        if (MJL.ua.webkit && MJL.ua.version < 3) {
            // BUG Sf2: DOM2 しかサポートしていない
            // BUG Sf2: document.createEvent に未サポートの種類を与えると
            //          "DOM Exception 9" 例外発生
            level = "DOM2";
            // BUG Sf2: 初期化メソッドは initEvent しかサポートしていない
            // BUG Sf2: initEvent.apply が未定義
            initEvent = function(event, init, type, options) {
                // options[2] 以降は全て無視
                event.initEvent(type, options[0], options[1]);
            };
        }

        return function(node, type, bubbles) {
            // イベント種類別 初期化情報
            var data = this._TYPES[level][
                type in this._TYPES[level] ? type : "DEFAULT"
            ];
            // event オブジェクト
            var event = document.createEvent(data.type);
            // 初期化メソッドに与える引数の設定
            var options = ("function" === typeof data.def) ? data.def(node)
                                                           : data.def;
            if ("boolean" === typeof bubbles) {
                options[0] = bubbles;
            }
            // 初期化
            initEvent(event, data.init, type, options);
            return node.dispatchEvent(event);
        };
    })() : document.fireEvent ? function(node, type, bubbles) { // Trident
        var event = document.createEventObject();
        event.cancelBubble = !bubbles;
        return node.fireEvent("on"+type, event);
    } : null;

    // DOM Events デフォルト設定一覧
    // {
    //     DOM Events レベル : {
    //         イベント名 : {
    //             type : カテゴリ,
    //             init : 初期化メソッド名,
    //             // 通常
    //             def  : [パラメタデフォルト値, ...]
    //             // relatedTarget 必要時
    //             def : function(relatedTarget) {
    //                 return [パラメタデフォルト値, ...];
    //             }
    //         }, ...
    //     }, ...
    // }
    MJL.event._TYPES = {
        DOM2 : (function() {
            // カテゴリ
            var UI_EVENT    = "UIEvents",
                MOUSE_EVENT = "MouseEvents",
                HTML_EVENT  = "HTMLEvents",
            // 初期化メソッド名
                INIT_UI_EVENT    = "initUIEvent",
                INIT_MOUSE_EVENT = "initMouseEvent",
                INIT_HTML_EVENT  = "initEvent";
            return {
                // 未定義時のデフォルト
                "DEFAULT"     : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  true]},
                // 定義済イベント種類 (仕様の一部のみ)
                "click"       : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mousedown"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseup"     : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseover"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : function(relatedTarget) { return [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, relatedTarget]; }},
                "mousemove"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseout"    : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : function(relatedTarget) { return [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, relatedTarget]; }},
                "load"        : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [false, false]},
                "unload"      : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [false, false]},
                "abort"       : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false]},
                "error"       : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false]},
                "select"      : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false]},
                "change"      : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false]},
                "focus"       : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [false, false]},
                "blur"        : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [false, false]},
                "resize"      : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false, window, 1]},
                "scroll"      : {type : HTML_EVENT,  init : INIT_HTML_EVENT,  def : [true,  false, window, 1]}
            };
        })(),
        DOM3 : (function() {
            // カテゴリ
            var UI_EVENT    = "UIEvent",
                TEXT_EVENT  = "TextEvent",
                MOUSE_EVENT = "MouseEvent",
                EVENT       = "Event",
            // 初期化メソッド名
                INIT_UI_EVENT    = "initUIEvent",
                INIT_TEXT_EVENT  = "initTextEvent",
                INIT_MOUSE_EVENT = "initMouseEvent",
                INIT_EVENT       = "initEvent";
            return {
                // 未定義時のデフォルト
                "DEFAULT"     : {type : EVENT,       init : INIT_EVENT,       def : [true,  true]},
                // 定義済イベント種類 (仕様の一部のみ)
                "focus"       : {type : UI_EVENT,    init : INIT_UI_EVENT,    def : [false, false, window, 1]},
                "blur"        : {type : UI_EVENT,    init : INIT_UI_EVENT,    def : [false, false, window, 1]},
                "click"       : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "dblclick"    : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 2, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mousedown"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseup"     : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 1, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseover"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : function(relatedTarget) { return [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, relatedTarget]; }},
                "mousemove"   : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, null]},
                "mouseout"    : {type : MOUSE_EVENT, init : INIT_MOUSE_EVENT, def : function(relatedTarget) { return [true,  true,  window, 0, 0, 0, 0, 0, false, false, false, false, 0, relatedTarget]; }},
                "load"        : {type : EVENT,       init : INIT_EVENT,       def : [false, false]},
                "unload"      : {type : EVENT,       init : INIT_EVENT,       def : [false, false]},
                "abort"       : {type : EVENT,       init : INIT_EVENT,       def : [true,  false]},
                "error"       : {type : EVENT,       init : INIT_EVENT,       def : [true,  false]},
                "select"      : {type : EVENT,       init : INIT_EVENT,       def : [true,  false]},
                "change"      : {type : EVENT,       init : INIT_EVENT,       def : [true,  false]},
                "resize"      : {type : UI_EVENT,    init : INIT_UI_EVENT,    def : [true,  false, window, 1]},
                "scroll"      : {type : UI_EVENT,    init : INIT_UI_EVENT,    def : [true,  false, window, 1]}
            };
        })()
    };

    // --------------------------------
    // HeightEqualizer
    // --------------------------------
    // BUG IE7: Tab との組み合わせでリサイズが発生しない問題の修正
    if (MJL.ua.trident && 7 === MJL.ua.version) {
        MJL.HeightEqualizer.prototype.__setAutoResize =
            MJL.HeightEqualizer.prototype._setAutoResize;
        MJL.HeightEqualizer.prototype._setAutoResize = function() {
            this.__setAutoResize();
            var obj = this;
            // this.parent の resize で無理矢理リサイズ
            MJL.event.add(this.parent, "resize", function() {
                obj.set();
            }, false);
        };
    }

    // --------------------------------
    // Tab
    // --------------------------------
    // アクティブタブ＆コンテンツ切替
    MJL.Tab.prototype._active = MJL.Tab.prototype.active;
    MJL.Tab.prototype.active = function(id) {
        var aid = this._getActiveId();
        this._active.apply(this, arguments);
        if (!this._isValidId(id)) { id = aid; }
        // Rollover アクティベート対応
        MJL.event.dispatch(this.items[id].event, "focus", false);
        if (id !== aid) {
            MJL.event.dispatch(this.items[aid].event, "blur", false);
        }
        // resize イベント発送
        if (MJL.ua.trident && 7 <= MJL.ua.version) { // IE7 以降
            // MJL 2.0.7 で追加した無限ループ回避 hack に抵触
            // resize イベントの dispatch が無効になってしまう
            // window.fireEvent が無いためコールスタックで代用
            MJL.event._runStack("resize");
        } else {                                     // IE6, その他
            // HeightEqualizer 自動リサイズ強制作動
            MJL.event.dispatch(this.items[id].panel, "resize", true);
        }
    };

    // --------------------------------
    // style
    // --------------------------------
    // body 要素以外の (style.Switcher による) テキストサイズ変化に対応
    MJL.style.isZoomed = (function() {
        // font-size の Computed Style + ViewPort サイズを利用
        // BUG Opera: ズーム時に Computed Style 値が再計算されない
        if (MJL.ua.opera) {
            var innserSize = 0;    // ViewPort サイズ
            var fontSize   = 0;    // font-size の Computed Style
            var obj        = null; // 計測対象
            // ViewPort サイズがなぜか増減することを併用
            // 但し、何らかの DOM スタイル操作で ViewPort のスクロールバーが
            // 縦横同時に出現した場合、ズームされなくとも true を返す
            // font-size の Computed Style はスタイルスイッチ & 直接変更
            MJL.event.add(window, "load", function() {
                obj       = getZoomObj();
                innerSize = MJL.vp.getInnerSize();
                fontSize  = MJL.style.getComputed(obj, "fontSize");
            }, false);
            return function() {
                var nowInnerSize = MJL.vp.getInnerSize();
                var nowFontSize  = MJL.style.getComputed(obj, "fontSize");
                if (innerSize.width  === nowInnerSize.width  &&
                    innerSize.height === nowInnerSize.height &&
                    fontSize         === nowFontSize) { return false; }
                innerSize = nowInnerSize;
                fontSize  = nowFontSize;
                return true;
            };
        // font-size の Computed Style を利用
        } else {
            var size = 0;    // font-size の Computed Style
            var obj  = null; // 計測対象
            MJL.event.add(window, "load", function() {
                obj  = getZoomObj();
                size = MJL.style.getComputed(obj, "fontSize");
            }, false);
            return function() {
                var nowsize = MJL.style.getComputed(obj, "fontSize");
                if (size === nowsize) { return false; }
                size = nowsize;
                return true;
            }
        }
    })();

    // --------------------------------
    // style.Switcher
    // --------------------------------
    // 生成
    MJL.style.Switcher.prototype._create = MJL.style.Switcher.prototype.create;
    MJL.style.Switcher.prototype.create = function() {
        this._create.apply(this, arguments);
        this.set(); // 同時に set を実行するようにしただけ
    };

    // スタイルを title に設定
    MJL.style.Switcher.prototype._set = MJL.style.Switcher.prototype.set;
    MJL.style.Switcher.prototype.set = function(title) {
        this._set.apply(this, arguments);
        // デフォルトスタイルシートの有無を考慮
        if (!title) {
            title = this._getNowStyleTitle();
        }
        var id  = this._title2id(title);
        var aid = isNaN(this._activeId) ? id : this._activeId;
        // Rollover アクティベート対応
        // this._activeId: アクティブなスイッチの ID
        MJL.addClassName(this.targets[id].node, active);
        MJL.event.dispatch(this.targets[id].node, "focus", false);
        if (id !== aid) {
            MJL.removeClassName(this.targets[aid].node, active);
            MJL.event.dispatch(this.targets[aid].node, "blur", false);
        }
        this._activeId = id;
    };

    // スタイルタイトルから id を逆算
    MJL.style.Switcher.prototype._title2id = function(title) {
        var targets = this.targets;
        var ntargets = targets.length;
        for (var t = 0; t < ntargets; t++) { // 線形探索するしかない
            if (title === targets[t].title) {
                return t;
            }
        }
        return 0;
    };

    // 現在アクティブなスタイルのタイトルを取得
    MJL.style.Switcher.prototype._getNowStyleTitle = function() {
        var sheets = document.styleSheets;
        var nsheets = sheets.length;
        for (var s = 0; s < nsheets; s++) {
            if (sheets[s].title && !sheets[s].disabled) {
                return sheets[s].title;
            }
        }
        return "";
    };


    // --------------------------------
    // Rollover
    // --------------------------------
    // 対象要素とイベントリスナのコレクションを生成
    // this.targets の各アイテムに親要素 parent の項目を追加
    MJL.Rollover.prototype._setTargets = function() {
        var parents  = MJL.getElementsByClassName(document, this.enable);
        var nparents = parents.length;
        for (var p = 0; p < nparents; p++) {
            // 取得した要素自身が対象要素の場合もありうる -> 追加
            this._setTargetsSub(parents[p], parents[p]);
            // 取得した要素の子孫要素に対し検索をかける
            for (var n in this._TYPES) {
                var childs = parents[p].getElementsByTagName(n);
                var nchilds = childs.length;
                for (var c = 0; c < nchilds; c++) {
                    this._setTargetsSub(parents[p], childs[c]);
                }
            }
        }
    };

    // 実際に this.targets へ値を設定 (_setTargets 補助)
    MJL.Rollover.prototype._setTargetsSub = function(parent, target) {
        if (this._isTarget(target)) {
            var name = target.nodeName.toLowerCase();
            var getters = this._TYPES[name].getters;
            var item = {
                element : target,
                parent  : parent,
                events  : {}
            };
            for (var v in getters) {
                // call しないと this が違ったままなので注意
                item.events[v] = getters[v].call(this, item);
            }
            this.targets.push(item);
        }
    };

    // 手動アクティブの是非
    // this.targets アイテム仕様に対応
    MJL.Rollover.prototype._isActive = function(target) {
        var element = target.element;
        var parent  = target.parent
        do {
            if (MJL.hasClassName(element, active)) {
                return true;
            }
        } while (
            !MJL.isSameNode(element, parent) && (element = element.parentNode)
        );
        return false;
    };

    // 対象にする要素の種類-条件対応
    // this.targets アイテム仕様に対応
    MJL.Rollover.prototype._TYPES = (function() {
        function getEventGetter(type) {
            return function(target) {
                var off = target.element.getAttribute("src");
                var on  = off.replace(
                    this.options.switchers.on.cond,
                    this.options.switchers.on.replace
                );
                var obj = this;
                var sw  = ("on" === type) ? true : false;
                this._addCache(on);
                return function(event) {
                    target.element.setAttribute(
                        "src",
                        (obj._isActive(target) || sw) ? on : off
                    );
                };
            };
        }
        // イベント種類変換条件
        var event2event = {"focus" : "mouseover", "blur" : "mouseout"};
        function getDescendantEventGetter(type) {
            // this.targets への push が行われる時に実行される
            return function(target) {
                var imgs = target.element.getElementsByTagName("img");
                var nimgs = imgs.length;
                return function(event) {
                    var type = event2event[event.type] || event.type;
                    for (var i = 0; i < nimgs; i++) {
                        // dispatch 方式に変更
                        MJL.event.dispatch(imgs[i], type, false);
                    }
                };
            };
        }
        // 以降はオリジナルから変更なし
        return {
            img : {
                isTarget : function() { return true; },
                getters : {
                    mouseover : getEventGetter("on"),
                    mouseout  : getEventGetter("off")
                }
            },
            input : {
                isTarget : function(elem) {
                    return ("image" === elem.getAttribute("type"));
                },
                getters : {
                    mouseover : getEventGetter("on"),
                    mouseout  : getEventGetter("off"),
                    focus     : getEventGetter("on"),
                    blur      : getEventGetter("off")
                }
            },
            a : {
                isTarget : function(elem) {
                    var imgs = elem.getElementsByTagName("img");
                    return (0 < imgs.length);
                },
                getters : {
                    focus : getDescendantEventGetter("on"),
                    blur  : getDescendantEventGetter("off")
                }
            }
        };
    })();
})(window, document);

