// ==UserScript==

// @name					 naist_schedule

// @namespace			http://emaame.com/

// @description		NAIST の授業日程表をキーボードナビゲーション

// @include				https://is-education.naist.jp/ScheduleSys/*

// ==/UserScript==*/

( function( ) {
	function isBackKey( code ) { return code== 8 || code==37 || code==75; } // BS	 , ←, K
	function isNextKey( code ) { return code==32 || code==39 || code==74; } // SPACE, →, J

	// from Prototype.js 1.5.1.1
	function observe(element, name, observer, useCapture) {
		if (element.addEventListener) {
			element.addEventListener(name, observer, useCapture);
		} else if (element.attachEvent) {
			element.attachEvent('on' + name, observer);
		}
	}

	function scrollTo(element) {
		var pos = cumulativeOffset(element);
		window.scrollTo(pos[0], pos[1]);
		return element;
	}
	function cumulativeOffset(element) {
		var valueT = 0, valueL = 0;
		do {
			valueT += element.offsetTop	|| 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
		} while (element);
		return _returnOffset(valueL, valueT);
	}
	function _returnOffset(l, t) {
		var result = [l, t];
		result.left = l;
		result.top  = t;
		return result;
	}

	// from http://yamanoue.sakura.ne.jp/blog/coding/68
	function xpath(query) {
		var results = document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
		var nodes = new Array();
		for(var i=0; i<results.snapshotLength; i++){
			nodes.push(results.snapshotItem(i));
		}
		return nodes;
	}
	
	var seps  = xpath("//table//table//table//td[@colspan=6]");
	var dates = [];
	var date  = 1;

	function searchNextHeaderTr( tr ) {
		var target = tr;
		while( target ) {
			if ( !(target.nextSibling            ) ) { return null; }
			if ( !(target.nextSibling.nextSibling) ) { return null; }
			target = target.nextSibling.nextSibling;
			var td = target.childNodes[1];
			if ( !td ) { return null; }
			if ( td.rowSpan && td.id=="" ) { return target; }
		}
		return null;
	}


	var ttList = {
		"1限目":"09:20",
		"2限目":"11:00",
		"3限目":"13:30",
		"4限目":"15:10",
		"5限目":"16:50",
		"6限目":"18:30"
	};

	function init( ) {
		for(var i=0; i<seps.length; ++i) {
			var tr = seps[i].parentNode.nextSibling.nextSibling;
			var td = tr.childNodes[1];
			dates.push( { form: td.childNodes[3], tr: tr, td: td } );
		}
		var next_tr = dates[0].tr;

		do {
			var tds = next_tr.childNodes;
			for(var j=0; j<tds.length; ++j) {
				var text = tds[j].textContent.replace(/\s+/g,"");
				if (ttList[text]) {
					tds[j].textContent = ttList[text];
				}
			}
		} while( next_tr = searchNextHeaderTr(next_tr) );
		moveDate( );
	}

	

	function moveDate( diff ) {
		date = (date + diff) || (new Date()).getDate();
		if (date<1) { date=1; } if (date>dates.length) { date=dates.length; }

		scrollTo(dates[date-1].td);
	}
	
	function keydownHandler( event ) {
		event = event || window.event;
		var code = event.keyCode || event.charCode;
		
		if ( isBackKey( code ) ) { moveDate(-1); }
		if ( isNextKey( code ) ) { moveDate( 1); }
	}
	
	observe( window, 'keydown', keydownHandler );
	observe( window, 'load'   , init );
} )( );

