//あいう
/**
 * アプリケーションインデックスファイル
 *
 * @desc 本ファイル読み込み時に require_mode キーでGET値が渡せる @see $a.requireMode
 * @dependency jquery-1.2.6
 * @dependency jquery-ui-1.6b
 * @charset utf-8
 * @newline_character LF
 * @author ishii <ishii[at]s-cubism[dot]jp>
 */

//---------------------------------------------
// グローバルオブジェクト生成
//---------------------------------------------
var $c = ("console" in window && "log" in console)? console.log: function(v){alert(v);};
var $a = (function(){

    // Environments and configs setting.
    var baseDir = "/";
    var jsBaseFilenames = [
        "data.js"
        ,"view.js"
        ,"form.js"
        ,"dialog.js"
    ];
    var jsBoxFilenames = [
        "box.js"
        ,"root_box.js"
        ,"tabbar_box.js"
        ,"main_box.js"
        ,"admin_box.js"
        ,"list_box.js"
        ,"search_box.js"
        ,"tool_box.js"
        ,"news_box.js"
        ,"detail_box.js"
        ,"note_list_box.js"
        ,"note_detail_box.js"
        // For cloud_map_box - Start
        //,"cloudmap/jquery/jquery.mousewheel-mod.js"
        //,"cloudmap/jquery/native-compatible.js"
        //,"cloudmap/base.js"
        ,"cloudmap/__all_min.js"
        ,"cloud_map_box.js"
        // For cloud_map_box - End
    ];
    var cssFilenames = [
        "base.css"
        ,"clmbase.css"
    ];

    // Global object setting.
    var app = {

        KEY_RETURN: 13,

        /** 初期化処理、bodyタグの先頭にて実行 */
        initializeAtFirstBody: function(){
            $a.Data.i();
        },

        /** 初期化処理、bodyタグの最後にて実行 */
        initializeAtLastBody: function(){
        },

        ///** 初期化を行う */
        //initialize: function(){
        //},

        /** ボックスシステムの初期化を行う */
        initializeBoxes: function(){

            // ルートのボックス
            var root = $a.RootBox.i();
            root.je().css({
                overflow: "visible"
            });
            root.appendToHTMLAsRoot("content");

            // タブのバー
            root.appendChild($a.TabbarBox.i(), {
                top: "-30px"
                ,left: "0"
            });

            // 検索タブ
            var main = $a.MainBox.i();
            root.appendChild(main, {
                top: "0"
                ,left: "5px"
            });
            main.appendChild(new $a.ToolBox, {
                top: "0"
                ,left: "0"
            });
            var search = $a.SearchBox.i();
            main.appendChild(search, {
                top: "85px"
                ,left: "0"
            });
            main.appendChild(new $a.ListBox, {
                top: "250px"
                ,left: "0"
            });

            // ノートブック管理タブ
            var admin = $a.AdminBox.i();
            root.appendChild(admin, {
                top: "0"
                ,left: "5px"
            });
            var noteList = $a.NoteListBox.i();
            admin.appendChild(noteList, {
                top: "0"
                ,left: "5px"
            });
            var noteDetail = $a.NoteDetailBox.i();
            admin.appendChild(noteDetail, {
                top: "0"
                ,left: "475px"
            });

            // 企業マップタブ
            var cloudMap = $a.CloudMapBox.i();
            root.appendChild(cloudMap, {
                top: "0"
                ,left: "5px"
            });

            // IE用Hack
            // 理由の詳細は不明だが
            // 1. 親ボックスに所属するjQuery要素が
            // 2. show/hide等のanimateするメソッドを実行していないと
            // 最初にjQuery.UI.Draggableによりドラッグした際に
            // 親ボックスのHTML要素のスタイルが効かなくなってた
            // -> いつの間にか無くても直ってた
            //$('<div/>').appendTo(r.je()).hide("normal").remove();
            //$('<div/>').appendTo(m.je()).hide("normal").remove();

            // Initialize data.
            $a.Data.i().update("selected_tab", "main");
            // 直列的な非同期通信
            $a.Data.i().requestToApi("list", {
                afterSuccess: function(){
                    $a.Data.i().requestToApi("note_list", {
                        afterSuccess: function(){
                            $a.Data.i().requestToApi("note_tag_list");
                        }
                    });
                }
            });
            // 並列的な非同期通信
            // * 前にparallel指定で並列に非同期通信をするとIEで動かないタイミングがあった
            //   今は大丈夫だが、要注意
            $a.Data.i().requestToApi("authentication", {
                parallel: true
            });
            $a.Data.i().requestToApi("prefecture_list", {
                parallel: true
            });
            $a.Data.i().requestToApi("news_list", {
                parallel: true
                ,afterSuccess: function(){
                    if ($a.Data.i().get("news_list.has_important_article") === true) {
                        $a.MainBox.i().appendChild(new $a.NewsBox, {
                            top: "0"
                            ,left: "490px"
                        });
                    };
                }
            });
        },

        /** 外部ファイルを読み込む */
        require: function(){

            this.parseRequireMode();

            $(jsBaseFilenames).each(function(i, e){
                document.write('<script type="text/javascript" src="' + $a.srcDir + e + '" charset="utf-8"></script>');
            });
            if (this.requireMode === "all") {
                $(jsBoxFilenames).each(function(i, e){
                    document.write('<script type="text/javascript" src="' + $a.srcDir + e + '" charset="utf-8"></script>');
                });
            };
            $(cssFilenames).each(function(i, e){
                document.write('<link rel="stylesheet" type="text/css" href="' + $a.cssDir + e + '">');
            });
        },

        /**
         * ファイル読み込み種別
         *
         * "all", "min" がある、詳細はthis.require参照
         */
        requireMode: "all",

        /** URLを解析してGET値のハッシュを返す */
        parseUrlToParameters: function(url){
            var params = {};
            if (/^.+?\?./.test(url)) {
                var pairs = url.replace(/^.+?\?/, '').split('&');
                for (var i = 0; i < pairs.length; i++) {
                    var pair = pairs[i].split('=');
                    params[pair[0]] = ((pair[1] !== undefined)? pair[1]: "");
                };
            };
            return params;
        },

        /** 本ソース呼び出し時のGET値を解析する */
        parseRequireMode: function(){
            var scriptTags = document.getElementsByTagName("script");
            try {
                var src = scriptTags[scriptTags.length - 1].src;
                var params = this.parseUrlToParameters(src);
                if ("require_mode" in params) this.requireMode = params.require_mode;
            } catch (error) {
                this.raiseError("Can't get own script-tag or wrong GET-Parameters.");
            };
        },

        /** エラーによる例外を上げる */
        raiseError: function(message, opts){
            opts = opts || {};
            throw new Error(message);
            //alert(message);
        },

        /** 関数のスコープを束縛する、@see prototype.js */
        bind: function(binded, scope){
            return function() {
                    return binded.apply(scope, arguments);
            };
        },

        /** HTML特殊文字をエスケープする、@see prototype.js */
        escapeHTML: function(str){
            var div = document.createElement('div');
            var text = document.createTextNode(str);
            div.appendChild(text);
            return div.innerHTML;
        },

        /** ある文字数以上の場合は文字を省略して"..."を付記した文字列を返す */
        omitString: function(str, max){
            if (max === undefined) max = 15;
            return str.replace(new RegExp('^(.{' + max + '}).+$'), '$1...');
        },

        /** クラスをSingletonパターンに加工して返す */
        singleton: function(SomeClass){
            var NewClass = function(){
                throw new Error("This is Singleton-Pattern Class. Use self.i().");
            };
            NewClass.__instance__ = null;
            NewClass.i = function(){
                if (this.__instance__ === null)
                    this.__instance__ = applyNew(SomeClass, arguments);
                return this.__instance__;
            };
            function applyNew(cls, args){
                var Tmp = function(){};
                Tmp.prototype = cls.prototype;
                var instance = new Tmp;
                cls.apply(instance, args || []);
                return instance;
            };
            return NewClass;
        },

        /** クラウドマップ用のノートブック追加インターフェース */
        addNoteForClm: function(companyUrl){

            // デモユーザの場合はボタン無効化
            //   authenticationのAPI結果が返ってくるタイミング如何では
            //   認証データが無いこともあるため例外で括っている
            try {
                if ($a.Data.i().checkLoginedByDemoUser() === true) {
                    alert('デモではノートブックへ登録することはできません。');
                    return;
                } else {
                    alert('ノートブックへ登録しました。');
                };
            } catch (err) {
                /* pass */
            };

            $a.Data.i().requestToApi("add_note", {
                data: {url: companyUrl}
                ,parallel: true
                ,afterSuccess: function(){
                    $a.Data.i().requestToApi("list", {
                        afterSuccess: function(){
                            $a.Data.i().requestToApi("note_list");
                        }
                    });
                }
            });
        }
    };

    // Paths setting.
    app.baseDir = baseDir;
    app.welcomeFile = app.baseDir + "welcome/";
    app.apiDir = app.baseDir + "api/";
    app.authenticationApi = app.apiDir + "authentication/";
    app.listApi = app.apiDir + "list/";
    app.detailApi = app.apiDir + "detail/";
    app.newsListApi = app.apiDir + "news_list/";
    app.noteListApi = app.apiDir + "note_list/";
    app.noteDetailApi = app.apiDir + "note_detail/";
    app.addNoteApi = app.apiDir + "add_note/";
    app.noteTagListApi = app.apiDir + "note_tag_list/";
    app.addNoteTagApi = app.apiDir + "add_note_tag/";
    app.deleteNoteTagApi = app.apiDir + "delete_note_tag/";
    app.addMemoApi = app.apiDir + "add_memo/";
    app.deleteMemoApi = app.apiDir + "delete_memo/";
    app.prefectureListApi = app.apiDir + "prefecture_list/";
    app.jsDir = app.baseDir + "media/js/";
    app.cssDir = app.jsDir + "css/";
    app.imgDir = app.jsDir + "img/";
    app.libDir = app.jsDir + "lib/";
    app.srcDir = app.jsDir + "src/";
    app.clmDir = app.srcDir + "cloudmap/";

    // デモユーザ名
    app.demoUsername = "demouser";

    return app;
})();


//---------------------------------------------
// 処理
//---------------------------------------------
(function(){
    $a.require();
})();

