function YahooSearch(){
	this.params = "";
	this.callback = "";
	this.timer = "";
	this.initialize.apply(this,arguments);
}

/**
 * 検索結果を取得する
 */
YahooSearch.prototype = {
	baseUrl : "./php/request.php?",
	name : "yahoo",
	
	initialize : function(){
		
	},
	
	doSearch : function(params,interval,callback){
		this.params = params;
		this.callback = callback;
		this.url = this.buildUrl(params);
		setTimeout(b(this,this.sendRequest),interval);
	},
	
	buildUrl : function(params){
		var url = this.baseUrl +
		"&p=" + encodeURIComponent(params.query) +
		"&num=" + params.num +
		"&start=" + params.start +
		"&block=" + params.block;
		log(url);
		return url;
	},
	
	sendRequest : function(){
		var url = this.url;
		log(url);
		$.get(url,b(this,this.recieveResults));
	},
	
	
	recieveResults : function(response){
		try {
			var result = eval("(" + response + ")");
			var query =result.query;
			var num = result.num;
			var totalResults = result.totalResults;
			var block = result.block;
			var rawItems = result.items;
			var items = [];
			var rank = block * $R.requestUnit + 1;
			
			for(var i = 0, n = rawItems.length; i < n; i++){
				items.push(new YahooItem(rawItems[i],rank++));
			}
			
			this.callback(items,query,totalResults,items.length,block);
		}
		catch(e){
			this.callback([],this.params.query,0,0,this.params.block);
		}
	}
};

function YahooItem(){
	this.title = "";	//元
	this.s_title = "";	//表示用
	this.url  = "";
	this.s_url = "";
	this.summary = "";
	this.s_sumary = "";
	this.originalRank = 0;
	this.currentRank = 0;
	this.element = null;
	this.morphed = false;
	this.id = "";
	this.elm = null;
	this.term = "";
	this.content = "";
	this.initialize.apply(this,arguments);
}

/**
 * 検索結果要素
 */
