function _log(msg) { console.log(msg) }
function position(curr,add) {
	if (!curr) curr = $('.selected');
	if (!add) add = 0;
	var s = $('div.slide');
	var c = $(curr)[0];
	for( var i=0;i<s.length;i++ ) {
		if ( i+add >=0 && i+add < s.length && s[i] == c ) {
			curr = $(s[i+add]); 
			// _log( 'set current to ' + (i+add));
			$('.pageno').html( (i+add+1) + '/' + s.length );
			$('.percent').html( Math.round( (i+add +1)*100/s.length) + ' %');
			break;
		}
	}

	if ( curr.length ) {
		// scroll into if necessary
		$('.selected').removeClass('selected');
		$(curr).addClass('selected');
		if ( ! checkvisible(curr)['full']) makevisible(curr);
	}

	if (add>0) {
		// reset incremental
		$(curr).find('.incremental-shown').removeClass('incremental-shown').addClass('incremental-hidden');
		$(curr).find('.incremental-current').removeClass('incremental-current').addClass('incremental-hidden');
		nextInc();
	} else if (add<0) {
		// make all visible
		$(curr).find('.incremental-hidden').removeClass('incremental-hidden').addClass('incremental-shown');
		$(curr).find('.incremental-current').removeClass('incremental-current').addClass('incremental-shown');
	} else {
		if ( ! $(curr).find('.incremental-shown').length 
			&& ! $(curr).find('.incremental-current').length )
			nextInc();
	}
}

function checkvisible(elm) {
	var vpH = $(window).height(), // Viewport Height
		st = $(window).scrollTop(), // Scroll Top
		ytop = $(elm).offset().top,
		ybot = ytop + $(elm).height();

	var vtop = (ytop >= st && ytop<= st+vpH) ? 1:0;
	var vbot = (ybot >= st && ybot<= st+vpH) ? 1:0;
	var vany = (ytop+10 < st+vpH && ybot-10 > st) ? 1:0;
	return { any: vany, bottom: vbot, top: vtop, full: vbot && vtop }; 
}   

function makevisible(elm) {
	$(document).scrollTop($(elm).offset().top);
}  

function nextInc() {
	if ( $('div.slide:visible').length>1 ) return false;
	$('.incremental-current').removeClass('incremental-current').addClass('incremental-shown');
	var ic = $('.selected .incremental-hidden');
	if(ic.length) {
		$(ic[0]).removeClass('incremental-hidden').addClass('incremental-current');
		return true;
	}
	return false;
}

function prevInc() {
	if ( $('div.slide:visible').length>1 ) return false;
	var c = $('div.slide#selected');
	$('.incremental-current').removeClass('incremental-current').addClass('incremental-hidden');
	var ic = $('.selected .incremental-shown');
	if(ic.length) {
		$(ic[ic.length-1]).removeClass('incremental-shown').addClass('incremental-current');
		return true;
	}
	return false;
}



var intoc = false;
function showtoc() {
	// fill toc
	if ( ! $('#toc').length ) return;
	if ( ! $('#toc').is(':visible')) switch_style('Presentation');
	var s = $('div.slide');
	var toc = '';
	for( var i=0;i<s.length;i++ ) {
		var h1 = $(s[i]).find('h1');
		if (!h1.length) continue;
		var clsel = $(s[i]).hasClass('selected') ? ' toc-item-selected':'';
		var hx = $(h1).attr('class').match(/\bh[1234]\b/);
		toc += "<a href='#' class='toc-item " + hx
			+ clsel + "' id='toc-item-" + i + "'>" + h1.html() + "</a>";
	}
	$('#toc').html(toc);
	$('#layout').hide();
	$('.selected').removeClass('selected');

	intoc = true;
	$('.toc-item').click( function() {
		var i = $(this).attr('id').substr(9);
		$('#toc').html('');
		$('#layout').show();
		intoc = false;
		position($('div.slide:eq(' + i + ')'));
		return false;
	});

	$(document).scrollTop($('.toc-item-selected').offset().top -50 );
}

