/** 
 * @copyright      MOGRA DESIGN .Ltd,
 * @auther         作者名
 * @link           http://www.mogra.co.jp/
 * @version        0.7.8
 * @lastupdate     2010/09/09
 */

/**
 * テンプレートクラス
 * 静的クラス
 */

var  KcTemplate = {
	kc_nm_patternDate : /(\d{2,4}).+?(\d{1,2}).+?(\d{1,2}).+?(\d{1,2}).+?(\d{1,2})/,
	
	kc_error : '<li>サーバメンテナンスのため、このコンテンツは閲覧できません。<br />お手数ですが、しばらく経ってから再度アクセスしてください。</li>',
	
	kc_pulldown_addHTML_more : '<a onclick="kc.pulldownRun();" href="javascript:void(0)">もっと見る</a>',
	kc_pulldown_addHTML_top : '<a href="#TOP">トップへ</a>',// アラート機能：アラートのHTML
	
	// アラート機能：アラートのHTML
	kc_alert_html : '',
  
	kc_tag_title_all : "",
	kc_tag_title_word : $.createTemplate('<em>{$T.word}</em>を含むブログ記事一覧'),
	// use template
	kc_tag_tmpl : $.createTemplate('<li class="level{$T.level}" id="kc_tc_tag_{$P.id}"><a href="javascript:void(0)" onclick="kc.selectTag(\'{$T.name}\', 1);">{$T.value}<span class="num">({$T.num})</span></a> </li>'),
	
	kc_notag_html : '<a href="javascript:kc.selectTag(\'\');focus();" id="tag-toggle-btn"><img src="/bravia/kuchikomi/images/btn_tagout.gif" alt="絞り込みを解除する" class="fadeImg" /></a>',
	
	kc_entry_tmpl : $.createTemplate('<li{$P.enclass}><p class="kc-date">{$T[2]}</p><h4><a href="{$T[1]}" target="_blank" onclick="clickCount(\'{$T[1]}\', {$P.suffix})">{$T[0]}</a></h4><p id="kc_entry_body_{$P.uid}" class="body"><a href="{$T[1]}" target="_blank" onclick="clickCount(\'{$T[1]}\', {$P.suffix})">{$T[3]}</a></p></li>'),
	
	kc_entry_date_tmpl : $.createTemplate('{$T[1]}年{$T[2]}月{$T[3]}日 {$T[4]}：{$T[5]}'),
	
	kc_page_tmpl : $.createTemplate('<a href="javascript:void(0)" onclick="kc.chagePage({$T.num})">{$T.name}</a>'),
	
	kc_page_prev_tmpl : $.createTemplate('<a href="javascript:void(0)" class="back-link" onclick="kc.chagePage({$T.num})">＜＜</a>'),
	kc_page_next_tmpl : $.createTemplate('<a href="javascript:void(0)" class="next-link" onclick="kc.chagePage({$T.num})">＞＞</a>'),

	kc_page_sepa_tmpl : "",
	
	kc_rank_tmpl : $.createTemplate('<li class="rank{$T.num}"><a href="{$T.url}" target="_blank">{$T.title}</a>')
    
};

//通常使うコントローラー変数
var kc;
/**
 * 各クチコミクリップ用コントローラークラス
 */
var callbackJSON;

