/*----- 共通JS事前初期定義 -----------------------------------------------------------------------*/

if (!$defined(this.mugendai.koh)) {

    /*----- パッケージ管理 -----------------------------------------------------------------------*/

    /*
     * パッケージを生成する。
     */
    mugendai.koh = { };

}

/*----- 共通JS初期定義 ---------------------------------------------------------------------------*/

if (!$defined(this.mugendai.koh.blog)) {

    /*----- パッケージ管理 -----------------------------------------------------------------------*/

    /*
     * パッケージを生成する。
     */
    mugendai.koh.blog = { };
    mugendai.koh.blog.widget = { };

    /*----- ウィンドウイベントリスナ定義 ---------------------------------------------------------*/

    /**
     * ウィンドウイベントリスナ。
     * ウィンドウのイベントをハンドリングする。
     */
    mugendai.koh.blog.WindowEventListener = new Class( {

        /**
         * コンストラクタ。
         */
        initialize: function() {

            //イベントハンドラを登録する
            window.addEvents( {
                domready: this.onDOMReady.bindWithEvent(this)
            } );

        },

        /**
         * DOMのロード完了イベントをハンドリングする。
         * @param event イベント
         * @return イベントを伝播するならtrue, しないならfalse
         */
        onDOMReady: function(event) {

            //展開可能イメージリンク要素を定義する
            this.applyExpandableImageLink();

            //外部ターゲット要素を定義する
            this.applyExternalTarget();

            //履歴バックリンク要素を定義する
            this.applyHistoryBackLink();

            //コメントフォーム要素を定義する
            this.applyCommentForm();

            //トラックバックアドレス要素を定義する
            this.applyTrackbackAddress();

            //イベントを伝播する
            return true;

        },

        /**
         * 展開可能イメージリンク要素を定義する。
         */
        applyExpandableImageLink: function() {
            var selector = "a.expandable-image-link";
            $$(selector).each(function(elem, index, elems) {
                new mugendai.koh.blog.ExpandableImageLink(elem);
            } );
        },

        /**
         * 外部ターゲット要素を定義する。
         */
        applyExternalTarget: function() {
            var selector = "";
            selector += "a[href^=http]"
                + ":not([href^=http://www.mugendai.info/koh/blog/])"
                + ":not([href^=http://www.mugendai.info/mt/])";
            selector += ", form[action^=http]"
                + ":not([action^=http://www.mugendai.info/koh/blog/])"
                + ":not([action^=http://www.mugendai.info/mt/])";
            selector += ", "
                + [
                    "bmp", "gif", "jpg", "jpeg", "png"
                ].map(function(ext, index, exts) {
                    return "a[href$=" + ext + "]";
                } ).join(", ");
            $$(selector).each(function(elem, index, elems) {
                new mugendai.koh.blog.ExternalTarget(elem);
            } );
        },

        /**
         * 履歴バックリンク要素を定義する。
         */
        applyHistoryBackLink: function() {
            var selector = "a.history-back-link";
            $$(selector).each(function(elem, index, elems) {
                new mugendai.koh.blog.HistoryBackLink(elem);
            } );
        },

        /**
         * コメントフォーム要素を定義する。
         */
        applyCommentForm: function() {
            var selector = "#comment-form";
            $$(selector).each(function(elem, index, elems) {
                new mugendai.koh.blog.CommentForm(elem);
            } );
        },

        /**
         * トラックバックアドレス要素を定義する。
         */
        applyTrackbackAddress: function() {
            var selector = ".trackback-address";
            $$(selector).each(function(elem, index, elems) {
                new mugendai.koh.blog.TrackbackAddress(elem);
            } );
        }

    } );

    /*----- 展開可能イメージリンク定義 -----------------------------------------------------------*/

    /**
     * 展開可能イメージリンク。
     * アンカー要素の指すイメージを展開する。
     * ※ATOM/RSSにて、MTテンプレートによって同様の処理を行っている。
     * 　展開内容が変更となる場合は、こちらも合わせて変更すること。
     */
    mugendai.koh.blog.ExpandableImageLink = new Class( {

        /**
         * アンカー要素。
         */
        elem: null,

        /**
         * コンストラクタ。
         * @param elem 適用対象要素
         */
        initialize: function(elem) {

            //適用対象要素が妥当であるか確認する
            if (!$chk(elem) || elem.get("tag") != "a") {
                throw new Error("適用対象の要素が不正です。");
            }

            //インスタンスを初期化する
            //  アンカー要素
            this.elem = elem;

            //アンカー要素の指すイメージを展開する
            this.expandImage();

        },

        /**
         * アンカー要素の指すイメージを展開する。
         */
        expandImage: function() {

            //イメージ要素を構築する
            var imgElem = new Element("img", {
                src: this.elem.get("href"),
                alt: this.elem.get("text"),
                title: this.elem.get("text")
            } )

            //イメージ要素を配置する
            this.elem.empty().grab(imgElem);

        }

    } );

    /*----- 外部ターゲット定義 -------------------------------------------------------------------*/

    /**
     * 外部ターゲット。
     * アンカー要素/フォーム要素を外部ターゲットとして取り扱う。
     */
    mugendai.koh.blog.ExternalTarget = new Class( {

        /**
         * アンカー要素。
         */
        elem: null,

        /**
         * コンストラクタ。
         * @param elem 適用対象要素
         */
        initialize: function(elem) {

            //適用対象要素が妥当であるか確認する
            if (!$chk(elem) || (elem.get("tag") != "a" && elem.get("tag") != "form")) {
                throw new Error("適用対象の要素が不正です。");
            }

            //インスタンスを初期化する
            //  アンカー要素
            this.elem = elem;

            //外部ウィンドウとして開くようターゲット属性を書き換える
            this.elem.set("target", "_blank");

        }

    } );

    /*----- 履歴バックリンク定義 -----------------------------------------------------------------*/

    /**
     * 履歴バックリンク。
     * アンカー要素を履歴バックリンクとして取り扱う。
     */
    mugendai.koh.blog.HistoryBackLink = new Class( {

        /**
         * アンカー要素。
         */
        elem: null,

        /**
         * コンストラクタ。
         * @param elem 適用対象要素
         */
        initialize: function(elem) {

            //適用対象要素が妥当であるか確認する
            if (!$chk(elem) || elem.get("tag") != "a") {
                throw new Error("適用対象の要素が不正です。");
            }

            //インスタンスを初期化する
            //  アンカー要素
            this.elem = elem;

            //イベントハンドラを登録する
            this.elem.addEvents( {
                click: this.onClick.bindWithEvent(this)
            } );

        },

        /**
         * クリックイベントをハンドリングする。
         * @param event イベント
         * @return イベントを伝播するならtrue, しないならfalse
         */
        onClick: function(event) {
            history.back();
            return false;
        }

    } );

    /*----- コメントフォーム定義 -----------------------------------------------------------------*/

    /**
     * コメントフォーム。
     * コメントフォーム要素を取り扱う。
     */
    mugendai.koh.blog.CommentForm = new Class( {

        /**
         * 個人情報の保存先となるCookieの名前。
         */
        personalInfoCookieName: "commentFormPersonalInfo1",

        /**
         * 個人情報の保存先となるCookieのアクセスオプション。
         */
        personalInfoCookieOptions: {
            duration: 30,   //有効期限[日]
            path: "/"       //所属パス
        },

        /**
         * コメントフォーム要素。
         */
        elem: null,

        /**
         * コンストラクタ。
         * @param elem 適用対象要素
         */
        initialize: function(elem) {

            //適用対象要素が妥当であるか確認する
            if (!$chk(elem) || elem.get("tag") != "form") {
                throw new Error("適用対象の要素が不正です。");
            }

            //インスタンスを初期化する
            //  コメントフォーム要素
            this.elem = elem;

            //保存チェックボックス要素を構築/配置する
            this.newRememberPersonalInfoElem();

            //イベントハンドラを登録する
            this.elem.addEvents( {
                submit: this.onSubmit.bindWithEvent(this)
            } );
            this.getRememberPersonalInfoElem().addEvents( {
                click: this.onClickRememberPersonalInfoElem.bindWithEvent(this)
            } );

            //個人情報の入力値をCookieから読込む
            this.loadPersonalInfo();

        },

        /**
         * 個人情報要素の配列を取得する。
         * @return 個人情報要素の配列
         */
        getPersonalInfoElems: function() {
            var selector = "#comment-form-author, #comment-form-home, #comment-form-mail";
            return this.elem.getElements(selector);
        },

        /**
         * 末尾の個人情報コンテナ要素を取得する。
         * @return 末尾の個人情報コンテナ要素
         */
        getLastPersonalInfoContainerElem: function() {
            var selector = "#comment-form-mail";
            return this.elem.getElement(selector).getParent();
        },

        /**
         * 個人情報保存チェックボックス要素を取得する。
         * @return 個人情報保存チェックボックス要素
         */
        getRememberPersonalInfoElem: function() {
            var selector = "#comment-form-remember-personal-info";
            return this.elem.getElement(selector);
        },

        /**
         * 個人情報保存チェックボックス要素を構築/配置する。
         * @return 保存チェックボックスのコンテナ要素
         */
        newRememberPersonalInfoElem: function() {

            //保存チェックボックス要素を構築/配置する
            return this.getLastPersonalInfoContainerElem().grab(
                new Element("dd").addClass("field-value").grab(
                    new Element("input", {
                        id: "comment-form-remember-personal-info",
                        name: "comment-form-remember-personal-info",
                        type: "checkbox",
                        value: "1"
                    } ).addClass("checkbox")
                ).appendText("\n").grab(
                    new Element("label", {
                        text: "なまえ,サイトURL,メールを保存する",
                        title: "チェックするとCookieに保存されます。\n"
                            + "チェックを外すと保存内容は削除されます。"
                    } ).set("for", "comment-form-remember-personal-info")
                ), "after"
            );

        },

        /**
         * 個人情報の入力値をCookieに保存する。
         * @return 成功したらtrue, 失敗したらfalse
         */
        savePersonalInfo: function() {

            //個人情報の入力値を連想配列に格納する
            var info = { };
            this.getPersonalInfoElems().each(function(elem, index, elems) {
                this[elem.get("name")] = elem.get("value");
            }, info);

            //JSONエンコードしCookieに保存する
            info = JSON.encode(info);
            Cookie.write(this.personalInfoCookieName, info, this.personalInfoCookieOptions);

            return true;

        },

        /**
         * 個人情報の入力値をCookieから読込む。
         * @return 成功したらtrue, 失敗したらfalse
         */
        loadPersonalInfo: function() {

            //Cookieを読込みJSONデコードする
            //Cookieに保存されていない場合は失敗を返却する
            var info = Cookie.read(this.personalInfoCookieName);
            if (!$chk(info)) {
                return false;
            }
            info = JSON.decode(info, true);

            //個人情報の入力値に反映する
            this.getPersonalInfoElems().each(function(elem, index, elems) {
                elem.set("value", this[elem.get("name")]);
            }, info);
            this.getRememberPersonalInfoElem().set("checked", true);

            return true;

        },

        /**
         * 個人情報の入力値をCookieから削除する。
         * @return 成功したらtrue, 失敗したらfalse
         */
        clearPersonalInfo: function() {

            //Cookieから保存内容を削除する
            Cookie.dispose(this.personalInfoCookieName, this.personalInfoCookieOptions);

            return true;

        },

        /**
         * ユーザの指定状態により個人情報を保存/削除する。
         * @return 成功したらtrue, 失敗したらfalse
         */
        applyRememberPersonalInfo: function() {

            //個人情報保存チェックボックスにより処理を分岐する
            if (this.getRememberPersonalInfoElem().get("checked")) {
                //個人情報を保存する
                return this.savePersonalInfo();
            } else {
                //個人情報をクリアする
                return this.clearPersonalInfo();
            }

        },

        /**
         * サブミットイベントをハンドリングする。
         * @param event イベント
         * @return イベントを伝播するならtrue, しないならfalse
         */
        onSubmit: function(event) {

            //個人情報を保存/削除する
            this.applyRememberPersonalInfo();

            return true;

        },

        /**
         * 個人情報保存チェックボックス要素のクリックイベントをハンドリングする。
         * @param event イベント
         * @return イベントを伝播するならtrue, しないならfalse
         */
        onClickRememberPersonalInfoElem: function(event) {

            //個人情報を保存/削除する
            this.applyRememberPersonalInfo();

            return true;

        }

    } );

    /*----- トラックバックアドレス定義 -----------------------------------------------------------*/

    /**
     * トラックバックアドレス。
     * トラックバックアドレス要素を取り扱う。
     */
    mugendai.koh.blog.TrackbackAddress = new Class( {

        /**
         * トラックバックアドレス要素。
         */
        elem: null,

        /**
         * コンストラクタ。
         * @param elem 適用対象要素
         */
        initialize: function(elem) {

            //適用対象要素が妥当であるか確認する
            if (!$chk(elem)) {
                throw new Error("適用対象の要素が不正です。");
            }

            //インスタンスを初期化する
            //  トラックバックアドレス要素
            this.elem = elem;

            //トラックバックURLコピーアンカー要素を構築/配置する
            this.newCopyURLAnchorElem();

        },

        /**
         * トラックバックURL要素を取得する。
         * @return トラックバックURL要素
         */
        getURLElem: function() {
            var selector = ".trackback-address-url";
            return this.elem.getElement(selector);
        },

        /**
         * トラックバックURLコピーアンカー要素を構築/配置する。
         * @return 成功したらトラックバックURLコピーアンカー要素, 失敗したらnull
         */
        newCopyURLAnchorElem: function() {

            //構築不可な場合は失敗とする
            if (!this.newableCopyURLAnchorElem()) {
                return null;
            }

            //アンカー要素を構築/配置する
            return this.elem.grab(
                new Element("a", {
                    href: this.getURLElem().get("text"),
                    title: "URLをコピーする",
                    events: {
                        click: this.onClickCopyURLAnchorElem.bindWithEvent(this)
                    }
                } ).grab(
                    new Element("img", {
                        src: "http://www.mugendai.info/mt/plugins/KohBlogTemplateSet/lib/famfamfam_silk_icons/page_white_get.gif",
                        alt: "コピー",
                        width: "16",
                        height: "16"
                    } ).addClass("icon")
                )
            );

        },

        /**
         * トラックバックURLコピーアンカー要素が構築可能か判定する。
         * @return 構築可能ならtrue, 構築不可ならfalse
         */
        newableCopyURLAnchorElem: function() {
            //クリップボードにアクセス可能なら構築可能とする
            return $chk(clipboardData) && $chk(clipboardData.setData);
        },

        /**
         * トラックバックURLコピーアンカー要素で発生したクリックイベントをハンドリングする。
         * @param event イベント
         * @return イベントを伝播するならtrue, しないならfalse
         */
        onClickCopyURLAnchorElem: function(event) {
            if (clipboardData.setData("text", this.getURLElem().get("text"))) {
                alert("URLをコピーしました。");
            } else {
                alert("URLをコピーできませんでした。\n"
                    + "セキュリティ設定でクリップボードへのアクセスが"
                    + "許可されていない可能性があります。");
            }
            return false;
        }

    } );

    /*----- JSレンダラ定義 -----------------------------------------------------------------------*/

    /**
     * Blog製作者メールリンクレンダラ。
     * Blog製作者メールリンクをレンダリングするレンダラクラス。
     */
    mugendai.koh.blog.BlogAuthorMailLinkJSRenderer = new Class( {

        Extends: mugendai.jsrendering.HTMLJSRenderer,

        /**
         * コンストラクタ。
         * @param params レンダリングパラメータ
         *      email: メールアドレス
         */
        initialize: function(params) {

            //インスタンスを初期化する
            //  基底クラス
            this.parent(params);

        },

        /**
         * レンダリングパラメータを調整する。
         */
        adjustParams: function() {

            //基底の処理を行う
            this.parent();

            //レンダリングパラメータをチェックする
            //  メールアドレス
            if (!$chk(this.params.email)) {
                throw new Error("メールアドレスが指定されていません。");
            }

            //HTMLコンテンツをセットする
            this.params.contents =
                " &lt;"
                + "<a href=\"mailto:" + this.params.email + "\">"
                + this.params.email + "</a>"
                + "&gt;";

        }

    } );

    /**
     * コメント投稿者メールリンクレンダラ。
     * コメント投稿者メールリンクをレンダリングするレンダラクラス。
     */
    mugendai.koh.blog.CommentAuthorMailLinkJSRenderer = new Class( {

        Extends: mugendai.jsrendering.HTMLJSRenderer,

        /**
         * コンストラクタ。
         * @param params レンダリングパラメータ
         *      email: メールアドレス
         */
        initialize: function(params) {

            //インスタンスを初期化する
            //  基底クラス
            this.parent(params);

        },

        /**
         * レンダリングパラメータを調整する。
         */
        adjustParams: function() {

            //基底の処理を行う
            this.parent();

            //レンダリングパラメータをチェックする
            //  メールアドレス
            if (!$chk(this.params.email)) {
                throw new Error("メールアドレスが指定されていません。");
            }

            //HTMLコンテンツをセットする
            this.params.contents =
                "<a href=\"mailto:" + this.params.email + "\">"
                + "<img src=\"http://www.mugendai.info/mt/plugins/KohBlogTemplateSet/lib/famfamfam_silk_icons/email_go.gif\""
                + " alt=\"Mail\" title=\"" + this.params.email + "\""
                + " width=\"16\" height=\"16\" class=\"icon\" />"
                + "</a>";

        }

    } );

    /*----- 初期処理 -----------------------------------------------------------------------------*/

    /*
     * シンプルCSSをフルCSSに置き換える。
     */
    
    document.write("\n        \<link id=\"full-css-link\" rel=\"StyleSheet\"\n            href=\"http://www.mugendai.info/koh/blog/full.css\" type=\"text/css\" /\>\n    ");
    $("simple-css-link").destroy();

    /*
     * ウィンドウイベントリスナをSingletonとして生成する。
     */
    mugendai.koh.blog.WindowEventListener = new mugendai.koh.blog.WindowEventListener();

    /*
     * レンダラクラスを登録する。
     */
    mugendai.jsrendering.JSRendering.rendererClasses["blog-author-mail-link"]
        = mugendai.koh.blog.BlogAuthorMailLinkJSRenderer;
    mugendai.jsrendering.JSRendering.rendererClasses["comment-author-mail-link"]
        = mugendai.koh.blog.CommentAuthorMailLinkJSRenderer;

}