/*------------------------------------------------------------------------------
	Copyright (C) 2008 Yuji OKAMURA, All rights reserved.
------------------------------------------------------------------------------*/
function ShortcutKey(root) {
	var	thisShortcutKey = this;

	if (root == undefined || root == null) {
		this.SetRoot($(document));
	}
	else {
		this.SetRoot($(root));
	}

	this.root.find('input[type=text]').focus(function() {
		thisShortcutKey.isInTextField = true;
	}).blur(function() {
		thisShortcutKey.isInTextField = false;
	});
	this.root.find('input[type=file]').focus(function() {
		thisShortcutKey.isInTextField = true;
	}).blur(function() {
		thisShortcutKey.isInTextField = false;
	});
	this.root.find('textarea').focus(function() {
		thisShortcutKey.isInTextField = true;
	}).blur(function() {
		thisShortcutKey.isInTextField = false;
	});
};

ShortcutKey.prototype.AssignProps = [
	'PrevArticle', 'NextArticle',
	'PrevPage', 'NextPage',
	'ArticlePage' ,'UpperPage'
];
ShortcutKey.prototype.AssignOptions = [
	'altKey', 'ctrlKey', 'shiftKey'
];

ShortcutKey.prototype.root = null;
ShortcutKey.prototype.articles = [];
ShortcutKey.prototype.currentArticleIndex = null;
ShortcutKey.prototype.prevPage = null;
ShortcutKey.prototype.upperPage = null;
ShortcutKey.prototype.nextPage = null;
ShortcutKey.prototype.isInTextField = false;
ShortcutKey.prototype.marginleft = -16;
ShortcutKey.prototype.marginTop = -40;
ShortcutKey.prototype.keyAssign = {
	'PrevArticle':	[75, 107],	// K, k
	'NextArticle':	[74, 106],	// J, j
	'PrevPage':		[72, 104],	// h, H
	'NextPage': 	[76, 108],	// l, L
	'ArticlePage':	[79, 111],	// O, o
	'UpperPage':	[85, 117]	// U, u
};
ShortcutKey.prototype.CookieName = 'ShortcutKeyAssign';
ShortcutKey.prototype.CookieSpec = {
	path:	'/yuji_okamura/DotMac/t',
	domain:	'homepage.mac.com',
	'max-age':	60*60*24*365
};

ShortcutKey.prototype.SetRoot = function(root) {
	this.root = root;
	this.articles = root.find('div.blogbody');
	this.currentArticleIndex = null;
	$.each(this.articles, function() {
		$(this).focus(function() {
			$(this).addClass('current');
		});
		$(this).blur(function() {
			$(this).removeClass('current');
		});
	});
	{
		var	pages = root.find('p.backAndForward > a[href]');

		switch (pages.length) {
		case 0:
			break;
		case 1:
			this.upperPage = $(pages[0]).attr('href');
			break;
		case 2:
			if ($(pages[0]).text() == 'Main') {
				this.upperPage = $(pages[0]).attr('href');
				this.nextPage = $(pages[1]).attr('href');
			}
			else {
				this.prevPage = $(pages[0]).attr('href');
				this.upperPage = $(pages[1]).attr('href');
			}
			break;
		case 3:
			this.prevPage = $(pages[0]).attr('href');
			this.upperPage = $(pages[1]).attr('href');
			this.nextPage = $(pages[2]).attr('href');
			break;
		}
	}
};

ShortcutKey.prototype.SetCurrentArticle = function(nth) {
	var	offsetLeft = this.marginLeft;
	var	offsetTop = this.marginTop;

	if (nth < 0 || this.articles.length <= nth) {
		return;
	}

	if (this.currentArticleIndex != null) {
		$(this.articles[this.currentArticleIndex]).blur();
	}
	
	try {
		var	cur = this.articles[nth];

		do {
			if (cur.offsetLeft && cur.offsetTop) {
				offsetLeft += cur.offsetLeft;
				offsetTop += cur.offsetTop;
			}
			cur = cur.offsetParent;
		} while (cur);
	}
	catch (e) {
	}
	window.scroll(offsetLeft, offsetTop);
	$(this.articles[nth]).focus();
	this.currentArticleIndex = nth;
};