var KcPublish = function (obj){
	this.today = new Date();
	this.current_page = 0;
	this.model;
	this.tmpl = {};
	this.init_obj=obj;
	//初期設定
	this.tag_area = 'kc-tag';
	this.tag_title_area = 'kc-title';
	this.tag_notag_area = 'kc-notag';
	this.entry_area = 'kc-list';
	this.page_area = 'kc-page';
	this.ranking_area = "kc-rank";
	this.btn_more = 'kc-btn-more';
	this.btn_showall = 'kc-btn-showall';
	this.kc_word = "";
  
	this.model_new_range = 2*24*60*60*1000;
	
    
	this.init = function(){
		
		if(!Boolean(this.init_obj.model)){
			this.init_obj.model = new KcModel();
		};
		
		for(var o in KcTemplate){
			this.tmpl[o] = KcTemplate[o];
		};
		
		for(var t in this.init_obj.tmpls){
			this.tmpl[t] = this.init_obj.tmpls[t];
		};
	  
	  
		for(var key in this.init_obj){
			
		  if(this.init_obj[key] != null){
		  	this[key] = this.init_obj[key];
		  }
		    
		};
		
		
		if(Boolean(this.model.kc_nm_targetDays)){
			this.model_new_range = this.model.kc_nm_targetDays*24*60*60*1000;
		};
	};
    
	this.setKC = function(){
		this.current_page = 0;
		
		if(Boolean(this.init_obj.json)){
			var o = this;
			
			callbackJSON = function(mjson){
				var entry_list = mjson;
				
				for(var key in entry_list){
					if(key == "entries"){
						o.model.kc_entries = o.model.enticeSameEntry(o.model.kc_entries, entry_list.entries);
					}else{
						o.model["kc_" + key] = entry_list[key];
					};
				};
				o.creationComplete(o);
			};
			
			errorJSON = function(e){
				$("#"+o.tag_area).html(o.tmpl.kc_error);
				$("#"+o.tag_title_area).hide();
				$("#"+o.entry_area).hide();
				$("#"+o.page_area).html("&nbsp;");
				$("#"+o.ranking_area).hide();
				$("#"+o.model_btn_more).hide();
			};
			
			this.model.getJsonData(this.init_obj.json, callbackJSON, errorJSON);
			
			
		}else{
			this.creationComplete(this);
		};
		
		this.onComplete();
	};
	
	//初期画面のセット
	this.creationComplete = function(o){	
		o.model.sortEntriesByTag("");
		
		for(var key in o.init_obj){
     	
			switch(key){
			case "tag_area" :
				//タグクラウド
				$("#"+o.tag_area).html(o.createTagCloud(0));
				$("#"+o.tag_notag_area).html(this.tmpl.kc_notag_html);
				break;
				
			case "entry_area" :
				//エントリー
				$("#"+o.entry_area).html(o.createEntries());
				if(o.model.kc_entries.length > o.model.kc_pulldown_entry_num_start){
					$("#"+o.btn_more).html(o.tmpl.kc_pulldown_addHTML_more);
				}
				break;
			
			case "tag_title_area" :
				$("#"+o.tag_title_area).show();
			case "page_area" :
				//ページネート
				$("#"+o.page_area).html(o.createPages());
				break;
				
			case "ranking_area" :
				//ページネート
				$("#"+o.ranking_area).html(o.createRanking());
				break;
				
			case "btn_more" :
				//もっと見る
				//$("#"+o.btn_more).html(o.tmpl.kc_pulldown_addHTML_more);
				break;
      default :
                
			}
		
		}
		
		
		if(this.query.get("key")){			
			var key = decodeURIComponent(this.query.get("key"));
			o.selectTag(key);
		};
		
		if(this.query.get("p")){
			o.chagePage(this.query.get("p"));
		};
		
	}
	
	//タグクラウドの生成
	this.createTagCloud = function(escape){
		
		//タグクラウドの取得
		tags = this.model.kc_tags = this.model.findTags();
		//
		var list = "";
		for(var i = 0; i < tags.length; i++){
			var obj = {};
			for(var val in tags[i]){
				obj[val] = tags[i][val];
			};
			
			if(escape){
				obj.name = (encodeURIComponent(obj.name));
			};
			var cls = this.customTagClass(obj).concat(new Array("level"+obj.level));
			
			obj.cls = cls.join(" ");
			
			list += this.tmpl.kc_tag_tmpl.get(obj, {id : i+1, suffix:this.today.getTime()}, window);
		};
		return list;
	};

	/**
	 * タグの選択
     * param int タグの番号[1-n]
     * param string タグのキー名
     * param bool URLエンコード
	 */
	this.selectTag = function(tag_name, escape){
		this.current_page = 0;
		
		this.kc_word = escape ? decodeURIComponent(tag_name) : tag_name;
		
		this.model.sortEntriesByTag(this.kc_word);
		
		var word = "";
		//タグの色かえ
		for(var i = 0; i < this.model.kc_tags.length; i++){
			
			var elm = $('#kc_tc_tag_'+(i+1)+" a:first-child");
			
			//選択されたのをactiveに。それ以外はnormalに
			elm.removeClass('kc-active');
			
			if(tag_name != ""){
				if(this.model.kc_tags[i].name == this.kc_word){
					word = this.model.kc_tc_names[this.kc_word];
					elm.addClass('kc-active');
				};
			
			};
		};
		
				
		//最後に設定
		var tag_title = $('#'+this.tag_title_area);
		if(this.kc_word == "" || !Boolean(this.kc_word)){
			tag_title.html(this.tmpl.kc_tag_title_all);
		}else if(word != ""){
			tag_title.html(this.tmpl.kc_tag_title_word.get({word:word}, null, window));
		};
		
		this.updateEntries();
        
	}
	
	/**
	 * エントリーの生成
	 * @param array
	 * @param int
	 * @return string(html)
	 */
	this.createEntries = function(){
		
		
		var arr = this.model.findEntries(this.current_page);
		
		var entry_list_html = "";
		
		for(var i=0; i < arr.length; i++){
			if(Boolean(arr[i])){
				var entryDat = this.attachEntryTmpl(arr[i], i)
				entry_list_html += this.tmpl.kc_entry_tmpl.get(entryDat[0], entryDat[1], window);
			};
		};
		
		return entry_list_html;
	};
	
	/**
	 * エントリーの更新
	 */
	this.updateEntries = function(){
		
		$("#"+this.entry_area).html(this.createEntries());
		
		
		if(Boolean(this.init_obj.page_area)){
			$("#"+this.page_area).html(this.createPages());
			
		}else if(this.model.entries.length > this.model.kc_pulldown_entry_num_start){
			$("#"+this.btn_more).html(this.tmpl.kc_pulldown_addHTML_more);
			
		}else{
			
			$("#"+this.btn_more).html('');
		};
		
		KcFunction.cleanEm();
	};
	
	/**
	 * エントリーの生成
	 * @param array
	 * @param int
	 * @return string(html)
	 */
	this.attachEntryTmpl = function (entry, id){
		// 投稿日時のフォーマット
		var my_entry = entry.concat();
		var m = my_entry[2].match(/(\d+)-0?(\d+)-0?(\d+)T(\d+):(\d+):(\d+)/) || my_entry[2].match(/(\d+)-0?(\d+)-0?(\d+) (\d+):(\d+):(\d+)/);
		
		my_entry[2] = this.tmpl.kc_entry_date_tmpl.get(m, null, window);

		// 検索語の強調
		if(this.kc_word != ""){
			if(Boolean(this.model.model_name == "KcWhiteModel")){
				var word_arr = this.model.kc_tc_tags[this.kc_word];
				
				for(var i=0; i < word_arr.length; i++){
					var kc_word_c = word_arr[i];
					
					my_entry[0] = my_entry[0].replace(eval('/('+kc_word_c+')/gi'),'<em>$1</em>');
					my_entry[3] = my_entry[3].replace(eval('/('+kc_word_c+')/gi'),'<em>$1</em>');
				};
			}else{
				my_entry[0] = my_entry[0].replace(eval('/('+this.kc_word+')/gi'),'<em>$1</em>');
				my_entry[3] = my_entry[3].replace(eval('/('+this.kc_word+')/gi'),'<em>$1</em>');
			};
		};
		
		// ニュースマーカーの作成
		var is_new = "";
		
		var m = my_entry[2].match(this.tmpl.kc_nm_patternDate);
		var class_arr = [];
		if(m){
			var day = new Date(m[1],m[2]-1,m[3],m[4],m[5],0).getTime();
			var kc_nm_today = this.today.getTime();
			
			if((kc_nm_today - day) < this.tmpl.kc_new_range){
				class_arr.push("new");
			};
		};
        
		class_arr = class_arr.concat(this.customEntryClass(my_entry));
		var entry_class;
		if(class_arr.length){
			entry_class = ' class="' + class_arr.join(" ") + '"';
		};
		//
		// エントリーのHTML
		return [my_entry, {uid:id, suffix:this.today.getTime(), enclass:entry_class}];
	};
	
	/**
	 * タグを強調
	 * @param string
	 */
	this.emphasisTag = function(str){
		return str.replace(eval('/(' + this.tag + ')/gi'),'<em>$1</em>');
	};
	
	//ページネート関係
	this.model_pagenate = 1;
	this.model_page_start_num = 1;
	this.model_page_max_num = 10;
		
	this.createPages = function(){
		var e = this.model.entries;
		var c = this.current_page + 1;
		//全体のページ数
		var pages = Math.ceil(e.length / this.model.kc_pulldown_entry_num);
		
		//最大ページ表示
		var start_page = Math.ceil(c / this.model_page_max_num)*this.model_page_max_num - (this.model_page_max_num-1);
		var last_page = start_page + (this.model_page_max_num-1) > pages ? pages : start_page + (this.model_page_max_num-1);
		
		var html = '';
		var i;
		
		//前の移動
		if(start_page > this.model_page_max_num){
			html += this.tmpl.kc_page_prev_tmpl.get({num:start_page-1, name:"&lt;&lt;"}, null, window);
		};
		
		//リスト
		for(i=start_page; i<last_page; i++){
			if(i == c){
				html += '<span class="kc-active">'+i+'</span>';
			}else{
				html += this.tmpl.kc_page_tmpl.get({num:i, name:i}, null, window);
			};
			if(i != last_page){
				html += this.tmpl.kc_page_sepa_tmpl;
			};
		};
		
		//後ろの移動
		if(i < pages){
			html += this.tmpl.kc_page_next_tmpl.get({num:start_page+this.model_page_max_num, name:"&gt;&gt;"}, null, window);
		};
		
		return html;
	};
	
    /**
     * ページの変更
     * param int ページ番号[1-n]
     */
	this.chagePage = function(n){
		
		this.current_page = n - 1;
		
		this.updateEntries();
		
	};
	
	/**
	 * ランキングの生成
	 */
	this.createRanking = function(){
		var ranks = this.model.findRankEntries(10);
		var html = "";
		for(var i = 0; i < ranks.length; i++){
			
			html += this.tmpl.kc_rank_tmpl.get({num:(i+1), title:ranks[i][0], url:ranks[i][1]}, null, window);
		};
		//alert(html)
		return html;
	};
	
	/**
	 * もっとみる
	 */

	this.pulldownRun = function(){
		this.current_page ++;
		
		var html = $("#"+this.entry_area).html() + this.createEntries();
		$("#"+this.entry_area).html(html);
		
		var len = (this.model.kc_pulldown_entry_num * this.current_page) + this.model.kc_pulldown_entry_num_start;
		
		if(len >= this.model.entries.length){
			$("#"+this.btn_more).html(this.tmpl.kc_pulldown_addHTML_top);
		};
	};

	/**
	 * ボタンの表示非表示
	 * @param string
	 * @param bool
	 */
	this.toggleBtn = function(id, bool){
		var elm = document.getElementById(id);
		if(bool && Boolean(elm)){
			elm.style.visibility = "visible";
		}else if(!bool && Boolean(elm)){
			elm.style.visibility = "hidden";
		};
	};
	/**
	 *  プルダウントリガーの表示／非表示
	 */
	this.selectBtn = function(){
		var more=document.getElementById(this.kc_btn_more);
		
			
			if(this.kc_entries.length > 0){
				kc_pulldown_more_isabled=true;
				more.innerHTML = this.kc_pulldown_addHTML_more;
				kc_pulldown_no=0;
				KcPublish.toggleBtn(this.model_btn_more, true);
			} else	{
				kc_pulldown_more_isabled=false;
				more.innerHTML = this.kc_pulldown_addHTML_top;
				KcPublish.toggleBtn(this.model_btn_more, false);
			};
		
	};
	
	//
  this.customTagClass = function(){
      //do something
      return new Array();
  };
  this.customEntryClass = function(){
      //do something
      return new Array();
  };
	
	this.whiteList = function(list){
		this.model.white_list = list; 	
	};
	
	this.blackList = function(list){
		this.model.black_list = list; 	
	};
	
	this.onComplete = function(){
		//do something
	}
	
	//クエリ関係
	this.query = {
    get:function(str){
        var s = location.search.substring(1);
        var obj = new Object();
        var arr = s.split('&');
        for(var i=0; i < arr.length; i++){
            var par = arr[i].split('=');
            obj[par[0]] = par[1];
        }
        
        if(Boolean(obj[str])){
            return obj[str];
        }else{
            return null;
        }
    }
	}
  
	this.init();
};


