// ==UserScript==
// @name           Mymixi Latest Diaries Pager
// @namespace      http://libelabo.jp/
// @description    This script add 'prev' and 'next' links in mymixi's diary page
// @include        http://mixi.jp/view_diary.pl*
// @version        0.6
// ==/UserScript==

(function() {

	/* Set your favorite key */
	var nextLinkKey = ['n', 'k', 'right'];
	var prevLinkKey = ['p', 'j', 'left'];
	var openExtLinkKey = ['v', 'o'];

	function waiting_img() {
		var img = document.createElement('img');
		var data = 'data:image/gif;base64,'+
			'R0lGODlhKwALAPEAAP////ikSPvSpfikSCH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5'+
		    'BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAKwALAAACMoSOCMuW2diD88UKG95W88uF4DaG'+
    		'WFmhZid93pq+pwxnLUnXh8ou+sSz+T64oCAyTBUAACH5BAAKAAEALAAAAAArAAsAAAI9xI4IyyAP'+
    		'YWOxmoTHrHzzmGHe94xkmJifyqFKQ0pwLLgHa82xrekkDrIBZRQab1jyfY7KTtPimixiUsevAAAh'+
    		'+QQACgACACwAAAAAKwALAAACPYSOCMswD2FjqZpqW9xv4g8KE7d54XmMpNSgqLoOpgvC60xjNonn'+
    		'yc7p+VKamKw1zDCMR8rp8pksYlKorgAAIfkEAAoAAwAsAAAAACsACwAAAkCEjgjLltnYmJS6Bxt+'+
    		'sfq5ZUyoNJ9HHlEqdCfFrqn7DrE2m7Wdj/2y45FkQ13t5itKdshFExC8YCLOEBX6AhQAADsAAAAA'+
    		'AAAAAAA=';
		img.src = data;
		img.setAttribute("style", "margin:auto; display: block");
		return img;
	}

	function NaviBar() {
		var bar = document.createElement('div');
		bar.setAttribute('class', 'navi_bar');
		bar.setAttribute('style', 'height: 1.5em;  padding: 5px 0px;');
		bar.appendChild(waiting_img());
		return bar;
	}

	function insertLatestDiariesPager() {
		GM_xmlhttpRequest({
		method: "GET",
		url: location.href.indexOf("comment_count")  == -1 ? "http://mixi.jp/new_friend_diary.pl" : "http://mixi.jp/new_comment.pl",
		onload: function(details) {
			var res = document.createElement('div');
			res.innerHTML = details.responseText;

			var prevLink;
			var nextLink;

			var latestDiaryLinks = document.evaluate('.//a[contains(@href, "view_diary")]', res, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			for(var i=0; i<latestDiaryLinks.snapshotLength; i++) {
				var link = latestDiaryLinks.snapshotItem(i);
				if(location.href == link.href) {
					prevLink = latestDiaryLinks.snapshotItem(i+1) ? latestDiaryLinks.snapshotItem(i+1) : null;
					nextLink = latestDiaryLinks.snapshotItem(i-1) ? latestDiaryLinks.snapshotItem(i-1) : null;
				}
			}

			var naviBars = document.evaluate("//div[@class='navi_bar']", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			for(var i=0; i<naviBars.snapshotLength; i++) {
				var naviBar = naviBars.snapshotItem(i);
				naviBar.removeChild(naviBar.firstChild);

				if(prevLink) {
					var prevImg = document.createElement('img');
					prevImg.setAttribute('src', 'http://img.mixi.jp/img/arw3-.gif');
					prevImg.setAttribute('style', 'vertical-align: middle; margin-right: 4');
					var barLeft  = document.createElement('div');
					barLeft.setAttribute('style', 'width: 49%; text-align: left; float: left');
					barLeft.appendChild(prevImg);
					barLeft.appendChild(prevLink.cloneNode(true));
					barLeft.appendChild(prevLink.nextSibling.cloneNode(true));
					naviBar.appendChild(barLeft);

					Keybind.add(prevLinkKey, function(){ location.href = prevLink.href });
				}

				if(nextLink) {
					var nextImg = document.createElement('img');
					nextImg.setAttribute('src', 'http://img.mixi.jp/img/arw4-.gif');
					nextImg.setAttribute('style', 'vertical-align: middle; margin-left: 4');
					var barRight = document.createElement('div');
					barRight.setAttribute('style', 'width: 49%; text-align: right; float: right');
					barRight.appendChild(nextLink.cloneNode(true));
					barRight.appendChild(nextLink.nextSibling.cloneNode(true));
					barRight.appendChild(nextImg);
					naviBar.appendChild(barRight);

					Keybind.add(nextLinkKey, function(){ location.href = nextLink.href });
				}
			}
		}
	});
	}

	var Keybind = {
		add:function(phrase, func){
		document.addEventListener("keydown", 
			function(event){
				var target = event.target;
				var tagName = target.tagName;
				var type = target.type;
				for(var i=0; i<phrase.length; i++) {
					if(phrase[i] == Keybind.code(event) &&
						!(tagName == "INPUT" && (!type.type || type=="text")) &&
						tagName != "TEXTAREA"){
							func();
					}
				}
			},
			true);
		},

		code: function(event){
			var code = [];
			if(event.shiftKey){
				code.push("S");
			} else if(event.ctrlKey){
				code.push("C");
			} else if(event.altKey){
				code.push("M");
			}
			code.push(Keybind.kc2char(event.keyCode));
			return code.join("-");
		},

		kc2char:function(kc){
			var between = function(a,b){
				return a <= kc && kc <= b;
			};

			var _32_40 = "space pageup pagedown end home left up right down".split(" ");
			var kt = {
				8  : "back",
				9  : "tab"  ,
				13 : "enter",
				16 : "shift",
				17 : "ctrl",
				27 : "esc",
				46 : "delete",
			};

			return (
				between(65,90)  ? String.fromCharCode(kc+32) : // a-z
				between(48,57)  ? String.fromCharCode(kc) :	// 0-9
				between(96,105) ? String.fromCharCode(kc-48) : // num 0-9
				between(32,40)  ? _32_40[kc-32] :
				kt.hasOwnProperty(kc) ? kt[kc] : 
				kc
			);
		}
	};

	if(/^http:\/\/mixi\.jp\/view_diary\.pl\?url=/.test(location.href)) {
		Keybind.add(openExtLinkKey,
			function() {
				var extLink = document.evaluate("//a[1][@target='_blank']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
				if(extLink) {
					window.open(extLink.href, "_blank");
				}
			});
	}
	var contentsBoxes = document.evaluate('(//div[contains(@class,"diaryPaging01")] | //div[@id="diaryComment"] | //div[contains(@class,"diaryMainArea02")][2] | //div[@class="messageArea"])', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var navis = [];
	for(var i=0; i<contentsBoxes.snapshotLength; i++) {
		var contentsBox = contentsBoxes.snapshotItem(i);
		contentsBox.setAttribute('style', 'clear: both');
		var naviBar = new NaviBar();
		contentsBox.parentNode.insertBefore(naviBar, contentsBox);
	}
	insertLatestDiariesPager();

})();