YahooItem.prototype = {
	
	maxUrlLength : 75,
	strongTag : "<strong>",
	strongCloseTag : "</strong>",
	
	initialize : function(rawItem,rank){
		log(rawItem.title);
		this.title = rawItem.title;
		this.s_title = $R.escapeHTML(rawItem.title);
		this.url = rawItem.url;
		this.s_url = this.url;
		try{
			this.s_url = decodeURI(this.url);
		}catch(e){
			
		}
		//長すぎるURLはカット
		this.s_url = $R.escapeHTML(this.s_url.substring(0,Math.min(75,this.s_url.length)));
		this.summary = rawItem.summary;
		this.s_summary = $R.escapeHTML(rawItem.summary);
		this.originalRank = rank;
		this.currentRank = rank;
		this.reranked = false;
		this.content = this.title + " " + this.summary;		
		//クエリ文字列をstrongで囲う
		var strong = this.strongTag;
		var strong_close = this.strongCloseTag;
		for(var i = 0, n = $R.queryList.length ; i < n; i++){
			this.s_title = this.s_title.replace($R.queryRegList[i],
				function(match){
					return strong + match + strong_close;
				});
			this.s_summary = this.s_summary.replace($R.queryRegList[i],
				function(match){
					return strong + match + strong_close;
				});
		}
		//this.element = this.toHtml();
	},
	
	format : 	'<div class="item">\r\n' +
				'<a href="' + "#url#" + '" target="_blank"><span class="title" type="title">' + "#s_title#" + '</span></a>\r\n' +
				'<div class="summaryarea" type="summary">\r\n' +
				'<span class="summary" type="summary">' + "#s_summary#" +'</span>\r\n' +
				'</div>\r\n' +	//summaryarea  +
				'<span class="url" type="smallurl">' + "#s_url#" + '　元:' + "#originalRank#" + '位</span>\r\n' +
				'</div>\r\n',
				
	str_url : "#url#",
	str_s_title: "#s_title#",
	str_s_summary : "#s_summary#",
	str_s_url : "#s_url#",
	str_o_rank : "#originalRank#",
	
	string_title : "title",
	string_url : 'smallurl',
	string_summary : "summary",
	string_tag :"tag",
	string_original : "original",
	string_content : "content",
	string_type : "type",			
	
	toHtml : function(){
		//innerHTML&replaceで作成
		try{
			var elm = document.createElement('li');
			elm.id = "item" +this.currentRank;
			this.id = elm.id;
			elm.setAttribute(this.string_type,this.string_content);
			elm.setAttribute(this.string_original,this.originalRank);
			var source = this.format.replace(this.str_url,this.url).
				replace(this.str_s_title,this.s_title).
				replace(this.str_s_summary,this.s_summary).
				replace(this.str_s_url,this.s_url).
				replace(this.str_o_rank,this.originalRank);
			elm.innerHTML = source;
			this.elm = elm;
			//$(this.elm).bind('mouseenter',b($E,$E.itemMouseEnter));
			return elm;
		}catch(e){
			return null;
		}
	},
	
	makeElementFromSource : function(source){
		var elm = document.createElement('li');
		elm.id = "item" +this.currentRank;
		this.id = elm.id;

		elm.setAttribute(this.string_type,this.string_content);
		elm.setAttribute(this.string_original,this.originalRank);		
		elm.innerHTML = source;
		$("#result").get(0).replaceChild(this.prev,elm);
		this.elm = elm;
		this.reranked = false;
	},
	
	makeElementfromElement : function(element){
		if (this.reranked) {
			this.elm = element;
		}
		this.reranked = false;
	},
	
	isContain : function(termReg,type){
		var content = this.content;
		switch (type) {
			case this.string_title:
			case this.string_summary:
			case this.string_tag:
				if (content.search(termReg) != -1) {
					return true;
				}
				break;
			case this.string_url:
				if (this.url.search(termReg) != -1) {
					return true;
				}
				break;
		}
		return false;
	},
	
	termEmphasis : function(term,termReg,replaceReg){
		this.term = term;
		this.curElement = this.elm;
		this.curType = "em";
		this.termReg = termReg;
		this.replaceReg = replaceReg;
		this.reranked = true;
		
//		setTimeout(b(this,this.highlightKeyword_call),10);
		this.highlightKeyword(this.elm,term,"em",termReg,replaceReg);
	},

	termDeletion : function(term,termReg,replaceReg){
		this.term = term;
		this.curElement = this.elm;
		this.curType = "del";
		this.termReg = termReg;
		this.replaceReg = replaceReg;
		this.reranked = true;
//		setTimeout(b(this,this.highlightKeyword_call),10);
		this.highlightKeyword(this.elm,term,"del",termReg,replaceReg);
	},
	
	s_span  : "span",
	s_span1 : '<span type="term" value="',
	s_span2 : '" class="',
	s_span3 : '">',
	s_span4 : "</span>",
	/**
	 * setTimeout版
	 * 検索結果中の指定の文字列をspanタグで囲う
	 */
	highlightKeyword_call : function(){
		var term = this.term;
		var type= this.curType;
		var element = this.curElement;
		var termReg = this.termReg;
		var replaceReg = this.replaceReg;
		var elms = element.childNodes;
		for(var i = 0, n = elms.length; i < n; i++){
			var elm = elms[i];
			var nodeType = elm.nodeType;
			var nodeValue = elm.nodeValue;
			if(nodeType == 3){	//textnode
				if(nodeValue.search(termReg) != -1){
					var elements = nodeValue.split(term);
					var span = document.createElement(s_span);
					var text = nodeValue.replace(replaceReg, this.s_span1 + term + this.s_span2 + type + this.s_span3 + term + this.s_span4);
					//var text = nodeValue.replace(replaceReg,'<span type="term" value="' + term + '" class="' + type + '">' + term + "</span>");
					span.innerHTML = text;
					element.replaceChild(span,elm);
				}
			}
			this.curElement = elm;
			setTimeout(b(this,this.highlightKeyword_call()),10);
		}
	},
	

	highlightKeyword : function(element,term,type,termReg,replaceReg){
		var elms = element.childNodes;
		for(var i = 0, n = elms.length; i < n; i++){
			var elm = elms[i];
			var nodeValue = elm.nodeValue;
			var nodeType = elm.nodeType;
			if(nodeType == 3){	//textnode
				if(nodeValue.search(termReg) != -1){
					var elements = nodeValue.split(term);
					var span = document.createElement("span");
					var text = $R.escapeHTML(nodeValue).replace(replaceReg,
						function(match){
							return '<span type="term" value="' + match + '" class="' + type + '">' + match + "</span>";
						});
					//alert(text);
					span.innerHTML = text;
					element.replaceChild(span,elm);
				}
			}
			this.highlightKeyword(elm,term,type,termReg,replaceReg);
		}
	},


	doMorph_call : function(){
		var element = this.curMorphElement;
		var elms = element.childNodes;
		for(var i = 0, n = elms.length; i < n; i++){
			var elm = elms[i];
			if(elm.nodeType == 3){	//textnode
			//	log(elm.nodeValue);
				var text = elm.nodeValue.replace($C.morphReg, "<span class=\"morph\">$1</span>");
				log(text);
				var span = document.createElement('span');
				span.innerHTML = text;
				element.replaceChild(span, elm);
				 var childs = span.childNodes;
				 for(var j = 0, k = childs.length; j < k; j++){
					 if (childs[j].tagName && childs[j].tagName.toLowerCase() == "span") {
					 	$(childs[j]).bind("click", b($E, $E.termElementClick));
					 }
				 }
			
			}
			this.curMorphElement = elm;
			setTimeout(b(this,this.doMorph_call()),300);
		}
	},
	
	/**
	 * 検索結果を形態素解析してノードを置き換える
	 */		
	doMorph : function(element){
		var elms = element.childNodes;
		for(var i = 0, n = elms.length; i < n; i++){
			var elm = elms[i];
			if(elm.nodeType == 3){	//textnode
				log(elm.nodeValue);
				var text = elm.nodeValue.replace($C.morphReg, "<span class=\"morph\">$1</span>");
				log(text);
				var span = document.createElement('span');
				span.innerHTML = text;
				element.replaceChild(span, elm);
				 var childs = span.childNodes;
				 for(var j = 0, k = childs.length; j < k; j++){
					 if (childs[j].tagName && childs[j].tagName.toLowerCase() == "span") {
					 	$(childs[j]).bind($("#loading").get(0).innerHTML, b($E, $E.termElementClick));
					 }
				 }
			
			}
			this.doMorph(elm);
		}
	}
};