ShortcutKey.prototype.NextArticle = function() {
	if (this.currentArticleIndex == null) {
		this.SetCurrentArticle(0);
	}
	else {
		this.SetCurrentArticle(this.currentArticleIndex + 1);
	}
};

ShortcutKey.prototype.PrevArticle = function() {
	if (this.currentArticleIndex == null) {
		this.SetCurrentArticle(this.articles.length - 1);
	}
	else {
		this.SetCurrentArticle(this.currentArticleIndex - 1);
	}
};

ShortcutKey.prototype.PrevPage = function() {
	if (!this.prevPage) {
		return;
	}

	window.location.href = this.prevPage;
};

ShortcutKey.prototype.UpperPage = function() {
	if (!this.upperPage) {
		return;
	}

	window.location.href = this.upperPage;
};

ShortcutKey.prototype.NextPage = function() {
	if (!this.nextPage) {
		return;
	}

	window.location.href = this.nextPage;
};

ShortcutKey.prototype.ArticlePage = function() {
	var	url;

	if (this.currentArticleIndex == null) {
		return;
	}

	url = $(this.articles[this.currentArticleIndex]).find(
		'ul.posted a[title="permanent link"]'
	).attr('href');
	if (url) {
		window.location.href = url;
	}
};

ShortcutKey.prototype.KeyEventHandler = function(event) {
	if (
		this.isInTextField
		|| event.ctrKey || event.altKey || event.metaKey
	) {
		return true;
	}

	for (var funcName in this.keyAssign) {
		for (var i = 0; i < this.keyAssign[funcName].length; i++) {
			if (
				this.keyAssign[funcName][i] == event.keyCode
				|| this.keyAssign[funcName][i] == event.charCode
			) {
				break;
			}
		}
		
		if (i < this.keyAssign[funcName].length) {
			this[funcName]();
			return true;
		}
	}

	return true;
};

ShortcutKey.prototype.LoadKeyAssign = function() {
	if (!window.document.cookie) {
		return true;
	}

	var	newAssign = {};

	{
		var	strProps;
		
		{
			var	strAssign = null;
		
			{
				var	cookies = document.cookie.split(';');
		
				for (var i = 0; i < cookies.length; i++) {
					var	pair = cookies[i].split('=', 2);
			
					if (pair[0] == this.CookieName) {
						strAssign = decodeURIComponent(pair[1]);
						break;
					}
				}
			}
		
			if (strAssign == null) {
				return true;
			}
		
			strProps = strAssign.split(';');
		}
	
		if (strProps.length != this.AssignProps.length) {
			return false;
		}
		
		for (var i = 0; i < strProps.length; i++) {
			var	codes = strProps[i].split(',');
			var	propName = this.AssignProps[i];
			
			for (var j = 0; j < codes.length; j++) {
				if (!codes[j].match(/^\d+$/)) {
					return false;
				}
				codes[j] = parseInt(codes[j]);
				if (codes[j] < 0 || 255 < codes[j]) {
					return false;
				}
			}
			newAssign[propName] = codes;
		}
	}

	this.keyAssign = newAssign;
	return true;
};

ShortcutKey.prototype.SaveKeyAssign = function() {
	var	cookie;
	
	{
		var	specs = [];
	
		for (var i = 0; i < this.AssignProps.length; i++) {
			var	propName = this.AssignProps[i];
			var	codes = [];
			
			for (var j = 0; j < this.keyAssign[propName].length; j++) {
				codes.push(this.keyAssign[propName][j].toString());
			}
			
			specs.push(codes.join(','));
		}
	
		cookie = this.CookieName + '=' + encodeURIComponent(specs.join(';'));
	}

	for (var cookieSpecName in this.CookieSpec) {
		cookie += ';' + cookieSpecName + '=' + this.CookieSpec[cookieSpecName];
	}

	window.document.cookie = cookie;
};
