Event.observe(window, 'load', function(){
	var image_search = new ImageSearch($('keyword').value);
	$('message').innerHTML = '<img src="/images/common/loading_mini.gif" width="16" height="16" alt="Loading..." />Loading...';
	var images = $('images');
	$A(images.getElementsByTagName('img') || []).each(function(img){
		if(+img.height > 180)img.height = '150';
	});

	var results = $('results');
	var results_height = Element.getDimensions(results).height;
	var executer = new PeriodicalExecuter(function(){
		if(image_search.isLoading())return;
		var self = arguments.callee;
		if(!image_search.append({callback: self})){
			$('message').innerHTML = 'end.';
		}
	}, 0.01);
	image_search.fill({
		callback: function(){
			var self = arguments.callee;
			var images_height = Element.getDimensions(images).height;
			if(images_height < results_height){
				if(!image_search.append({callback: self})){
					$('message').innerHTML = 'end.';
				}
			}
		}
	});
	Event.observe(window, 'resize', function(){
		results_height = Element.getDimensions(results).height;
	});
});

var ImageSearch = Class.create();
ImageSearch.prototype = {
	engines: 'google_image,yahoo_image,flickr'.split(','),
	index: 0,
	state: [],
	relational: [],
	loading: false,
	ad: null,
	initialize: function(keyword){
		var self = this;
		var current = $('engine').innerHTML.split(',');
		this.keyword = keyword.toLowerCase();
		this.engines.each(function(eng){
			self.state[eng] = (current.include(eng)) ? 2 : 1;
		});
		this.images = $('images');
		this.count = $('count');
		this.filter = $('filter').value;
		this.relational_words = $('relational_words');
		$A(this.relational_words.getElementsByTagName('a') || []).each(function(a){
			self.relational.push(a.innerHTML);
		});
	},
	append: function(options){
		if(!this.engines.length)return false;
		if(this.loading)return true;
		this.loading = true;
		var self = this;
		var count = this.count;
		if(count.innerHTML >= 2000)return false;
		var filter = this.filter;

		options = options ? options : {};
		var callback = options.callback || function(){};
		var images = this.images;
		var engine = options.engine || this.getEngine(this.index);
		var state = this.getState(engine);
		var keyword = this.keyword;
		var parameters = $H({
			engine: engine,
			keyword: keyword,
			page: state,
			filter: filter
		}).toQueryString();
		var timeout = false;
		var ltid = setTimeout(function(){
			timeout = true;
			self.failure(engine);
			self.loading = false;
			callback();
		}, 15000);
		new Ajax.Request('/image/json', {
			method: 'get',
			parameters: parameters,
			onSuccess: function(response){
				if(timeout)return;
				clearTimeout(ltid);
				var res = eval('[' + response.responseText + ']');
				var results = res[0].results || [];
				var relational = res[0].relational || [];
				var blank = '_blank', str_li = 'li', str_a = 'a', str_img = 'img';
				var str_load = 'load', str_error = 'error', str_none = 'none';

				var rellen = relational.length;
				var c = 0;
				if(rellen){
					var tid2 = setInterval(function(){
						self.setRelationalWord(relational[c]);
						if(++c >= rellen)clearInterval(tid2);
					}, 100);
				}

				var i = 0;
				var rlen = results.length;
				if(rlen){
					var tid = setInterval(function(){
						var r = results[i];
						var li = document.createElement(str_li);
						var a = document.createElement(str_a);
						var img = document.createElement(str_img);

						if(engine.match(/^dmm1$/)){
							var vc = 'http://ck.jp.ap.valuecommerce.com/servlet/referral?sid=2450834&pid=876714273';
							vc += '&vc_url=http%3a%2f%2fdbirth%2edmm%2eco%2ejp%2fhit%2ehtml%3fID%3dvaluecommerce%26url%3d';
							vc += encodeURI(r.url).toLowerCase();
							r.url = vc;
							if(self.ad){
								self.ad.src = 'http://ad.jp.ap.valuecommerce.com/servlet/gifbanner?sid=2450834&pid=876714273';
							}
						}
						if(engine.match(/^dmm2$/)){
							r.url += 'kanpeki-001';
						}

						a.href = r.url;
						a.target = blank;
						img.src = r.thumbnail;
						if(r.width)img.width = r.width;
						if(r.height)img.height = r.height;
						img.title = r.title;
						img.alt = r.title;

						Event.observe(img, str_load, function(){
							if(+img.height > 180)img.height = '150';
							if(+img.height <= 8 && +img.width <= 8)img.style.display = str_none;
						});
						Event.observe(img, str_error, function(){
							img.style.display = str_none;
						});
						images.appendChild(li);
						li.appendChild(a);
						a.appendChild(img);
						count.innerHTML = +count.innerHTML + 1;

						if(engine.match(/^valuecommerce$/)){
							var src = r.url.replace('ck.', 'ad.').replace('referral', 'gifbanner').replace(/\&vc_url=.+/, '');
							if(!self.ad){
								var ad = document.createElement('img');
								ad.width = '1';
								ad.height = '1';
								ad.alt = '';
								ad.src = src;
								$('site').appendChild(ad);
								self.ad = ad;
							}
							self.ad.src = src;
						}

						if(++i == results.length){
							clearInterval(tid);
							self.success(engine);
							self.loading = false;
							callback();
						}
					}, 50);
				}else{
					self.success(engine);
					self.loading = false;
					callback();
				}
			},
			onFailure: function(){
				if(timeout)return;
				clearTimeout(ltid);
				self.failure(engine);
				self.loading = false;
				callback();
			}
		});
		return true;
	},
	getEngine: function(index){
		return this.engines[(index || this.index) % this.engines.length];
	},
	getEngines: function(){
		return this.engines;
	},
	getState: function(engine){
		return this.state[engine];
	},
	success: function(engine){
		this.state[engine]++;
		this.index++;
		this.index %= this.engines.length;
	},
	failure: function(engine){
		this.state[engine] = false;
		this.engines = this.engines.without(engine);
		if(this.engines.length){
			this.index %= this.engines.length;
		}
	},
	fill: function(options){
		var callback = options.callback || function(){};
		var self = this;
		var flag = true;
		for(var i = 0, len = this.engines.length; i < len; i++){
			var eng = this.engines[i];
			if(this.getState(eng) == 1){
				this.append({
					engine: eng,
					callback: function(){
						self.fill({callback: callback});
					}
				});
				flag = false;
				break;
			}
		}
		if(flag)callback();
	},
	isLoading: function(){
		return this.loading;
	},
	setRelationalWord: function(word){
		if(this.relational.include(word))return false;
		var li = document.createElement('li');
		var a = document.createElement('a');
		a.href = '/search/' + encodeURI(word);
		a.innerHTML = word;
		Element.addClassName(li, (this.relational.length % 2) ? 'even' : 'odd');
		this.relational_words.appendChild(li);
		li.appendChild(a);
		this.relational.push(word);
		return true;
	}
};
