$(function(){
	$('img.favicon').one('error', function(){
		$(this).css('background-color', 'orange');
	});
	var next = '';
	var prev = '';
	$('#entries a').attr('href', function(){return $(this).attr('href').replace(/^http:\/\/hatebladder\.inucara\.net\/url\//, '')});
	Entry.preload($('#entries a:first').attr('href'));
	Pin.get();
	$('#entries li').click(function(){
		Entry.set($(this));
		return false;
	});

	$('ul.tab li').click(function(){
		Panel.set($(this).attr('id').replace('-tab', ''));
		return false;
	});

	$('h1').click(function(){
		$('#main').load('/top');
		return false;
	});

	$('body').append($(document.createElement('div'))
		.css('width', '30%')
		.css('height', '5%')
		.css('position', 'absolute')
		.css('bottom', '0')
		.css('right', '0')
		.click(function(){
			Entry.scrollDown();
		})
	);

	$(document).keydown(function(e){
		if((e.target || e.srcElement).tagName.match(/input/i))return true;
		switch(/*e.charCode || */e.keyCode){
			case 39: case 83:
				Entry.next();
				break;
			case 37: case 65:
				Entry.prev();
				break;
			case 36:
				Entry.scrollTop();
				break
			case 35:
				Entry.scrollBottom();
				break
			case 33: case 38: case 75:
				Entry.scrollUp();
				break;
			case 34: case 40: case 74: case 32:
				Entry.scrollDown();
				break;
			case 98: case 86:
				Entry.open();
				break;
			case 84:
				Panel.next();
				break;
			case 80: case 96:
				var url = Entry.getUrl();
				Pin.exists(url) ? Pin.clear(url) : Pin.set(url);
				break;
			case 79: case 97:
				Pin.open();
				break;
			case 70:
				$('#tag-input').length && $('#tag-input').get(0).select();
				$('#id-input').length && $('#id-input').get(0).select();
				break;
			default:
				return true;
		}
		return false;
	});
});
var Entry = {
	entries: [],
	tid: null,
	li: null,
	url: '',
	positions: [],
	appending: false,
	set: function(li){
		var url = li.children('a').attr('href')
			.replace(/^http:\/\/hatebladder\.inucara\.net\/url\//, '').replace(/#e[0-9]+$/, '');
		if(!url)return false;
		this.li && this.li.removeClass('selected');
		li.addClass('selected');
		this.li = li;
		this.url = url;
		var self = this;
		setTimeout(function(){
			if(self.entries[url]){
				self.append(self.entries[url], url);
				self.preload();
			}else{
				$.get('/url?url=' + encodeURIComponent(url), null, function(html, status){
					self.append(html, url);
					self.entries[url] = html;
					self.preload();
					setTimeout(function(){
						self.entries[url] = null;
					}, 1000 * 180);
				});
			}
		}, 0);
	},
	append: function(html, url){
		this.scrollTid && clearTimeout(this.scrollTid);
		this.scrollFlag = false;
		if(this.url != url)return;
		var main = this.main || (this.main = $('#main'));
		main.html(html).get(0).scrollTop = 0;
		document.title = 'Hatebladder2 - ' + $.trim($('h2', main).text());

		var self = this;

		this.positions = [];
		var positions = this.positions;
		
		Pin.exists(this.url) && $('#entry').addClass('pin');

		$('.tags a', main).click(function(){
			Panel.set('tag', $(this).text());
			return false;
		});

		$('#comments a.id', main).click(function(){
			Panel.set('user', $(this).text());
			return false;
		});

		var lis = $('#comments li', main);
		for(var i = 0, len = lis.length; i < len; i += 10){
			var li = lis.get(i);
			positions.push(li.offsetTop);
			$(li).addClass('first');
		}
		$('#to-top', main).click(function(){
			Entry.scrollTop();
			return false;
		});
		//Panel.scrollTo((this.li.prev().length && this.li.prev().prev().length) ? this.li.prev().prev().get(0) : {offsetTop: 0});
		Panel.scrollTo(this.li.get(0));
	},
	preload: function(u){
		var self = this;
		var url = u ? [u] : [];
		var li = this.li;
		li && li.next().length && url.push(li.next().children('a:first').attr('href')
			.replace(/^http:\/\/hatebladder\.inucara\.net\/url\//, '').replace(/#e[0-9]+$/, ''));
		li && li.prev().length && url.push(li.prev().children('a:first').attr('href')
			.replace(/^http:\/\/hatebladder\.inucara\.net\/url\//, '').replace(/#e[0-9]+$/, ''));
		$.each(url, function(){
			var u = this;
			if(!u || self.entries[u])return;
			$.get('/url?url=' + encodeURIComponent(u), null, function(html, status){
				self.entries[u] = html;
				setTimeout(function(){
					self.entries[u] = null;
				}, 1000 * 180);
			});
		});
	},
	next: function(){
		//((this.li && this.li.next().length) ? this.li.next() : $('.entries li:first')).click();
		(this.li)
			 ? (this.li.next().length) && this.li.next().click()
			 : $('.entries li:first').click();
	},
	prev: function(){
		//((this.li && this.li.prev().length) ? this.li.prev() : $('.entries li:last')).click();
		(this.li)
			 ? (this.li.prev().length) && this.li.prev().click()
			 : $('.entries li:last').click();
	},
	open: function(){
		window.open(this.url);
	},
	scrollFlag: false,
	scrollTid: null,
	scrollUp: function(flag){
		if(this.scrollFlag)return;
		var self = this;
		this.scrollFlag = true;
		var main = (this.main || $('#main')).get(0);
		var scroll = main.scrollTop;
		var target = 0;
		if(!flag){
			var positions = this.positions;
			for(var i = positions.length - 1; i >= 0; i--){
				if(positions[i] < scroll - 30){
					target = positions[i];
					break;
				}
			}
		}
		var i = parseInt((scroll - target) / 10);
		(function(){
			var tout = arguments.callee;
			self.scrollTid = setTimeout(function(){
				scroll -= parseInt(i);
				if(i > 7)i /= 1.08;
				if(scroll <= target){
					scroll = target;
					self.scrollFlag = false;
				}else{
					tout();
				}
				main.scrollTop = scroll;
			}, 10);
		})();
	},
	scrollTop: function(){
		this.scrollUp(true);
	},
	scrollDown: function(flag){
		if(this.scrollFlag)return;
		var self = this;
		this.scrollFlag = true;
		var main = (this.main || $('#main')).get(0);
		var scroll = main.scrollTop;
		var positions = this.positions;
		var target = positions.length ? positions[positions.length - 1] : null;
		if(!flag){
			for(var i = 0, len = positions.length; i < len; i++){
				if(positions[i] > scroll + 30){
					target = positions[i];
					break;
				}
			}
		}
		if(!target)return (this.scrollFlag = false);
		var i = parseInt((target - scroll) / 10);
		(function(){
			var tout = arguments.callee;
			self.scrollTid = setTimeout(function(){
				scroll += parseInt(i);
				if(i > 7)i /= 1.08;
				if(scroll >= target){
					scroll = target;
					self.scrollFlag = false;
				}else{
					tout();
				}
				main.scrollTop = scroll;
			}, 10);
		})();
	},
	scrollBottom: function(){
		this.scrollDown(true);
	},
	getUrl: function(){
		return this.url;
	}
};
var Panel = {
	panels: [],
	ids: /^hot|attention|tag|user|video$/,
	current: 'hot',
	value: '',
	user: 'inucara',
	tag: 'html',
	control: {
		hot: [$(document.createElement('h3'))
			.html('<a href="http://b.hatena.ne.jp/hotentry" target="_blank">人気エントリー</a>')],
		attention: [$(document.createElement('h3'))
			.html('<a href="http://b.hatena.ne.jp/entrylist?sort=hot" target="_blank">注目エントリー</a>')],
		tag: [
			$(document.createElement('h3'))
				.html('<a href="http://b.hatena.ne.jp/t/html" target="_blank">タグ「html」を含むエントリー</a>'),
			$(document.createElement('form'))
				.html([
					'<fieldset>',
						'<legend accesskey="l">タグ検索</legend>',
						'<label for="tag-input">タグ</label>',
						'<input type="text" size="20" value="html" name="tag" id="tag-input" accesskey="t" tabindex="1" />',
						'<input type="submit" value="GO!" id="tag-submit" accesskey="s" tabindex="2" />',
					'</fieldset>',
				].join(''))
				.submit(function(){
					Panel.set('tag', $('#tag-input').val());
					return false;
				})
		],
		user: [
			$(document.createElement('h3'))
				.html('<a href="http://b.hatena.ne.jp/inucara/" target="_blank">id:inucara のブックマーク</a>'),
			$(document.createElement('form'))
				.html([
					'<fieldset>',
						'<legend accesskey="l">ユーザ検索</legend>',
						'<label for="id-input">ユーザ</label>',
						'<input type="text" size="20" value="inucara" name="id" id="id-input" accesskey="t" tabindex="1" />',
						'<input type="submit" value="GO!" id="tag-submit" accesskey="s" tabindex="2" />',
					'</fieldset>',
				].join(''))
				.submit(function(){
					Panel.set('user', $('#id-input').val());
					return false;
				})
		],
		video: [$(document.createElement('h3'))
			.html('<a href="http://b.hatena.ne.jp/video" target="_blank">注目の動画</a>')]
		
	},
	set: function(id, value){
		if(!this.ids.test(id))return false;
		var self = this;
		this.current = id;
		if(id == 'user'){
			value = value ? (this.user = value) : this.user;
			this.control['user'][0].html([
				'<a href="http://b.hatena.ne.jp/',
				encodeURI(value),
				'/" target="_blank">id:',
				value,
				' のブックマーク</a>'
			].join(''));
		}else if(id == 'tag'){
			value = value ? (this.tag = value) : this.tag;
			this.control['tag'][0].html([
				'<a href="http://b.hatena.ne.jp/t/',
				encodeURI(value),
				'" target="_blank">タグ「',
				value,
				'」を含むエントリー</a>'
			].join(''));
		}
		$('.tab li').each(function(){
			if($(this).attr('id').match(id))$(this).addClass('active').removeClass('inactive');
			else $(this).addClass('inactive').removeClass('active');
		});

		/*if(!value ? this.panels[id] : (this.panels[id] || [])[value]){
			this.append(!value ? this.panels[id] : this.panels[id][value]);
			return true;
		}*/
		this.panels[id] = [];
		$.getJSON(
			'/panel?id=' + id + ((value) ? ('&value=' + encodeURIComponent(value)) : ''),
			function(json){
				//var cache = !value ? self.panels[id] : self.panels[id][value];
				//cache = json;
				self.append(json);
			}
		);
	},
	append: function(obj){
		var entries = this.entries || (this.entries = $('#entries'));
		var echildren = entries.children();
		$('#panel').get(0).scrollTop = 0;
		var control = $('#control').empty();
		$.each(this.control[this.current], function(){
			this.appendTo(control);
		});
		(this.current == 'tag') && $('#tag-input').val(this.tag);
		(this.current == 'user') && $('#id-input').val(this.user);
		var pre = 'http://b.hatena.ne.jp/entry/image/';
		$.each(obj, function(i){
			var title = this.title;
			var url = this.url;
			var video_id = this.video_id;
			var favicon = this.favicon;
			var ent = $(document.createElement('li')).append(
				$(document.createElement('a')).attr('href', url).append(
					(!video_id) 
						? $(document.createElement('img'))
							.attr('width', '16')
							.attr('height', '16')
							.attr('alt', '')
							.attr('src', favicon)
							.addClass('favicon')
							.one('error', function(){
								$(this).css('background-color', 'orange');
							})
						: $(document.createElement('img'))
							.attr('width', '80')
							.attr('height', '60')
							.attr('alt', '')
							.attr('src', 'http://img.youtube.com/vi/' + video_id + '/default.jpg')
							.addClass('youtube'),
					$(document.createElement('img'))
						.attr('height', '13')
						.attr('alt', 'ブックマーク数')
						.addClass('bookmark')
						.attr('src', pre + url),
					title
				).addClass(Pin.exists(url) ? 'pin' : '')
			).click(function(){
				Entry.set($(this));
				return false;
			});
			entries.append(ent);
			if(!i)ent.click();
		});
		echildren.remove();
	},
	scrollTo: function(target){
		var panel = this.panel || (this.panel = $('#panel-direction').get(0));
		var scroll = panel.scrollTop;
		var offset = target.offsetTop - 100;
		offset = (offset < 0) ? 0 : offset;
		var m = parseInt((offset - scroll) / 10);
		var i = 0;
		(function(){
			var tout = arguments.callee;
			setTimeout(function(){
				var t = panel.scrollTop + m;
				if(((m > 0) ? (t >= offset) : (t <= offset)) || ++i > 10)t = offset;
				else tout();
				panel.scrollTop = t;
			}, 10);
		})();
	},
	next: function(){
		var id = 'hot,attention,user,tag,video'.split(',');
		var index;
		for(var i = 0, len = id.length; i < len; i++){
			if(id[i] == this.current){
				index = i;
				break;
			}
		}
		var next = id[(index + 1) % id.length];
		var value = (next == 'user') ? this.user
				: (next == 'tag') ? this.tag : '';
		this.set(next, value);
	}
};
Pin = {
	pins: [],
	set: function(url){
		if(url && $.inArray(url, this.pins) < 0){
			this.pins.push(url);
			$('#entry').addClass('pin');
			$('#pin-count').text(this.pins.length);
			$.ajax({
				url: '/pin',
				type: 'post',
				data: {url: url}
			});
			$("#entries a[href='" + url + "']").addClass('pin');
		}
	},
	clear: function(url){
		!url ? (this.pins = []) : this.exists(url) && this.pins.splice($.inArray(url, this.pins), 1);
		$('#entry').removeClass('pin');
		$(url ? "#entries a[href='" + url + "']" : '#entries a').removeClass('pin');
		$('#pin-count').text(this.pins.length);
		$.ajax({
			url: '/pin',
			type: 'post',
			data: {url: url || '', 'type': 'delete'}
		});
	},
	open: function(){
		$.each(this.pins, function(){
			window.open(this);
		});
		this.clear();
	},
	exists: function(url){
		return ($.inArray(url, this.pins) >= 0);
	},
	get: function(){
		var self = this;
		$.getJSON('/pin', function(pins){
			if(pins && pins.length){
				self.pins = pins;
				$('#pin-count').text(self.pins.length);
				$.each($('#entries a'), function(){
					($.inArray($(this).attr('href'), pins) >= 0) && $(this).addClass('pin');
				});
			};
		});
	}
};