/**
 * 各クチコミクリップ用モデルクラス
 */
var KcModel = function(obj) {
	
	this.error = "";
	
	this.kc_tags;
	this.kc_name;
	this.kc_words;
	this.kc_ga;
	this.kc_alert;
	this.kc_nm;
	this.kc_nm_targetDays;
	this.kc_pulldown;
	this.kc_pulldown_entry_num;
	this.kc_pulldown_entry_num_start;
	this.kc_tc_power;
	this.kc_tc_tag_chars;
	this.kc_tc_tag_num;
	this.kc_tc_min_num;
	this.kc_tc_max_num;
	this.kc_tc_names;
	this.kc_tc_nums;
	this.kc_entries;
	
	this.tag = "";
	this.entries;
	
	this.white_list;
	this.black_list;
	
	this.isRandom = false;
	
	//ここからinit
	this.init = function(){
		
		var window_var = ['kc_name','kc_words','kc_ga','kc_alert','kc_nm','kc_nm_targetDays','kc_pulldown','kc_pulldown_entry_num','kc_pulldown_entry_num_start','kc_tc_power','kc_tc_tag_chars','kc_tc_tag_num','kc_tc_min_num','kc_tc_max_num','kc_tc_names','kc_tc_nums','kc_entries'];
		//展開
		//eval(str);
		
		//kc_のついたグローバル変数をこちらにうつす
		for(var i=0; i < window_var.length; i++){
			if(Boolean(window[window_var[i]])){
				if(!Boolean(this[window_var[i]])){
					this[window_var[i]] = window[window_var[i]];
				};
				//window[window_var[i]] = null;
			};
		};
		
		//追加のオブジェ
		if(Boolean(obj)){
			for(var o in obj){
				this[o] = obj[o];
			};
		}
		
		//ちゃんと読み込めたかどうか
		if(!Boolean(this.kc_name) || !Boolean(this.kc_words) || !Boolean(this.kc_entries)) {
			// 不具合発生時のHTML
			this.error = this.getError("INIT");
			
		};
		
	};//this.init
	
	this.getError = function(n) {
		switch(n){
		case "INIT":
			return 'サーバメンテナンスのため、このコンテンツは閲覧できません。<br />お手数ですが、しばらく経ってから再度アクセスしてください。';
		case 'TAG':
			return '表示できるタグがありません。';
			break;
		};
		
	};//this.getError
	
	
	
	/**
	 * Ajaxで詳細情報
	 * @param array
	 * @param function
	 */
	this.getJsonData = function(json_url, callback_func, error_func){
    var kc = this;
		$.ajax({
						url: json_url,
						type: "GET",
						dataType: "jsonp",
						scriptCharset: "utf-8",
						callback: "callbackJSON",
						success: callback_func,
						error : error_func
					});
		
		
	};
	
	
	//タグクラウドの解析
	this.findTags = function(){
		
		// タグ数の再取得
		this.kc_tc_nums = new Array();
		
		for(var i=0; i < this.kc_entries.length; i++){
		
			var entry_title = this.kc_entries[i][0];
			var entry_body = this.kc_entries[i][3];
			//タグが含まれているかどうか、小文字にして確認
			for(var tag_name in this.kc_tc_names){
				
				var c=0;
				var p=0;
				while((p = entry_title.toLowerCase().indexOf(tag_name,p)) != -1){
					c++;// ※「c=1」で記事単位。
					p++;
				}
				p=0;
				while((p = entry_body.toLowerCase().indexOf(tag_name,p)) != -1){
					c++;// ※「c=1」で記事単位。
					p++;
				}
				
				if(this.kc_tc_nums[tag_name]){
					this.kc_tc_nums[tag_name] += c;
				}else{
					this.kc_tc_nums[tag_name] = c;
				};
			};
		};
		
		//タグの総数
		var tag_num = 0;
		// 最多タグ
		var tag_most=0;
		//
		for(var tag_name in this.kc_tc_names){
			tag_num++;
			
			if(tag_most < this.kc_tc_nums[tag_name]){
				tag_most = this.kc_tc_nums[tag_name];
			};
		};
		var tc_array = new Array();
		
		if(this.kc_tc_tag_num <= tag_num){
			var i=0;
			var vi=0;
			for(var tag_name in this.kc_tc_names){
				if(!this.kc_tc_nums[tag_name]){
					//エントリーのないタグは無視
					continue;
				};
				var a = this.kc_tc_nums[tag_name] / tag_most;
				a = 6 * a;
				a = Math.floor(a);
				a++;
				vi = i + 1;
				if(a>=6){
					a=6;
				};
				tc_array.push({level:a, name:tag_name, num:this.kc_tc_nums[tag_name], value:this.kc_tc_names[tag_name]});
				i++;
			}
		}//if(this.kc_tc_tag_num <= tag_num){
		if(tc_array.length){
			return tc_array;
		}else{
			return this.getError('TAG');
		};

	};//this.findTags
	
	/*
	 * 重複エントリーを誘惑する
	 *
	 */
	this.enticeSameEntry = function(old_e, new_e){
		var arr = [];
		var old_l = old_e.length;
		var new_l = new_e.length;
		
		for(var i=0; i<old_l; i++){
			var en = old_e[i];
			for(var h=0; h<new_l; h++){
				if(en[1] == new_e[h][1]){
					arr.push(new_e[h]);
					break;
				};
			};
		};
		
		return arr;
	}
	
	/*
	 * エントリーを返す
	 *
	 */
	this.findEntries = function(page){
		
		var start;
		var max;
		if(page == 0){
			start = 0;
			max = this.kc_pulldown_entry_num_start;
		}else{
			start = ((page - 1) * this.kc_pulldown_entry_num) + this.kc_pulldown_entry_num_start;
			max = start + this.kc_pulldown_entry_num;
		};
		
		
		var arr = new Array();
		
		
		for(var i=start; i < max; i++){
			arr.push(this.entries[i]);
		};
		
		return arr;
	};
	
	/**
	 * 最大クリック数
	 */
	this.getMaxCount = function(){
		var max = this.findRankEntries(1);
		return max[0][6];
	}
	
	/**
	 * ランキングの取得
	 */
	this.findRankEntries = function(n){
		//配列のコピー
		var arr = this.entries.concat(new Array());
		
		arr.sort( function (b1, b2) { return Number(b1[6]) < Number(b2[6]) ? 1 : -1; } );
		
		var ranks = arr.splice(0,n);
		return ranks;
	};
	
	
	/**
	 * 選択タグのエントリーを抽出
	 * @param int
	 * @param string
	 */
	this.sortEntriesByTag = function(tag_name){
		
		this.entries = new Array();
		
		if(!Boolean(tag_name) && this.isRandom){
			this.entries = this.entryRandomize(this.kc_entries.concat(new Array()));
			return;
		};
		//タグが存在するかどうか
		var is_tag = false;
		if(tag_name != ""){
			for(var i=0; i < this.kc_tags.length; i++){
			
				if(this.kc_tags[i].name == tag_name){
					tag_no = i + 1;
					is_tag = true;
					break;
				};
			};
		};
		if(!is_tag){
			tag_name = "";
		};
		
		var re=eval('/'+tag_name+'/');
		
		
		//表示用記事の選別
		
		for(var i = 0, k = 0; i < this.kc_entries.length; i++){
			
			if(this.kc_entries[i][0].toLowerCase().indexOf(tag_name) != -1 
					|| this.kc_entries[i][3].toLowerCase().indexOf(tag_name) != -1){
				
				this.entries.push(this.kc_entries[i]);
				k++;
			};
		};
		
		
	};//sortEntriesByTag
	
	//ランダムに並べ替え
	this.entryRandomize = function(entries){
		
		var arr = new Array();
		
		var i = entries.length;
    while(i){
        var j = Math.floor(Math.random()*i);
        var t = entries[--i];
        entries[i] = entries[j];
        entries[j] = t;
    };
		return entries;
	};
		
	this.init();
};


var KcFunction = {
	cleanEm: function(){
		var ems = document.getElementsByTagName("em");
		
		for(var i=0; i < ems.length; i++){
			var html = ems[i].innerHTML.replace(/<\/?em>/gi,'');
			ems[i].innerHTML = html;
		};
	},
	inArray: function(arr, s){
	
		for(var i=0; i < arr.length; i++){
			if(arr[i] == s){
				return true;
			};
		};
		return false;
	},
	getSubstitution: function(str){
		var sub = "";
		for(var i=0; i < str.length; i++){
			sub += "*";
		};
		return sub;
	}

};
