/**
 * FeedBlog Script - version 1.2.0.0
 *
 * @author Kureha Hisame
 * @copyright 2008 Kureha Hisame (http://www.lunardial.com/)
 * @since 2008/10/16
 * @version 1.2.0.0
 */
/**
 * 最新の日記を示すパスへの文字列です。最新の日記を置く場所を変えたいときは変更してください。
 */
var latestXml = "./xml/diary.xml";

/**
 * XMLファイルから読み込んだファイルのバリデートモードを選択します。
 * 0 = 改行コード部分に<br/>を挿入
 * 1 = 改行コード部分に<br/>を挿入しない
 */
var validateMode = "0";


/**
 * Ext jsパネルを実際に生成します。この部分を編集することでデザインを変更可能です。
 * @param {String} title パネルのタイトル部分に表示する文字列
 * @param {String} drawitem パネルの本文を格納したDIV要素のid
 * @param {String} renderto 「タイトル・更新日時・本文」の1日分の日記データを焼き付けるDIV要素のid
 * @param {String} closed (Ext jsパネルオプション)日記をクローズ状態で生成するか否か
 */
function generatePanel(title, drawitem, renderto, closed){

	/**
	 * スタイルを記入してください！
	 * 各ダブルクオーテーション内への記入順序は「1.外枠 / 2.タイトルと本文の合間 / 3.外枠」となります
	 */
/*	 
	var styleTag = "\<div class=\"diary\" \>\<div class=\"title\" \>" + title + "\</div\>" + document.getElementById(drawitem).innerHTML + "\</div\>";
	document.getElementById(renderto).innerHTML = styleTag;
*/

	var styleTag = "\<div class=\"section entry\" \>\<h2\>" + title + "\</h2\>\<div class=\"textBody\" \>" + document.getElementById(drawitem).innerHTML + "\</div\>\<ul class=\"reaction\"\>\</ul\>\</div\>";
	document.getElementById(renderto).innerHTML = styleTag;

}

/**
 * Extへのイベント登録です。すべてのDOMが利用可能になった時点で実行されます。
 */
Ext.onReady(function(){
    // 特定の過去ログの探索モードか否かを判別するためにハッシュを取得する
    var urlhash = "" + location.hash.substring(1);
    
    /*
     * ハッシュの形式チェック
     * RFC3339の形式であればよい。
     * [頭 - 数値] → 数値要素 x 3 → - → 数値要素 x 2 → - → 数値要素 x 2 → T → // 年～日付
     * 数値要素 x 2 → : → 数値要素 x 2 → : → 数値要素 x 2 → [z/+/0～9:文末] // 時～最終要素
     */
    var hashCheck = new RegExp("^[0-9][0-9]{3}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}[\dz+]*");
    
    // ハッシュが空か、ハッシュ形式の正規表現に一致しないようなら通常モードで実行
    if (urlhash.length == 0 || hashCheck.test(urlhash) != true) {
        xmlLoader(latestXml);
        logXMLLoader();
    }
    // ハッシュ形式の正規表現に一致したら探索モード
    else {
        searchMode(urlhash);
        logXMLLoader();
    }
});

/**
 * 呼び出すとDIV:id名:writeArea上のHTMLを削除し、ロードエフェクトを表示します
 */
function loadingEffect(){
    var writeArea = Ext.getDom("writeArea");
    writeArea.innerHTML = '<br/><br/><div id="drawPanel"><div id="drawItem" class="code" style="text-align: center;"><\/div><\/div>';
    
    var drawItem = Ext.getDom("drawItem");
    drawItem.innerHTML = '<br/><img src="./library/ext/resources/images/default/shared/blue-loading.gif"><br/>長時間画面が切り替わらない場合はページをリロードしてください。<br/><br/>';
    
    // ロード表示用のパネルを生成
    generatePanel("Now Loading .....", "drawItem", "drawPanel", false);
    
}

/**
 * ログファイル選択用のコンボボックスをid名:logSelecterに生成します
 */
function logXMLLoader(){
    // XMLファイルのロードロジック生成
    var logXMLData = new Ext.data.Store({
        url: "./xml/loglist.xml",
        reader: new Ext.data.XmlReader({
            record: "file"
        }, [{
            name: "display"
        }, {
            name: "path"
        }])
    });
    
    // XMLを実際にロード
    logXMLData.load();
    
    // コンボボックスを生成
    var comboBox = new Ext.form.ComboBox({
        store: logXMLData,
        applyTo: "logSelecter",
        displayField: "display",
        valueField: "path",
        triggerAction: "all",
        emptyText: "ログを選択してください..."
    });
    
    // コンボボックスのイベント登録
    comboBox.on("change", function(){
        xmlLoader("" + comboBox.getValue());
    });
}

