/*
 * Copyright (c) 2008 Otchy
 * This source file is subject to the MIT license.
 * http://viewer.webcomicranking.com
 */
(function() {
	var d = document;
	var w = window;
	var err = function (msg) {
		alert('[WCR コミックビューワ]\n' + msg);
	}
	if (!d.getElementById || !d.getElementsByTagName) {
		err('ご利用になっているブラウザでは、WCR コミックビューワは動作しません。');
		return;
	}
	var byId = function(id) {return d.getElementById(id);}

	var bind;
	if (d.attachEvent) {
		bind = function (o, e, f) {
			o.attachEvent('on' + e, f);
		}
	} else if (d.addEventListener) {
		bind = function (o, e, f) {
			o.addEventListener(e, f, false);
		}
	}
	function getElement(id, tag, styles, insertBefore, appendChild) {
		var e = byId(id);
		if (!e) {
			e = d.createElement(tag);
			e.id = id;
			if (styles) {
				setStyles(e, styles);
			}
			if (insertBefore) {
				insertBefore.parentNode.insertBefore(e, insertBefore);
			} else if (appendChild) {
				appendChild.appendChild(e);
			}
		}
		return e;
	}
	function setStyles(e, styles) {
		for (name in styles) {
			e.style[name] = styles[name];
		}
	}
	function setSize(e, width, height) {
		setStyles(e, {'width' : width + 'px', 'height' : height + 'px'});
	}
	function setPageSize(e) {
		setSize(e, cv.width, cv.height);
	}
	function createPageImg(num) {
		var img = d.createElement('img');
		var topPx = '0px';
		var leftPx = '0px';
		switch (cv.opt.scroll) {
		case 'left' :
			if (cv.width > 0) {
				leftPx = ((cv.list.length - num - 1) * cv.width) + 'px';
			}
			break;
		case 'right' :
			if (cv.width > 0) {
				leftPx = (num * cv.width) + 'px';
			}
			break;
		case 'down' :
		case 'none' :
			if (cv.height) {
				topPx = (num * cv.height) + 'px';
			}
		}
		setStyles(img, {border: 'none', margin: '0', padding: '0', position: 'absolute', top: topPx, left: leftPx});
		return img;
	}
	function setCookie(name, value) {
		var date = new Date();
		date.setTime(date.getTime() + 30 * 1000 * 60 * 60 * 24);
		var exp = date.toGMTString();
		d.cookie = name + "=" + escape(value) + ";expires=" + exp;
	}
	function getCookie(name) {
		var cookie = d.cookie + ';';
		var start = cookie.indexOf(name + '=');
		if (start == -1) { return ''; }
		var end = cookie.indexOf(';', start);
		var value = unescape(cookie.substring(start + name.length + 1, end));
		return value;
	}
	function createHref(prefix, suffix, width, num) {
		var numstr = num + '';
		while (numstr.length < width) {
			numstr = '0' + numstr;
		}
		return prefix + numstr + suffix;
	}

	var cv = {};
	cv.ver = '1.2.1';
	cv.root = 'http://viewer.webcomicranking.com/';
	cv.opt = {
		page_clickable: true,
		scroll: 'down',
		window_scroll: true,
		view_pages: true,
		use_jump: true,
		use_bookmark: true,
		bg_color: '#000',
		font_color: '#fff',
		border_color: '#999',
		menu_width: 100,
		menu_side: 'right',
		image_path: cv.root + 'images/',
		form_bg_color: '#ccc',
		form_font_color: '#000',
		form_border_color: '#fff',
		msg_bg_color: '#f66',
		msg_font_color: '#fff',
		msg_border_color: '#fff'
	};
	cv.current = 0;
	cv.list = new Array();
	cv.imgs = new Array();
	cv.load = function (num) {
		if (!cv.list[num]) return;
		if (cv.imgs[num]) return;
		cv.imgs[num] = createPageImg(num);
		setPageSize(cv.imgs[num]);
		cv.imgs[num].onload = function() {
			this.loaded = true;
		}
		var inserted = false;
		for (var i=num+1; i<cv.list.length; i++) {
			if (cv.imgs[i]) {
				cv.page.insertBefore(cv.imgs[num], cv.imgs[i]);
				inserted = true;
				break;
			}
		}
		if (!inserted) {
			cv.page.appendChild(cv.imgs[num]);
		}
		cv.imgs[num].src = cv.list[num];
	}
	cv.jump = function(num) {
		if (num < 0 || num >= cv.list.length) { return; }
		var scroll = d.body.scrollTop  || d.documentElement.scrollTop;
		if (cv.timerPage) {clearInterval(cv.timerPage);}
		if (cv.opt.window_scroll && scroll>cv.canvasY) {
			d.documentElement.scrollTop = cv.canvasY;
			d.body.scrollTop = cv.canvasY;
		}
		cv.load(num);
		cv.load(num+1);
		cv.load(num+2);
		cv.current = num;
		if (cv.pages) {
			cv.pages.innerHTML = (num+1) + '/' + cv.list.length + ' ページ';
		}
		if (cv.autosaveCheck && cv.autosaveCheck.checked) {
			cv.saveNum();
		}
		if (cv.timer) {clearInterval(cv.timer);}
		cv.timer = setInterval(cv.scroll, 50);
	}
	cv.next = function() {
		cv.jump(cv.current+1);
	}
	cv.back = function() {
		cv.jump(cv.current-1);
	}
	cv.scroll = function() {
		var scroll, offset;
		var rate = 0.5;
		switch (cv.opt.scroll) {
		case 'left' :
			scroll = (cv.list.length - cv.current - 1) * cv.width;
			offset = cv.page.scrollLeft;
			if (!cv.init) {
				rate = 1.0;
				cv.init = true;
			}
			break;
		case 'right' :
			scroll = cv.current * cv.width;
			offset = cv.page.scrollLeft;
			break;
		case 'down' :
			scroll = cv.current * cv.height;
			offset = cv.page.scrollTop;
			break;
		case 'none' :
			cv.page.scrollTop = cv.current * cv.height;
			clearInterval(cv.timer);
			return;
		}
		if (offset == scroll) {
			clearInterval(cv.timer);
			return;
		}
		var from = scroll > offset ? scroll : offset;
		var to = scroll < offset ? scroll : offset;
		var adjust = scroll > offset ? 0.5 : -0.5;
		var newOffset = Math.floor((from - to)*rate + adjust + to);
		switch (cv.opt.scroll) {
		case 'left' :
		case 'right' :
			cv.page.scrollLeft = newOffset;
			break;
		case 'down' :
			cv.page.scrollTop = newOffset;
		}
	}
	cv.saveNum = function() {
		setCookie('num', cv.current);
	}
	cv.saveNumClick = function() {
		cv.saveNum();
		cv.autosaveOff();
		cv.msg((cv.current+1) + 'ページ目にしおりを挟みました');
	}
	cv.loadNum = function (init) {
		var num = parseInt(getCookie('num'));
		if (!cv.opt.use_bookmark || !(num >= 0)) {
			num = 0;
		}
		if (!init || num>0) {
			cv.msg((num+1) + 'ページ目のしおりを開きました');
		}
		cv.jump(num);
	}
	cv.loadNumClick = function() {
		cv.loadNum(false);
		cv.autosaveOff();
	}
	cv.autosaveOff = function() {
		if (cv.autosaveCheck && cv.autosaveCheck.checked) {
			cv.autosaveCheck.checked = false;
			cv.autosaveCheck.onclick();
		}
	}
	cv.msg = function(msg) {
		if (!cv.msgArea) return;
		cv.msgArea.innerHTML = msg;
		cv.msgArea.style.display = 'block';
		if (cv.msgTimer) {clearTimeout(cv.msgTimer);}
		cv.msgTimer = setTimeout(
			function(){
				cv.msgArea.style.display = 'none'
			}, 3000
		);
	}

	bind(window, 'load', function() {
		if (window.WCRCV_OPTION) {
			for (var opt in WCRCV_OPTION) {
				cv.opt[opt] = WCRCV_OPTION[opt];
			}
		}

		var ul = byId('wcrcv_list');
		if (!ul) {
			var arr = d.getElementsByTagName('ul');
			if (arr.length == 0) {
				err('画像リストが見つかりません。');
				return;
			}
			ul = arr[0];
			ul.id = 'wcrcv_list';
		}
		ul.style.display = 'none';

		var list = ul.childNodes;
		for (var i=0; i<list.length; i++) {
			var li = list[i];
			if (!li.tagName || li.tagName.toUpperCase() != 'LI') { continue; }
			var alist = li.childNodes;
			for (var j=0; j<alist.length; j++) {
				var a = alist[j];
				if (!a.tagName || a.tagName.toUpperCase() != 'A' || !a.href) { continue; }
				cv.list.push(a.href);
				if (a.title && a.title.match(/lastpage=([0-9]+)/)) {
					var lastPage = parseInt(RegExp.$1);
					if (a.href.match(/^(.*[^0-9])?([0-9]+)(\.(GIF|JPG|PNG|JPEG))/i)) {
						var prefix = RegExp.$1;
						var width = RegExp.$2.length;
						var suffix = RegExp.$3;
						var currentPage = parseInt(RegExp.$2);
						for (var k=currentPage+1; k<=lastPage; k++) {
							cv.list.push(createHref(prefix, suffix, width, k));
						}
					}
				}
			}
		}
		if (cv.list.length == 0) { err('画像リストに画像へのリンクが含まれていません。'); }

		var hadCanvas = byId('wcrcv_canvas') ? true : false;
		cv.canvas = getElement('wcrcv_canvas', 'div', null , ul);
		if (!hadCanvas) {
			var innerCanvas = d.createElement('div');
			cv.canvas.appendChild(innerCanvas);
			cv.canvas.id = '';
			innerCanvas.id = 'wcrcv_canvas';
			innerCanvas.style.padding = '5px';
			cv.canvas = innerCanvas;
		}
		var pageFloat = cv.opt.menu_side == 'right' ? 'left' : 'right';
		cv.page = getElement('wcrcv_page', 'div', {styleFloat: pageFloat, cssFloat: pageFloat}, null, cv.canvas);
		setStyles(cv.page, {position: 'relative'});
		cv.page.innerHTML = '';
		cv.imgs[0] = createPageImg(0);
		cv.page.appendChild(cv.imgs[0]);
		setStyles(cv.page, {overflow: 'hidden'});
		cv.imgs[0].onload = function() {
			cv.width = this.offsetWidth;
			cv.height = this.offsetHeight;
			if (cv.opt.scroll == 'left') {
				this.style.left = ((cv.list.length - 1) * cv.width) + 'px';
			}
			setPageSize(cv.page);
			if (cv.opt.page_clickable) {
				cv.page.onclick = cv.next;
				setStyles(cv.page, {cursor: 'pointer'});
			}
			cv.init = false;
			cv.jump(0);

			if (!hadCanvas) {
				setStyles(cv.canvas.parentNode, {
					width: (cv.width + cv.opt.menu_width + 15) + 'px',
					backgroundColor: cv.opt.bg_color,
					color: cv.opt.font_color,
					border: 'solid 1px ' + cv.opt.border_color,
					fontSize: '10pt'
				});
			}

			if (!byId('wcrcv_menu')) {
				var menu = getElement(
					'wcrcv_menu', 'div',
					{
						width: cv.opt.menu_width + 'px',
						styleFloat: cv.opt.menu_side,
						cssFloat: cv.opt.menu_side,
						height: cv.height + 'px'
					},
					null, cv.canvas
				);
				var clear = d.createElement('div');
				clear.style.clear = 'both';
				cv.canvas.appendChild(clear);

				var menuHTML = '';
				if (cv.opt.view_pages) {
					menuHTML += '<div id="wcrcv_pages" style="margin-top: 10px; text-align:center;"></div>';
				}
				menuHTML += '<div style="text-align: center; margin-top: 10px"><img src="' + cv.opt.image_path + 'back.gif" id="wcrcv_back" style="cursor: pointer; border:none; margin:0; padding:0;" alt="" /><img src="' + cv.opt.image_path + 'next.gif" id="wcrcv_next" style="cursor: pointer; border:none; margin:0; padding:0 0 0 5px;" alt="" /></div>';
				if (cv.opt.use_jump) {
					menuHTML += '<div style="margin-top: 10px; text-align:center">ページ指定：<input type="text" id="wcrcv_num" style="width: 20px; border: solid 1px ' + cv.opt.form_border_color + '; color: ' + cv.opt.form_font_color + '; background-color: ' + cv.opt.form_bg_color + '; text-align: right;" /><br />&raquo;Enterで確定</div>';
				}
				if (cv.opt.use_bookmark) {
					menuHTML += '<div style="text-align: center; margin-top: 10px">しおり機能：<br />' +
					'<img src="' + cv.opt.image_path + 'save.gif" id="wcrcv_save" style="cursor: pointer; border:none; margin:0; padding:0;" alt="" /><img src="' + cv.opt.image_path + 'load.gif" id="wcrcv_load" style="cursor: pointer; border:none; margin:0; padding:0 0 0 5px;" alt="" /><br />' +
					'<input type="checkbox" id="wcrcv_autosave"><label for="wcrcv_autosave">自動保存</label></div>' +
					'<div id="wcrcv_msg" style="background-color: ' + cv.opt.msg_bg_color + '; color:' + cv.opt.msg_font_color + '; border: 1px solid ' + cv.opt.msg_border_color + '; padding:2px 4px;"></div>';
				}
				menuHTML += '<hr /><div style="font-size: 6pt; text-align: center"><a href="' + cv.root + '" style="color: ' + cv.opt.font_color + '; text-decoration: underline;" target="_blank">WCR Comic Viewer ' + cv.ver + '</a></div>';
				menu.innerHTML = menuHTML;
			}
			cv.pages = byId('wcrcv_pages');
			cv.backButton = byId('wcrcv_back');
			cv.nextButton = byId('wcrcv_next');
			if (cv.backButton) { cv.backButton.onclick = cv.back; }
			if (cv.nextButton) { cv.nextButton.onclick = cv.next; }
			cv.numText = byId('wcrcv_num');
			if (cv.numText) {
				cv.numText.onkeydown = function(event) {
					event = event ? event : window.event;
					if (event.keyCode == 13) {
						var num = cv.numText.value;
						var han = '0123456789';
						var zen = '０１２３４５６７８９';
						var tmp = '';
						for (var i=0; i<num.length; i++) {
							var c = num.charAt(i);
							var n = zen.indexOf(c,0);
							if (n >= 0) {c = han.charAt(n)};
							tmp += c;
						}
						num = parseInt(tmp);
						if (num > 0) {
							cv.numText.value = num;
							cv.jump(num-1);
							if (num <= cv.list.length) {
								cv.numText.value = '';
							}
						}
					}
				}
			}
			cv.saveButton = byId('wcrcv_save');
			cv.loadButton = byId('wcrcv_load');
			if (cv.saveButton) { cv.saveButton.onclick = cv.saveNumClick; }
			if (cv.loadButton) { cv.loadButton.onclick = cv.loadNumClick; }
			cv.autosaveCheck = byId('wcrcv_autosave');
			if (cv.autosaveCheck) {
				cv.autosaveCheck.onclick = function() {
					if (this.checked) {
						setCookie('autosave', 'on');
					} else {
						setCookie('autosave', 'off');
					}
				}
			}
			if (cv.autosaveCheck) {
				cv.autosaveCheck.checked = (getCookie('autosave') == 'on');
			}
			cv.msgArea = byId('wcrcv_msg');
			if (cv.msgArea) {
				cv.msgArea.style.display = 'none';
			}

			var isOp = window.opera ? true : false;
			var isIe = !isOp && window.attachEvent ? true : false;
			var isSf = navigator.userAgent.indexOf("AppleWebKit")!=-1;
			var isGk = !isIe && !isSf && !isOp && document.addEventListener ? true : false;
			var target = cv.canvas;
			cv.canvasY = 0;
			while(target){
				cv.canvasY += target.offsetTop;
				target = target.offsetParent;
			}
			if (isGk) {
				cv.canvasY += 2*(parseInt(w.getComputedStyle(d.body,'').getPropertyValue("border-top-width").replace('px','')) || 0);
			}
			cv.canvasY -= isIe ? 5 : 1;

			if (location.hash.match(/^#p([0-9]+)$/)) {
				cv.jump(parseInt(RegExp.$1)-1);
			} else {
				cv.loadNum(true);
			}
			for (var i=0; i<d.links.length; i++) {
				var link = d.links[i];
				if (link.href && link.href.match(/#p([0-9]+)$/)) {
					bind(link, 'click', function() {
						if (window.event && event.srcElement && event.srcElement.href.match(/#p([0-9]+)$/)) {
							cv.jump(parseInt(RegExp.$1)-1);
						} else if (this.href.match(/#p([0-9]+)$/)) {
							cv.jump(parseInt(RegExp.$1)-1);
						}
						return false;
					});
				}
			}
		}
		cv.imgs[0].onerror = function() {
			err('最初の画像読み込みに失敗しました。');
		}
		cv.imgs[0].src = cv.list[0];
	});
})();
