var yt;
Event.observe(window, 'load', function(){
	yt = new SmoothTube();
	var keyword = $('keyword');
	keyword.focus();
	Event.observe($('search'), 'submit', function(e){
		Event.stop(e);
		var kw = keyword.value;
		kw && yt.search(kw);
	});
	//keyword.value && yt.search(keyword.value);
	Event.observe(window, 'resize', function(){
		yt.setWindow();
	});
	var popular = $('popular');
	var history = $('history');
	var keep = $('keep');
	var results = $('results');
	history.innerHTML = '';
	popular.innerHTML = '';
	Event.observe($('popular-navi'), 'click', function(){
		yt.changePanel(popular);
	});
	Event.observe($('results-navi'), 'click', function(){
		yt.changePanel(results);
	});
	var his_first = true;
	Event.observe($('history-navi'), 'click', function(){
		yt.changePanel(history);
	});
	Event.observe($('keep-navi'), 'click', function(){
		yt.changePanel(keep);
	});

	var hash = window.location.hash.toString();
	hash = hash.replace(/^#/, '');
	if(hash){
		yt.search(hash);
		keyword.value = hash;
	}

	yt.getPopularVideos();
});
String.prototype.toTime = function(){
	var min = parseInt(this / 60);
	var sec = this % 60;
	return ((min < 10) ? '0' : '') + min + ':' + ((sec < 10) ? '0' : '') + sec;
	
}
var SmoothTube = Class.create();
SmoothTube.prototype = {
	reselem: null,
	head: null,
	url: null,
	keywords: [],
	initialize: function(){
		var reselem = $('results');
		this.reselem = reselem;
		this.head = document.getElementsByTagName('head')[0];
		this.body = document.getElementsByTagName('body')[0];

		this.contents = $('contents');
		this.main = $('main');
		this.sub = $('sub');
		this.information = $('information');
		this.player = $('player');
		var history = $('history');
		this.history = history;
		var popular = $('popular');
		this.popular = popular;
		var keep = $('keep');
		this.keep = keep;
		this.search_form = $('search');
		this.submit = $('submit');
		this.keyword = $('keyword');

		reselem.style.display = 'none';
		history.style.display = 'none';
		keep.style.display = 'none';

		this.now_playing = '';
		this.played_video = [];
		this.info = [];
		this.info[history.id] = '<p class="linfo">Your viewing history on Smooth<strong>Tube</strong>';
		this.info[keep.id] = '<p class="linfo">Your favorite videos</p>';

		this.keep_color = '#ffb';
		this.keep_videos = [];

		this.history_color = '#708';

		this.url = new Template([
			'http://gdata.youtube.com/feeds/videos',
			'?vq=#{vq}',
			'&max-results=#{max_results}',
			'&start-index=#{start_index}',
			'&orderby=#{orderby}',
			'&alt=json-in-script',
			'&callback=#{callback}'
		].join(''));
		this.user_url = new Template([
			'http://gdata.youtube.com/feeds/videos',
			'?author=#{author}',
			'&max-results=#{max_results}',
			'&start-index=#{start_index}',
			'&orderby=#{orderby}',
			'&alt=json-in-script',
			'&callback=#{callback}'
		].join(''));
		this.player_tpl = new Template([
			'<h2>#{title}</h2>',
			'<object id="video" width="#{width}" height="#{height}" type="application/x-shockwave-flash" ',
			'data="http://www.youtube.com/v/#{id}&autoplay=1">',
			'<param name="movie" value="http://www.youtube.com/v/#{id}&autoplay=1" />',
			'<param name="autoplay" value="1" />',
			'<param name="wmode" value="transparent" />',
			'<embed src="http://www.youtube.com/v/#{id}&autoplay=1" ',
			'type="application/x-shockwave-flash" wmode="transparent" width="#{width}" height="#{height}"></embed>',
			'</object>'
		].join(''));
		this.information_tpl = new Template([
			'<p class="linfo">Search results for ',
			'<strong id="query">#{query}</strong></p>',
			'<p class="rinfo"><strong id="visible">#{visible}</strong> of ',
			'<strong id="total">#{total}</strong> videos - <span id="past">#{past}</span> sec</p>'
		].join(''));
		this.indicator = {
			shadow: (function(){
				var div = document.createElement('div');
				var dstyle = div.style;
				dstyle.position = 'absolute';
				dstyle.backgroundColor = 'black';
				dstyle.zIndex = '100';
				dstyle.display = 'none';

				var opacity = 5;

				dstyle.filter = 'alpha(opacity=' + (opacity * 10) + ')';
				dstyle.MozOpacity = opacity / 10;
				dstyle.opacity = opacity / 10;

				var img = document.createElement('img');
				var istyle = img.style;
				img.src = 'images/indicator.gif';
				img.width = 16;
				img.height = 16;
				img.alt = 'Loading...';
				istyle.marginTop = '50%';
				istyle.marginLeft = '50%';

				div.appendChild(img);
				$('main').appendChild(div);
				return div;
			})(),
			setPosition: function(){
				var shadow = this.shadow;
				[reselem, popular, history, keep].each(function(r){
					(Element.visible(r)) && Position.clone(r, shadow);
				});
			},
			on: function(){
				this.shadow.style.display = '';
			},
			off: function(){
				this.shadow.style.display = 'none';
			}
		};
		this.reselem.scrollTop = 0;

		var iframe = document.createElement('iframe');
		iframe.width = '1';
		iframe.height = '1';
		iframe.src = 'dummy';
		this.body.appendChild(iframe);
		this.iframe = iframe;
		this.setWindow();
	},
	_appendScript: function(url){
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.charset = 'utf8';
		script.src = url;
		this.head.appendChild(script);
	},
	searchFromStater: function(query){
		query = query.unescapeHTML();
		var last_query = this.query || '';
		var self = this;
		setTimeout(function(){
			if(last_query != query){
				self.search(query, true);
			}
		}, 0);
	},
	search: function(query, state){
		if(!query)return false;
		this.changePanel(this.reselem);
		this.keyword.value = query;
		Form.disable(this.search_form);
		this.indicator.on();
		this.std = (new Date()).getTime();
		this.query = query;
		var now = this.now_playing;
		state || this.changeState({id: now, query: query});
		this.current_page = 1;
		var url = !query.match(/^user:/) ? this.url.evaluate({
			vq: encodeURI(query.toLowerCase()).replace('&', '+'),
			max_results: (this.result_cols * 10),
			start_index: 1,
			orderby: 'relevance',
			callback: 'yt._newSearch'
		}) : this.user_url.evaluate({
			author: query.replace(/^user:/, ''),
			max_results: (this.result_cols * 10),
			start_index: 1,
			orderby: 'relevance',
			callback: 'yt._newSearch'
		});
		this._appendScript(url);
	},
	getPopularVideos: function(){
		//this.changePanel(this.popular);
		Form.disable(this.search_form);
		this.indicator.on();
		this.std = (new Date()).getTime();
		
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.charset = 'utf8';
		script.src = 'http://gdata.youtube.com/feeds/standardfeeds/most_viewed?time=today&alt=json-in-script&callback=yt._popularVideos';
		this.head.appendChild(script);
	},
	_popularVideos: function(json){
		this.appendVideo(json, this.popular);
		Form.enable(this.search_form);
		this.keyword.focus();
		this.indicator.off();
		new Ajax.Request('history', {
			method: 'get',
			onSuccess: function(response){
				eval('var videos = ' + response.responseText);
				setTimeout(function(){
					videos.each(function(video){
						if(!video)return;
						yt.intoHistory(video, true);
					});
				}, 300);
			}
		});
		new Ajax.Request('keep', {
			method: 'get',
			onSuccess: function(response){
				eval('var videos = ' + response.responseText);
				setTimeout(function(){
					videos.each(function(video){
						if(!video)return;
						yt.keepVideo(video, true);
					});
				}, 400);
			}
		});
	},
	_newSearch: function(json){
		if(!this.query.match(/^user:/) && !json.feed.title.$t.replace('YouTube Videos matching query: ', '').match(this.query.toLowerCase().replace(/\&|\+/, ' '))){
			return;
		}
		var reselem = this.reselem;
		var std = this.std;
		var total = +json.feed.openSearch$totalResults.$t;
		this.total = total;
		reselem.scrollTop = 0;
		reselem.innerHTML = (total) ? '' : ('<p>No videos found for ' + this.query + '</p>');
		//this.indicator.setPosition();
		
		var smv = this.start_max_visible;
		if($('query')){
			$('query').innerHTML = this.query;
			$('visible').innerHTML = (!total) ? '0-0' : ('1-' + ((total < smv) ? total : smv));
			$('total').innerHTML = total;
			$('past').innerHTML = ((new Date()).getTime() - std) / 1000;
		}else{
			this.information.innerHTML = this.information_tpl.evaluate({
				query: this.query,
				total: total,
				visible: (!total) ? '0-0' : ('1-' + ((total < smv) ? total : smv)),
				past: ((new Date()).getTime() - std) / 1000
			});
			this.rewriteVisibleVideoNumber();
		}
		this.info[reselem.id] = this.information.innerHTML;
		this.appendVideo(json);
		Form.enable(this.search_form);
		this.keyword.focus();
		this.indicator.off();
		(total) && this.revolveKeyword(this.query);
	},
	setWindow: function(){
		var contents = this.contents;
		var main = this.main;
		var sub = this.sub;
		var player = this.player;
		var px = 'px';

		var result = document.createElement('div');
		Element.addClassName(result, 'result');
		result.style.visibility = 'hidden';
		this.body.appendChild(result);		
		
		var result_dim = Element.getDimensions(result);
		var result_width = result_dim.width;
		var result_height = result_dim.height;

		this.body.removeChild(result);		

		var contents_width = Element.getDimensions(contents).width;
		var cols = parseInt((contents_width - 450) / result_width);
		cols = (cols > 4) ? 4 : ((cols < 1) ? 1 : cols);

		var main_width = result_width * cols + 20;
		var sub_width = contents_width - main_width - 5;
		main.style.width = main_width + px;
		sub.style.width = sub_width + px;
		var player_width = sub_width - 10;
		player.style.width = player_width + px;
		player.style.marginLeft = '10px';
		//this.search_form.style.right = (sub_width + 5) + px;

		//var video_width = (sub_width > 560) ? 530 : (sub_width - 30);
		var video_width = player_width - 2;
		var video_height = parseInt(video_width / 420 * 350);

		var main_height = Element.getDimensions(main).height;

		var results_dim = Element.getDimensions(this.reselem);
		var results_width = results_dim.width;
		var results_height = results_dim.height;

		if($('video')){
			var vstyle = $('video');
			vstyle.width = video_width;
			vstyle.height = video_height;
		}

		this.indicator.setPosition();
		this.video_width = video_width;
		this.video_height = video_height;
		this.result_width = result_width;
		this.result_height = result_height;
		this.result_cols = cols;
		this.results_width = results_width;
		this.results_height = results_height;
		this.start_max_visible = parseInt((results_height - 30) / result_height + 1) * cols;
	},
	playVideoFromId: function(id){
		var self = this;
		if(this.now_playing.match(id))return;
		this.played_video.each(function(video){
			if(video.id.match(id)){
				video.no_push = true;
				self.playVideo(video);
			}
		});
	},
	playVideo: function(video){
		var self = this;
		var doc = document;
		var title = video.title;
		var id = video.id;
		var category = video.category;		
		var description = video.description.replace(
			/(http:\/\/[0-9a-zA-Z_#%&\(\)\/\.\[\]\?\+\*\!\=\~\-]+)/g,
			'<a href="$1" target="_blank">$1</a>'
		);		
		var author = video.author;
		var rates = video.rate;
		var view_count = video.view_count;

		var pvideo = this.played_video;
		this.now_playing = id;
		if(!video.no_push){
			var flag = true;
			var query = this.query;
			pvideo.each(function(v){
				if(v.id.match(id))flag = false;
			});
			flag && this.played_video.push(video);
			this.changeState({id: id, query: query});
		}

		var player = this.player;
		var search_tpl = new Template('search for #{term}');
		var kcat = 'http://gdata.youtube.com/schemas/2007/keywords.cat';
		var click_t = 'click', li_t = 'li';

		var video_obj = doc.createElement('div');
		video_obj.innerHTML = this.player_tpl.evaluate({
			title: title,
			id: id,
			width: self.video_width,
			height: self.video_height
		});


		var keep_button = doc.createElement('span');
		keep_button.id = 'keep_button';
		//keep_button.title = 'keep "' + video.title + '"';
		Element.addClassName(keep_button, 'keep_button');
		var kp = 'Keep this video';
		var dn = 'Don\'t keep';
		keep_button.innerHTML = ((this.keep_videos || []).indexOf(video.id) >= 0) ? dn : kp;
		Event.observe(keep_button, 'click', function(){
			(keep_button.innerHTML.match(kp)) ? self.keepVideo(video) : self.removeKeepVideo(video);
		});
		var attrs = doc.createElement('p');
		Element.addClassName(attrs, 'attributes');
		
		var from = doc.createElement('em');
		var from_value = doc.createElement('span');
		from.innerHTML = 'From';
		from_value.innerHTML = author;
		Event.observe(from_value, 'click', function(){
			self.search('user:' + author);
			self.keyword.value = 'user:' + author;
		});
		Element.addClassName(from_value, 'author');
		attrs.appendChild(from);
		attrs.appendChild(from_value);

		var rate = doc.createElement('em');
		var rate_value = doc.createElement('span');
		rate.innerHTML = 'Rate';
		rate_value.innerHTML = rates;
		Element.addClassName(rate_value, 'rate');
		(rates >= 4) && Element.addClassName(rate_value, 'hot');
		attrs.appendChild(rate);
		attrs.appendChild(rate_value);

		var view = doc.createElement('em');
		var view_value = doc.createElement('span');
		view.innerHTML = 'Views';
		view_value.innerHTML = view_count;
		Element.addClassName(view_value, 'view');
		(view_count >= 10000) && Element.addClassName(view_value, 'hot');
		attrs.appendChild(view);
		attrs.appendChild(view_value);

		var tags = doc.createElement('p');
		Element.addClassName(tags, 'tag');
		var sp = doc.createElement('em');
		sp.innerHTML = 'Tags';
		tags.appendChild(sp);
		(video.keywords || '').split(', ').each(function(term){
			var span = doc.createElement('span');
			span.innerHTML = term;
			span.title = search_tpl.evaluate({term: term});
			Event.observe(span, click_t, (function(term){
				return function(){
					self.search(term);
					self.keyword.value = term;
				}
			})(term));
			tags.appendChild(span);
			tags.appendChild(doc.createTextNode(' '));
		});
		
		var desc = doc.createElement('p');
		desc.innerHTML = description;
		Element.addClassName(desc, 'description');
		player.innerHTML = '';
		player.appendChild(video_obj);
		player.appendChild(keep_button);
		player.appendChild(attrs);
		player.appendChild(tags);

		var player_height = Element.getDimensions(player).height;
		var div_height = Element.getDimensions(video_obj).height;
		var attrs_height = Element.getDimensions(attrs).height;
		var tag_height = Element.getDimensions(tags).height;
		var desc_height = player_height - div_height - attrs_height -tag_height - 30;
		player.appendChild(desc);
		if(Element.getDimensions(desc).height > desc_height)desc.style.height = desc_height + 'px';
	},
	rewriteVisibleVideoNumber: function(){
		var self = this;
		var reselem = this.reselem;
		var hyphen = '-';
		Event.observe(this.reselem, 'scroll', function(){
			var visible = $('visible');
			var cols = self.result_cols;
			var vheight = self.result_height;
			var rheight = self.results_height;
			var total = self.total;

			var scr = reselem.scrollTop;
			var start = parseInt((scr + 30) / vheight) * cols + 1;
			var end = parseInt((scr + rheight - 30) / vheight) * cols + cols;
			end = (end > total) ? total : end;
			visible.innerHTML = start + hyphen + end;
			var vpp = cols * 5;
			if(end >= (self.current_page * vpp)){
				self.current_page++;
				var start_index = self.current_page * vpp + 1;
				var max_results = ((start_index + vpp) > 1000) ? (1000 - start_index) : vpp;
				var url = (!self.query.match(/^user:/)) ? self.url.evaluate({
					vq: encodeURI(self.query.toLowerCase()).replace('&', '+'),
					max_results: max_results,
					start_index: start_index,
					orderby: 'relevance',
					callback: 'yt.appendVideo'
				}) : self.user_url.evaluate({
					author: self.query.replace(/^user:/, ''),
					max_results: max_results,
					start_index: start_index,
					orderby: 'relevance',
					callback: 'yt.appendVideo'
				});
				(start_index < 1000) && self._appendScript(url);
			}
		});
	},
	appendVideo: function(json, target){
		var self = this;
		var doc = document;
		var reselem = target || this.reselem;
		var div_t = 'div', img_t = 'img', click_t = 'click', span_t = 'span';
		var total = +json.feed.openSearch$totalResults.$t;
		this.total = total;
		var count = 2000;
		$('total') && ($('total').innerHTML = total);
		(json.feed.entry || []).each(function(entry){
			var title = entry.title.$t;
			var media = entry.media$group;
			var description = (media.media$description || {$t:''}).$t;
			var thumbnail = media.media$thumbnail[2];
			var id = entry.id.$t.split('/').last();
			var category = entry.category;
			var keywords = (media.media$keywords || {$t:''}).$t;
			var view_count = (entry.yt$statistics || {viewCount:0}).viewCount || 0;
			var rate = (entry.gd$rating) ? entry.gd$rating.average : 0;
			var author = entry.author[0].name.$t;
			var duration =  media.yt$duration.seconds.toTime();

			var video = {
				id: id,
				title: title,
				description: description,
				category: category,
				keywords: keywords,
				author: author,
				rate: rate,
				time: duration,
				view_count: view_count,
				thumbnail: thumbnail
			};
			var div = self.createResultElement(video);
			if((self.keep_videos || []).indexOf(id) >= 0){
				Element.addClassName(div, 'keeped');
			}
			self.history_videos || (self.history_videos = []);
			if(self.history_videos.indexOf(id) >= 0){
				Element.addClassName(div, 'viewed');
			}
			Event.observe(div, click_t, function(){
				self.playVideo(video);
				self.intoHistory(video);
				Element.addClassName(div, 'viewed');
			});
			Event.observe(div, 'contextmenu', function(e){
				Event.stop(e);
				self.contextMenu(video, e);
			});

			reselem.appendChild(div);
		});
	},
	changePanel: function(panel){
		var info = this.info;
		[this.popular, this.reselem, this.history, this.keep].without(panel).each(function(p){
			Element.visible(p) && (info[p.id] = $('information').innerHTML);
			p.style.display = 'none';
			Element.addClassName($(p.id + '-navi'), 'inactive');
			Element.removeClassName($(p.id + '-navi'), 'active');
		});
		$('information').innerHTML = info[panel.id] || '';
		panel.style.display = 'block';
		Element.addClassName($(panel.id + '-navi'), 'active');
		Element.removeClassName($(panel.id + '-navi'), 'inactive');
	},
	revolveKeyword: function(keyword){
		var i = this.keywords.indexOf(keyword.toLowerCase());
		if(i >= 0){
			var l = $('recent-keyword').childNodes[this.keywords.length - i - 1];
			this.keyword_true_width -= Element.getDimensions(l).width;
			$('recent-keyword').removeChild(l);
			this.keywords = this.keywords.without(keyword.toLowerCase());
		}
		this.keywords.push(keyword.toLowerCase());
		var li = document.createElement('li');
		var lstyle = li.style;
		li.innerHTML = keyword;
		li.title = 'search for ' + keyword;
		lstyle.marginLeft = '-100px';
		if(!$('recent-keyword')){
			var ul = document.createElement('ul');
			ul.id = 'recent-keyword';
			$('header').appendChild(ul);
			this.recent_keyword_width = Element.getDimensions(ul).width;
			this.keyword_true_width = 0;
		}
		var self = this;
		Event.observe(li, 'click', function(){
			self.search(keyword);
		});
		var recent_keyword = $('recent-keyword');
		recent_keyword.insertBefore(li, recent_keyword.firstChild);
		var w = -100, px_t = 'px';
		var tid = setInterval(function(){
			lstyle.marginLeft = w + px_t;
			w += 3;
			if(w > 2){
				clearInterval(tid);
				self.keyword_true_width += Element.getDimensions(li).width + 2;
				while(self.keyword_true_width > self.recent_keyword_width){
					var last = recent_keyword.lastChild;
					self.keyword_true_width -= Element.getDimensions(last).width;
					self.keywords.shift();
					recent_keyword.removeChild(last);
				}
			}
		}, 5);
	},
	createResultElement: function(video){
		var div = document.createElement('div');
		var img = document.createElement('img');
		var time = document.createElement('span');
		Element.addClassName(time, 'time');
		time.appendChild(document.createTextNode('[' + video.time + ']'));

		var title = video.title;
		var description = video.description;

		var thumbnail = video.thumbnail;
		img.src = thumbnail.url;
		img.height = thumbnail.height;
		img.width = thumbnail.width;
		img.alt = title;

		div.title = description;
		div.name = video.id;
		Element.addClassName(div, 'result');
		div.appendChild(img);
		var p = document.createElement('p');
		p.appendChild(document.createTextNode(title + ' '));
		p.appendChild(time);
		div.appendChild(p);

		return div;
	},
	keepVideo: function(video, flag){
		this.keep_videos || (this.keep_videos = []);
		if(this.keep_videos.indexOf(video.id) >= 0){
			return;
		}
		var velem = this.createResultElement(video);
		var vstyle = velem.style;
		var keep = this.keep;
		var self = this;
		var id = video.id;
		(this.now_playing.match(id) && $('keep_button')) && ($('keep_button').innerHTML = 'Don\'t keep');
		Element.addClassName(velem, 'keeped');
		[this.popular, this.reselem, this.history].each(function(elem){
			var div = $A(elem.getElementsByTagName('div'));
			div.each(function(d){
				d.name.match(id) && Element.addClassName(d, 'keeped');
			});
		});
		Event.observe(velem, 'click', function(){
			self.playVideo(video);
			self.intoHistory(video);
			Element.addClassName(velem, 'viewed');
		});
		Event.observe(velem, 'contextmenu', function(e){
			Event.stop(e);
			self.contextMenu(video, e);
		});

		this.history_videos || (this.history_videos = []);
		if(this.history_videos.indexOf(id) >= 0){
			Element.addClassName(velem, 'viewed');
		}

		var keep_color = 238;
		var kstyle = $('keep-navi').style;
		var n = 0;
		var tid = setInterval(function(){
			kstyle.backgroundColor = '#eeee' + n.toColorPart();
			n += 5;
			if(n > keep_color){
				clearInterval(tid);
				kstyle.backgroundColor = '';
			}
		}, 10);
		(this.keep_videos.length) ? keep.insertBefore(velem, keep.getElementsByTagName('div')[0]) : keep.appendChild(velem);
		this.keep_videos.push(id);

		flag || new Ajax.Request('keep', {
			method: 'post',
			postBody: 'id=' + id + '&video=' + encodeURIComponent(Object.toJSON(video))
		});
		
	},
	removeKeepVideo: function(video){
		var keep_videos = this.keep_videos;
		if(keep_videos.indexOf(video.id) < 0)return;
		var keep = this.keep;
		var id = video.id;
		var div = keep.getElementsByTagName('div');
		(this.now_playing.match(id) && $('keep_button')) && ($('keep_button').innerHTML = 'Keep this video');
		div.length.times(function(i){
			var d = div[i];
			if(!d.name.match(id))return;
			var opacity = 100;
			var vstyle = d.style;
			var tid = setInterval(function(){
				if(opacity < 0)opacity = 0;
				vstyle.filter = 'alpha(opacity=' + (opacity) + ')';
				vstyle.MozOpacity = opacity / 100;
				vstyle.opacity = opacity / 100;
				if(opacity <= 0){
					clearInterval(tid);
					setTimeout(function(){
						keep.removeChild(d);
					}, 400);
				}
				opacity -= 5;
			}, 10);
		});
		[this.popular, this.reselem, this.history].each(function(elem){
			var div = $A(elem.getElementsByTagName('div'));
			div.each(function(d){
				d.name.match(id) && Element.removeClassName(d, 'keeped');
			});
		});
		this.keep_videos = keep_videos.without(id);
		new Ajax.Request('delete_keep', {
			method: 'post',
			postBody: 'id=' + id
		});
	},
	intoHistory: function(video, flag){
		this.history_videos || (this.history_videos = []);
		var history = this.history;
		var id = video.id;
		flag || new Ajax.Request('history', {
			method: 'post',
			postBody: 'id=' + id + '&video=' + encodeURIComponent(Object.toJSON(video))
		});
		if(this.history_videos.indexOf(id) >= 0){
			var histries = history.getElementsByTagName('div');
			histries.length.times(function(i){
				var his = histries[i];
				if(his.name.match(id)){
					history.removeChild(his);
					if(histries.length > 1){
						history.insertBefore(his, histries[0]);
					}else{
						history.appendChild(his);
					}
				}
			});
			return;
		}
		var velem = this.createResultElement(video);
		var vstyle = velem.style;
		var self = this;
		if((this.keep_videos || []).indexOf(video.id) >= 0){
			Element.addClassName(velem, 'keeped');
		}
		Element.addClassName(velem, 'viewed');

		[this.popular, this.reselem, this.history].each(function(elem){
			var div = $A(elem.getElementsByTagName('div'));
			div.each(function(d){
				d.name.match(id) && Element.addClassName(d, 'viewed');
			});
		});

		Event.observe(velem, 'click', function(){
			self.playVideo(video);
		});
		Event.observe(velem, 'contextmenu', function(e){
			Event.stop(e);
			self.contextMenu(video, e);
		});
		(this.history_videos.length) 
			? history.insertBefore(velem, history.getElementsByTagName('div')[0]) : history.appendChild(velem);
		this.history_videos.push(id);
	},
	contextMenu: function(video, e){
		var m = document.createElement('div');
		var body = this.body;
		var self = this;
		var id = video.id;
		var keeped = (this.keep_videos.indexOf(id) >= 0);
		m.innerHTML = (keeped) ? 'Don\'t keep' : 'Keep this video';
		Element.addClassName(m, 'keep-menu');
		m.style.left = (Event.pointerX(e)) + 'px';
		m.style.top = (Event.pointerY(e) - 3) + 'px';
		Event.observe(m, 'click', function(){
			body.removeChild(m);
			(keeped) ? self.removeKeepVideo(video) : self.keepVideo(video);
			Event.stopObserving(m, 'click', arguments.callee);
			m = null;
		});
		Event.observe(m, 'mouseout', function(){
			body.removeChild(m);
			Event.stopObserving(m, 'mouseout', arguments.callee);
			m = null;
		});
		body.appendChild(m);
	},
	changeState: function(obj){
		var id = encodeURIComponent(obj.id || '');
		var query = encodeURIComponent(obj.query || '');
		this.iframe.src = 'state?id=' + id + '&query=' + query;
	},
	clearPlayer: function(){
		this.player.innerHTML = '';
	},
	clearSearchResults: function(){
		this.reselem.innerHTML = '';
		this.info[this.reselem.id] = '';
	}
}