/**
 * 日記のデータが記述されたXMLデータを読み込むロジックを生成します
 * @param {String} fileName 読み込み日記のデータが記述されているXMLファイルのパス
 */
function xmlLoader(fileName){
    // ロードエフェクトに切り替え
    loadingEffect()
    
    var url = fileName;
    
    // 最新の日記かそうでないかで挙動を変更する
    if (fileName == latestXml) {
        var loader = new jQuery.ajax({
            url: url,
            method: "POST",
            success: initWriteHtml,
            error: showError
        });
    }
    else {
        var loader = new jQuery.ajax({
            url: url,
            method: "POST",
            success: writeHtml,
            error: showError
        });
    }
    
}

/**
 * 日記データのエラー時の処理を行います
 */
function showError(){
    var writeArea = Ext.getDom("writeArea");
    writeArea.innerHTML = '<br/><br/><div id="drawPanel"><div id="drawItem" class="code" style="text-align: center;"><\/div><\/div>';
    
    var drawItem = Ext.getDom("drawItem");
    drawItem.innerHTML = '<br/>日記ファイルのロードに失敗しました！<br/><br/>';
    
    // エラー内容をパネルに描画
    generatePanel("Error!", "drawItem", "drawPanel", false);
    
    Ext.Msg.alert("Error!", "日記ファイルが読み込めません！");
}

/**
 * 渡された文字列と一致するfeed1.0:updated要素を持った日記を検索し、表示します
 * @param {String} urlhash feed1.0:updated要素と一致する文字列
 */
function searchMode(urlhash){
    // ロードエフェクト表示
    loadingEffect();
    
    // ログURLの指定
    var url = "./xml/loglist.xml";
    
    // ログXMLファイルを読み込む
    var loader = new jQuery.ajax({
        url: url,
        method: "POST",
        error: showError,
        success: function(xmlData){
            // ファイルパスの要素のみを抽出する
            var separateTag = xmlData.getElementsByTagName("file");
            var filelist = new Array(separateTag.length);
            
            // すべてのファイルパスを配列に格納する
            for (var i = 0; i < separateTag.length; i++) {
                // "path"ノードの値を格納
                filelist[i] = separateTag[i].getElementsByTagName("path")[0].firstChild.nodeValue;
            }
            
            // ファイルパス配列に格納されているすべての日記に対し、探索を開始する
            for (var i = 0; i < separateTag.length; i++) {
            
                // ファイルパス配列の要素からリクエストを生成し、対象データをロードする
                var searchlog = new jQuery.ajax({
                    url: filelist[i],
                    method: "POST",
                    success: function(xmlData){
                        // entry要素のみを切り出す
                        var searchSeparateTag = xmlData.getElementsByTagName("entry");
                        
                        for (var j = 0; j < searchSeparateTag.length; j++) {
                            // entryタグ内部のpublishedノードの値のみ抽出し、入力されたhashと比較を行う
                            var published = searchSeparateTag[j].getElementsByTagName("published")[0];
                            
                            // publishedの値と比較を行う
                            if (urlhash == published.firstChild.nodeValue) {
                                // ハッシュが一致したら対象のデータをXMLからフルロードし、パネルを生成する
                                var title = searchSeparateTag[j].getElementsByTagName("title")[0];
                                var contents = searchSeparateTag[j].getElementsByTagName("content")[0];
                                var date = searchSeparateTag[j].getElementsByTagName("updated")[0];
                                
                                var writeArea = Ext.getDom("writeArea");
                                writeArea.innerHTML = '<br/><br/><div id="drawPanel"><div id="drawItem" class="code"><\/div><\/div>';
                                var drawItem = Ext.getDom("drawItem");
                                drawItem.innerHTML = validateContents(contents.firstChild.nodeValue, published.firstChild.nodeValue);
                                
                                // 探索されたパネルはオープン状態で展開する
                                generatePanel(title.firstChild.nodeValue + " / " + validateData(date.firstChild.nodeValue), "drawItem", "drawPanel", false);
                                
                                break;
                            }
                        }
                    }
                });
            }
            
            // ファイルパス配列から日記が見つからなかった場合の処理
            var writeArea = Ext.getDom("writeArea");
            writeArea.innerHTML = '<br/><br/><div id="drawPanel"><div id="drawItem" class="code"><\/div><\/div>';
            var drawItem = Ext.getDom("drawItem");
            drawItem.innerHTML = "指定された日記は存在しません。";
            
            // エラー内容を表示する
            generatePanel("Search Failed.", "drawItem", "drawPanel", false);
            
        }
    });
}

