/**
 * 主にイベントのハンドリングを扱う
 */
var EventHandler = {
	
	name : "EventHandelr",
	lastActiveType : "",
	lastBaseNode : null,
	selectString : "",
	maxRecursion : 6,
	anchorNode : null,
	anchorHref: "",
	defaultQueryText : "検索語句を入力！",
	
	/**
	 * 
	 */
	initialize : function(){
		//強調削除ボタン
		$('#buttonEmphasis').bind("click",b(this,this.buttonEmphasisClick));
		$('#buttonDeletion').bind("click",b(this,this.buttonDeletionClick));	
		/*
		$('#buttonEmphasis').hover(
			function(){
				$('#buttonEmphasis').get(0).setAttribute('src',"img/button_emphasis_h.gif");
			},
			function(){
				$('#buttonEmphasis').get(0).setAttribute('src',"img/button_promote.png");
			});
		$('#buttonDeletion').hover(
			function(){
				$('#buttonDeletion').get(0).setAttribute('src',"img/button_deletion_h.gif");
			},
			function(){
				$('#buttonDeletion').get(0).setAttribute('src',"img/button_demote.png");
			});
		*/			
		//query box
		$('#textQuery').bind("focus",b(this,this.queryFocus));
	},
	
	/**
	 * 検索結果中の語に対してitembind
	 */
	bindItems : function(){
			$("#result").bind('mouseup',b($E,$E.itemMouseUp));
			$("#result").bind('mousedown',b($E,$E.itemMouseDown));
			$("#result").bind('click',b($E,$E.termClick));
			$("#tagcloud").bind('click',b($E,$E.termElementClick));
			$("#tagcloud").bind('mousedown',b($E,$E.itemMouseDown));
			
//			$("#mainarea").bind('mousedown',b($E,$E.itemMouseDown));

//		$("#result").each(function(){
//			$(this).bind('mouseup',b($E,$E.itemMouseUp));
//			$(this).bind('mousedown',b($E,$E.itemMouseDown));
//		});
		
		
//      //検索結果自動形態素解析を有効にするかどうか
//		$("li").hover(b($E,$E.itemMouseEnter),function(){});
//		
	},
	
	bindHighLightEvent : function(element){
		var spans = element.getElementsByTagName('span');
		for(var i = 0, n = spans.length; i < n; i++){
			var e = spans[i];
			if (e.getAttribute('class') && e.getAttribute('class') == "em") {
				$(e).bind('mouseenter',b($E,$E.termEnter));
				$(e).bind('mouseout', b($E,$E.termLeave));
			}
		}
	},
	
	itemMouseDown : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		log('mousedown');
		var element = event.target;
		$R.hideFloat();	//mousedownの時点でボタンは非表示に変更する
		var anchor = this.getAnchorNode(element,0);	//<a>タグの場合はhrefを消去し文字列を選択可能にする
		if(anchor){
			if (anchor.isbinded) {
			
			}
			else {
				$(anchor).bind('mouseup', b($E, $E.anchorMouseUp));
				$(anchor).bind('mousemove', b($E, $E.anchorMouseMove));
				$(anchor).bind('click', b($E, $E.anchorClick));
				anchor.isbinded = true;
			}
			this.removeAnchor(anchor);
		}
		return;
	},
	
	itemMouseUp : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		log('mouseup');
		var element = event.target;
		
		this.restoreAnchor();

		var lastActiveType = this.getTargetType(element,0);
		var selectString = this.getSelectString();
		if(!selectString){
			$R.hideFloat();
			return;
		}
		log(selectString);

		log(lastActiveType);
		if(lastActiveType == "whitespace"){
			lastActiveType = "tag";
		}
		
		//検索結果以外の箇所でのクリックは何もしない
		if ((lastActiveType != "title") && (lastActiveType != "smallurl") &&
			(lastActiveType != "summary") &&
			(lastActiveType != "tag")) {
			return; //
		}
		log(selectString + "::" + lastActiveType);
		//選択文字列，操作対象ノード，属性を記録
		this.selectString = selectString;
		this.lastActiveType = lastActiveType;
		$R.startFloat(event.pageX,event.pageY);
		var base = this.getBaseNode(element,0);
		$E.lastBaseNode = base;
		if (base) {
			$R.highlightItems(selectString, lastActiveType, this.getCurrentRank(base.id), base);
		}
		return;
		//highlight
	},
	
	/**
	 * tag等のクリックだけで選択できる要素
	 * @param {Object} event
	 */
	termElementClick : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		log('term click');
		var element = event.target;
		if($R.activeElement){
			$($R.activeElement).removeClass('active');
			$R.activeElement = null;
		}
		$(element).addClass('active');
		$R.activeElement = element;
		this.lastActiveType = this.getTargetType(element);
		this.selectString = $(element).text();
		this.lastBaseNode = this.getBaseNode(element);
		log(this.selectString + ";; " + this.lastActiveType);
		$R.startFloat(event.pageX,event.pageY);
	},
	
	termClick : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		var element = event.target;
		var base = this.getTermNode(element,0);
		if(base){
//			alert(this.selectString);
			if(this.selectString && this.selectString.length >= 1){
				return;
			}
			var text = element.getAttribute('value');
			var suf = "";
			switch(element.getAttribute('class')){
				case "em":
					suf = "　";
					break;
				case "del":
					suf = " -";
					break;
			}
			$('#textQuery').val($("#textQuery").val() + suf + text);
			$("#formarea").submit();	
		}
	},
	
	termEnter : function(event){
		var style = {
			"position" : "absolute",
			"top" : event.pageY,
			"left" : event.pageX
		}
		$("#popup").css(style);
		$("#popup").show();
	},
	
	termLeave : function(event){
		$("#popup").hide();
	},


	anchorMouseDown : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		//左クリック検出をする
		if (event.button !== 0) {
			return;
		}
	
		//アンカーテキストを選択しようとした場合
		var target = event.target;
		if(target.tagName && target.tagName.toLowerCase() == "a"){
			this.removeAnchor(target);
		}
		else{
			var a = this.getAnchorNode(target,0);
			this.removeAnchor(a);
		}		
	},
		
	anchorMouseUp : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		//リンクの遷移判定はclickで行われる
		this.restoreAnchor();	
	},
	
	anchorClick : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		//何も選択していなければ，クリックイベント（URLのopen）を発生させる
		var selectString = this.getSelectString();
		if (selectString) {
			event.preventDefault();
			return;
		}
		//logging
		var element = event.target;
		var base = this.getBaseNode(element,0);
		$L.click(base);
	},
	
	anchorMouseMove : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		if ($.browser.safari) {
			return; //Safariとchromeはmousemove時にhrefが復活しているとanchorを選択してしまう
		}
		//アンカーテキストを復帰する処理はclickイベント
		this.restoreAnchor();
	},
	
	anchorMouseOut : function(event){
		if (!this.isLeftButton(event)) {
			return;
		}
		this.restoreAnchor();
	},
	
	/**
	 * mouse downを行ったanchorノードからリンクを一時的に消去
	 * 現状ではSafariでは上手く動作しない
	 * @param {Object} anchor
	 */
	removeAnchor : function(anchor){
		if (anchor && anchor.tagName && 
			anchor.tagName.toLowerCase() == "a" &&
			anchor.getAttribute('href')) {
			this.anchorNode = anchor;
			this.anchorHref = anchor.getAttribute('href');
			anchor.removeAttribute('href');
		}		
	},
	
	/**
	 * 一時的に除去したanchorを元に戻す
	 */
	restoreAnchor : function(){
		if(this.anchorNode){
			this.anchorNode.setAttribute('href',this.anchorHref);
			this.anchorNode = null;
			this.anchorHref = null;
		}			
	},
	
	/** item **/
	
	itemMouseEnter : function(event){
		
		var element = event.target;

		element = this.getBaseNode(element,0);

		var rank = this.getCurrentRank(element.id);
		if (rank <= 0) {
			return;
		}
		var item = $R.items[rank-1];
		if (!item.morphed) {
			item.morphed = true;
			log(item.id);
			log(item.elm.textContent);
			item.curMorphElement = item.elm;
			setTimeout(b(item,item.doMorph_call),300);
//			item.doMorph(item.elm);
		}
//	item.highlightKeyword(item.elm,"パターン","em");	

//		$R.items[0].morph($R.items[0].elm);
		
	},
	
	getCurrentRank : function(id){
		for(var i = 0, n =$R.items.length; i < n; i++){
				if(id == $R.items[i].id){
					return i + 1;
				}
		}
		return 0;
	},
	
	
	buttonEmphasisClick : function(event){
		if (!$R.prepareRerank()) {
			return;
		}
		$R.rerankTimer = setTimeout(b($R,$R.termEmphasis),100);
//		$R.termEmphasis();
	},
	
	buttonDeletionClick : function(event){
		if (!$R.prepareRerank()) {
			return;
		}
		$R.rerankTimer = setTimeout(b($R,$R.termDeletion),100);
//		$R.termDeletion();
	},
	
	buttonSearchKeyPress : function(event){
		var code = event.code;
		//改行コード
		if(code == 13){
			$R.startSearch();
		}
	},
	
	/**
	 * 自動的に選択
	 * chromeでは意図通りに動作しない
	 */
	queryFocus : function(event){
		if(event && event.target){
			if($("#textQuery").val() == this.defaultQueryText){
				$("#textQuery").val('');
				return;
			}
			try{
				event.target.select();
			}
			catch(e){
				
			}
		}
	},
	
	queryLostFocus : function(event){
		
	},
	
	/* util */
		
	getSelectString: function(){
		var selectString = "";
		try {
			selectString = window.getSelection().toString();
		} 
		catch (e) {
			selectString = document.selection.createRange().text;
		}
		if (selectString) {
			selectString = selectString.replace(/^[\s　]+|[\s　]+$/g, "");
		}
		return selectString;
	},
	
	getBaseNode : function(element,depth){
		if(depth >= this.maxRecursion){
			return null;
		}
		if(element && element.getAttribute('type') &&
			 (element.getAttribute('type') == "content" || element.getAttribute('type') == "tag")){
			return element;
		}
		else{
			if (element.parentNode) {
				return this.getBaseNode(element.parentNode, depth + 1);
			}
			else{
				return null;
			}
		}
	},
	
	getTermNode: function(element,depth){
		if(depth >= this.maxRecursion){
			return null;
		}
		if(element && element.getAttribute('nodetype') && element.getAttribute('nodetype') == "term"){
			return element;
		}
		else{
			if (element.parentNode) {
				return this.getTermNode(element.parentNode, depth + 1);
			}
			else{
				return null;
			}
		}		
	},
	
	getTargetType : function(element,depth){
		if(depth >= this.maxRecursion){
			return null;
		}
		if(element && element.getAttribute('type')){
			return element.getAttribute('type');
		}
		else{
			if (element.parentNode) {
				return this.getTargetType(element.parentNode, depth + 1);
			}
			else{
				return null;
			}
		}		
	},
	
	getParentAnchorNode : function(elm,depth){
		if(depth > 3){
			return null;
		}
		if(elm && elm.tagName.toLowerCase() == "a"){
			return elm;
		}
		else{
			return this.getParentAnchorNode(elm.parentNode,depth + 1);
		}
	},	
		
	getAnchorNode : function(element,depth){
		if(depth > this.maxRecursion){
			return null;
		}
		
		if(element && element.tagName && element.tagName.toLowerCase() == "a"){
			return element;
		}
		else{
			if(element.parentNode){
				return this.getAnchorNode(element.parentNode,depth + 1);
			}
			else{
				return null;
			}
		}
	},
	
	
	  isLeftButton: function(event) {
	   	if(event.which){
			return event.which == 1;
		}
		else{	//IE click用
			return event.button === 0;
		}
	  }
	
};


var $E = EventHandler;