(function(){

// *****

function show_string( render, text, font, horizontal, verticle )
{
	var ctx = render.context;
	var width = render.width;
	var height = render.height;

	ctx.save();
	ctx.font = font;

	var tm = ctx.measureText( text );
	var w = tm.width;
	var x;

	if( horizontal == "left" ) {
		x = width / 10;
	} else if( horizontal == "right" ) {
		x = (width * 9 / 10 - w);
	} else {
		x = (width - w) / 2;
	}

	ctx.fillText( text, x, verticle );

	ctx.restore();
}

// *****

function show_image( render, node )
{
	var ctx = render.context;
	var width = render.width;
	var height = render.height;
	var x, y, sw, sh;

	var img = new Image();
	var scale, halign, valign;

	var padding_top = 5;
	var padding_left = 5;
	var padding_bottom = 5;
	var padding_right = 5;

	img.src = node.getAttribute("src") ;

	scale = node.getAttribute("scale");
	halign = node.getAttribute("halign");
	valign = node.getAttribute("valign");

	img.onload = function() {

			if( scale != null ) {
				sw = img.width * scale;
				sh = img.height * scale;
			} else {
				sw = img.width;
				sh = img.height;
			}

			if( halign == "left" ) {
				x = padding_left;
			} else if( halign == "right" ) {
				x = width - sw - padding_right;
			} else {
				x = (width - sw) / 2;
			}

			if( valign == "top" ) {
				y = padding_top;
			} else if( valign == "bottom" ) {
				y = height - sh - padding_bottom;
			} else {
				y = (height - sh) / 2;
			}

			ctx.drawImage( img, x, y, sw, sh );
		}
}

function show_itemize( render, node )
{
	var ctx = render.context;
	var width = render.width;
	var height = render.height;

	var children = node.childNodes;
	var fh = 24;
	var h = 0;

	ctx.save();
	ctx.font = "24px Times New Roman";

	for( i = 0; i < children.length; i++) {

		child = children[i];
		if( child.nodeName == "item" ) {

			if( child.getAttribute("color") != null ) {
				ctx.save();
				ctx.fillStyle = child.getAttribute("color");
			}

			ctx.save();
			ctx.beginPath();
			ctx.arc( width / 5 - fh / 2, height / 4 + h - fh / 3, 5 , 0, Math.PI*2,true);
			ctx.closePath();
			ctx.fillStyle = "grey";
			ctx.fill();
			ctx.restore();

			ctx.fillText( child.textContent, width / 5, height / 4 + h );

			if( child.getAttribute("color") != null ) {
				ctx.restore();
			}

			h += fh + fh / 2;
		}
	}

	ctx.restore();
}

function show_title( render, node )
{
	var ctx = render.context;
	var width = render.width;
	var height = render.height;

	var font;
	var vert = node.getAttribute("verticle");
	var v;

	if( vert == null ) {
		font = "36px Times New Roman";
		v = height / 10;
	} else if( vert == "center" ) {
		font = "64px Times New Roman";
		v = height / 2;
	}

	show_string( render, node.textContent, font, "center", v );
}

function show_header( render, nav )
{
}

function show_footer( render, nav )
{
	var font = "20px Times New Roman";
	var str = (nav.current_page + 1) + "/" + nav.pages.length;
	var verticle = render.height * 19 / 20;

	show_string( render, str, font, "center", verticle );

	if( nav.current_page > 0 ) {
		show_string( render, get_title( nav.pages[nav.current_page - 1] ), font, "left", verticle);
	}

	if( nav.current_page + 1 < nav.pages.length ) {
		show_string( render, get_title( nav.pages[nav.current_page + 1] ), font, "right", verticle);
	}
}

function show_page( render, nav, node )
{
	var ctx = render.context;
	var width = render.width;
	var height = render.height;

	var children = node.childNodes;

	// ctx.save();
	// ctx.fillStyle = "white";
	// ctx.fillRect( 0, 0, width, height );
	// ctx.restore();

	ctx.clearRect( 0, 0, width, height );

	show_header( render, nav );

	for( var i = 0; i < children.length; i++) {

		var name = children[i].nodeName;

		if( name == "title" ) {
			show_title( render, children[i] );
		} else if ( name == "itemize" ) {
			show_itemize( render, children[i] );
		} else if( name == "img" ) {
			show_image( render, children[i] );
		}
	}

	show_footer( render, nav );
}

// *****

function getElementByName( node, name )
{
	var children = node.childNodes;
	var found;

	if( node.nodeName == name ) {
		return node;
	}

	for( var i = 0; i < children.length; i++) {
		if( (found = getElementByName( children[i], name )) != null ) {
			return found;
		}
	}

	return null;
}

function get_title( page )
{
	var title = getElementByName(page, "title");
	return title.textContent;
}

// *****

function init_ui()
{
	document.documentElement.style.overflow = "hidden";
}

function init_event( nav )
{

	function onKeypress( event )
	{
		var char = event.charCode;
		var key = event.keyCode;

		switch( char ) {
			case 0x20:
				nav.show_next_page();
				break;
		};

		switch( key ) {
			case 35:
				nav.show_last_page();
				break;
			case 36:
				nav.show_first_page();
				break;
			case 33:
			case 37:
			case 38:
				nav.show_prev_page();
				break;
			case 34:
			case 39:
			case 40:
				nav.show_next_page();
				break;
		};
	}

	function onResize()
	{
		nav.update_size();
	}

	function onClick( event )
	{
		nav.show_next_page();
	}

	function onWheel( event )
	{
		if( event.detail > 0 ) {
			nav.show_next_page();
		} else {
			nav.show_prev_page();
		}
	}

	window.addEventListener( 'keypress', onKeypress, false );
	window.addEventListener( 'resize', onResize, false );

	window.addEventListener( 'click', onClick, false );
	window.addEventListener( 'DOMMouseScroll', onWheel, false);
}

function load_page( request )
{
	var doc = request.responseXML;
	var slide = doc.childNodes[0];
	var children = slide.childNodes;
	var pages = new Array();

	for( var i = 0; i < children.length; i++) {
		if( children[i].nodeName == "page" ) {
			pages.push( children[i] );
		}
	}

	// alert( "Total " + pages.length + " pages" );

	return pages;
}

function init_canvas( nav )
{
	var cv = document.getElementById("cv");
	var ctx = cv.getContext("2d");

	if( !ctx.measureText ) {

		function fontSize()
		{
			var i = ctx.font.indexOf("px");
			return ctx.font.substr( 0, i );
		}

		function TextMetrics( text ) {
			this.width = fontSize() / 2 * text.length;
		}

		ctx.measureText = function( text ) {
				return new TextMetrics( text );
			}

	}

	if( !ctx.fillText ) {
		ctx.fillText = function( text, x, y ) {
				ctx.fillRect( x, y, ctx.measureText(text).width, 10 );
			}
	}

	cv.width = document.documentElement.clientWidth;
	cv.height = document.documentElement.clientHeight;

	nav.url = cv.getAttribute("src");
	nav.render = { context: ctx, width: cv.width, height: cv.height };
}

function init_request( nav )
{
	var request = new XMLHttpRequest();
	request.onreadystatechange = function() {
		if( request.readyState == 4 ) {
			nav.pages = load_page(request);
			nav.refresh();
		}
	};
	request.open("GET", nav.url, true);
	request.send("");
}

function navigator()
{
	this.current_page = 0;

	this.update_size = function()
	{
		var cv = document.getElementById("cv");

		cv.width = this.render.width = document.documentElement.clientWidth;
		cv.height = this.render.height = document.documentElement.clientHeight;

		this.refresh();
	}

	this.get_page = function(index)
	{
		return this.pages[index];
	}

	this.refresh = function()
	{
		if( this.pages == undefined )
			return;

		show_page( this.render, this, this.pages[this.current_page] );
	}

	this.show_next_page = function()
	{
		if( this.pages == undefined )
			return;

		if( this.current_page + 1 < this.pages.length )
			show_page( this.render, this, this.pages[++this.current_page] );
	}

	this.show_prev_page = function()
	{
		if( this.pages == undefined )
			return;

		if( this.current_page > 0 ) 
			show_page( this.render, this, this.pages[--this.current_page] );
	}

	this.show_first_page = function()
	{
		if( this.pages == undefined )
			return;

		this.current_page = 0;
		show_page( this.render, this, this.pages[this.current_page] );
	}

	this.show_last_page = function()
	{
		if( this.pages == undefined )
			return;

		this.current_page = this.pages.length - 1;
		show_page( this.render, this, this.pages[this.current_page] );
	}

	// get canvas context, width, height, url
	init_canvas( this );

	// get page content and show
	init_request( this );

	init_ui();

	// handle resize, keypress, mouse event
	init_event( this );

}

new navigator();

})();