$('document').ready(function() {

	function xposition(curr,add) {
		if (!intoc || curr) return position(curr,add);
		var s = $('.toc-item');
		var c = $('.toc-item-selected');
		var curr;
		for( var i=0;i<s.length;i++ ) {
			if ( i+add >=0 && i+add < s.length && s[i] == c[0] ) {
				curr = $(s[i+add]);
				break;
			}
		}
		if (curr) {
			c.removeClass('toc-item-selected');
			curr.addClass('toc-item-selected');
			var rpos = curr.offset().top - $(window).scrollTop();
			if (rpos < 0 || rpos > $(window).height()-20)
				$(document).scrollTop(curr.offset().top);
		}
	}

	// collect stylesheets
	var styles = [];
	$('link').each( function(i,e) {
		if ($(e).attr('rel').indexOf('style')>=0 
			&& $(e).attr('media').indexOf('screen')>=0) {
			if ( $(e).attr('disabled'))
				styles.push(e);
			else
				styles.unshift(e);
		}
	});

	
	function switch_style(name) {
		for( var i=0;i<styles.length;i++ ) {
			if ( $(styles[i]).attr('title') == name ) {
				if ( i == 0 ) return; // already activ
				styles[0].disabled = true;
				for( var j=0;j<i;j++ ) {
					styles.push(styles.shift());
				}
				styles[0].disabled = false;
				position();
			}
		}
	}

	$(document).bind('keydown',function (ev){
		if (ev.metaKey || ev.ctrlKey || ev.altKey) 
			// let the browser handle keys itself
			return true;

		if ( ev.which == 74 || ev.which == 40 || ev.which == 34 || ev.which == 32) {
			// [J],[cursor down],[page down],[space]
			if ( intoc || ! nextInc()) xposition( null,+1 );
		} else if ( ev.which == 75 || ev.which == 38 || ev.which == 33) {
			// [K],[cursor up],[page up]
			if ( intoc || ! prevInc()) xposition( null,-1 );
		} else if ( ev.which == 78 || ev.which == 39) {
			// [N],[cursor right]
			if (intoc) return true;
			xposition( null,+1 );
		} else if ( ev.which == 85 || ev.which == 37 ) {
			// [U],[cursor left]
			if (intoc) return true;
			xposition( null,-1 );
		} else if ( intoc && ( ev.which == 13 || ev.which == 84 || ev.which == 27 || ev.which == 116 )) {
			// [T]|[Return][Escape] -> switch to slide view again
			var i = $('.toc-item-selected').attr('id').substr(9);
			$('#toc').html('');
			$('#layout').show();
			intoc = false;
			position($('div.slide:eq(' + i + ')'));
		} else if ( ! intoc && ( ev.which == 84 || ev.which == 27 || ev.which == 116 )) {
			// [T][Escape] -> switch to toc
			showtoc();
		} else if ( ev.which == 83 || ev.which == 190 ) {
			// [S]tyle, Keycode 190
			if (styles.length <=1) return;
			styles[0].disabled = true;
			styles.push(styles.shift());
			styles[0].disabled = false;
			position();
		} else if ( ev.which == 79 && ! intoc ) {
			// [O]utline
			if ( $(styles[0]).attr('title' ) == 'Outline' )
				switch_style('Presentation');
			else
				switch_style('Outline');

		} else {
			// _log('got key '+ev.which );
			return true;
		}
		return false; // stopPropagation, preventDefault
	});

	if(0) {
		// from outline to presentation on doubleclick
		$('div.slide').dblclick(function(ev) {
			if ( $('div.slide:visible').length>1 ) {
				// outline view or similar
				position($(this));
				switch_style('Presentation');
				return false;
			}
		});
		$('div.slide').bind('contextmenu', function(ev) { return false });
		$('div.slide').bind('mousedown', function(ev) {
			if ( $('div.slide:visible').length>1 ) {
				// outline view or similar
				position($(this));
				return false;
			} else if ( ev.which == 1 ) {
				// goto next
				if ( ! nextInc()) xposition(null,+1);
				return false;
			} else if ( ev.which == 3 ) {
				// goto prev
				if ( ! prevInc()) xposition(null,-1);
				return false;
			}
			return true;
		});
	}

	// incremental - make a li below .incremental hidden
	$('.incremental > li').addClass('incremental-hidden');
	$('li.plus').addClass('incremental-hidden');

	// add bgimage, thimage to each slide
	var img = $('#thimage').attr('src');
	if(img)
		$('div.slide').append( '<img class="thimage" src="' + img + '">');
	if (img = $('#bgimage').attr('src')) 
		$('div.slide').append( '<img class="bgimage" src="' + img + '">');

	// add percent+pageno to each subtitle
	$('.subtitle').append(
		'<div class="percent" style="display:none"></div>' +
		'<div class="pageno" style="display:none"></div>'
	);

	// add upper header to each slide
	{
		var uph = [];
		$('.slide').each( function(i,e) {
			var h1 = $(e).find('h1');
			if (!h1.length) return;
			var h = $(h1[0]).attr('class').match(/\bh[1234]\b/);
			if(!h.length) return;
			var level = h[0].substr(1);
			uph[level] = h1[0];
			var up = level>1 ? $(uph[level-1]).html() : '';
			$(e).prepend( '<div class="uph" style="display:none">' + up + '</div>' );
		});
	}


	// initial position can be specific page
	var h = location.hash;
	if ( h && h.length && $(h).length ) {
		location.hash = '';
		position(h); // jump to this position
	} else {
		if ($('div.slide#title').length) 
			position('div.slide#title');
		else
			position('div.slide:first');
	}
});