/**
 * 日記のログファイルデータが記述されているXMLファイルを読み込んで表示します。DIV:id名:writeArea上に読み込んだ日記の内容を表示します
 * @param {Object} xmlData 日記が記述されたXMLファイル(feed 1.0準拠)
 */
function writeHtml(xmlData){
    var separateTag = xmlData.getElementsByTagName("entry");
    var writeArea = Ext.getDom("writeArea");
    var stringBuffer = "";
    
    for (var i = 0; i < separateTag.length; i++) {
        stringBuffer += '<br/><br/><div id="drawPanel' + i + '"><div id="drawItem' + i + '" class="code"><\/div><\/div>';
    }
    
    writeArea.innerHTML = stringBuffer;
    stringBuffer = "";
    
    for (var i = 0; i < separateTag.length; i++) {
        var title = separateTag[i].getElementsByTagName("title")[0];
        var date = separateTag[i].getElementsByTagName("updated")[0];
        var contents = separateTag[i].getElementsByTagName("content")[0];
        var published = separateTag[i].getElementsByTagName("published")[0];
        
        var drawItem = Ext.getDom("drawItem" + i);
        drawItem.innerHTML = validateContents(contents.firstChild.nodeValue, published.firstChild.nodeValue);
        
        // 全てのパネルをクローズ状態で生成する
        generatePanel(title.firstChild.nodeValue + " / " + validateData(date.firstChild.nodeValue), "drawItem" + i, "drawPanel" + i, true);
    }
}

/**
 * 最新の日記のデータが記述されているXMLファイルを読み込んで表示します。DIV:id名:writeArea上に読み込んだ日記の内容を表示します
 * @param {Object} xmlData 日記が記述されたXMLファイル(feed 1.0準拠)
 */
function initWriteHtml(xmlData){
    var separateTag = xmlData.getElementsByTagName("entry");
    var writeArea = Ext.getDom("writeArea");
    var stringBuffer = "";
    
    for (var i = 0; i < separateTag.length; i++) {
        stringBuffer += '<br/><br/><div id="drawPanel' + i + '"><div id="drawItem' + i + '" class="code"><\/div><\/div>';
    }
    
    writeArea.innerHTML = stringBuffer;
    stringBuffer = "";
    
    for (var i = 0; i < separateTag.length; i++) {
        var title = separateTag[i].getElementsByTagName("title")[0];
        var date = separateTag[i].getElementsByTagName("updated")[0];
        var contents = separateTag[i].getElementsByTagName("content")[0];
        var published = separateTag[i].getElementsByTagName("published")[0];
        
        var drawItem = Ext.getDom("drawItem" + i);
        drawItem.innerHTML = validateContents(contents.firstChild.nodeValue, published.firstChild.nodeValue);
        
        // 3つ目までのパネルをオープン状態で生成する
        if (i < 3) {
            generatePanel(title.firstChild.nodeValue + " / " + validateData(date.firstChild.nodeValue), "drawItem" + i, "drawPanel" + i, false);
        }
        else {
            generatePanel(title.firstChild.nodeValue + " / " + validateData(date.firstChild.nodeValue), "drawItem" + i, "drawPanel" + i, true);
        }
    }
}

/**
 * 日付のHTML表示用バリデーション処理を行います
 * @param {String} data RFC3339形式のdate-time文字列
 */
function validateData(data){
    var regT = new RegExp("T", "gm");
    data = data.replace(regT, " ");
    
    // 秒数の小数点以下の部分はカットする
    data = data.substring(0, 19);
    
    return data;
}

/**
 * 日記本文のバリデーション処理を行います
 * @param {String} contents 日記の本文が格納されている文字列
 * @param {String} published 日記の初公開日を示す日付文字列
 */
function validateContents(contents, published){

    // <br/>タグを挿入する
    if (validateMode == 0) {
        var regCR = new RegExp("\n", "gm");
        contents = contents.replace(regCR, "<br />");
    }
    
    // リンク用文末作成
//    var hashTag = '<br/><div style="text-align: right;"><a href="#' + published + '" target="_blank">- この日の記事にリンクする -<\/a><\/span>';
    var hashTag = '<p style="text-align: right;"><a href="#' + published + '" target="_blank">- この日の記事にリンクする -<\/a><\/p>';
	contents = contents + hashTag;
    
    return contents;
}
