/**
 * script.js
 */
(function(window,document){

var
	
	// emulate slow connections for testing
	lag = 0,
	
	// dom handles
	$notice = $('#notice'),
	$content = $('#content'),
	
	// scratch pad for html/text conversion
	$pad = $('<pre></pre>'),
	
	// xhr instance for loading content
	xhr,
	
	// showdown converter
	converter = new Showdown.converter;


/**
 * load the given page.
 */
function load(hash) {
	
	// scroll to top of page
	try {
		$('body').animate({
			scrollTop: 0
		}, 'slow');
	} catch (err) {
		$('body').scrollTop(0);
	}
	
	// attempt to normalize hash
	hash = hash.replace(/^[#\s]+|\s+$/g, '').toLowerCase();
	try {
		hash = decodeURIComponent(hash);
	} catch(err) {
		//console.log(err);
	}
	
	// cancel current load
	cancel();
	
	// set notification that page is loading
	$notice
		.hide()
		.html('<p class="loading">Loading page content ...</p>')
		.show();
	
	// kick off ajax request
	xhr = $.ajax({
		url: "content/" + encodeURIComponent(hash) + ".md",
		complete: function() {
			delete xhr;
		},
		error: function(xhr) {
			error(hash, xhr.status, xhr.statusText);
		},
		success: success
	});
	
}

/**
 * what to do when loading errors out.
 */
function error(pagename, status, statusText) {
	
	setTimeout(function(){
	
	// set notice
	$notice
		.hide()
		.html('<p class="error"></p>')
		.find('p')
			.text('Error loading "' + pagename + '" - ' + status + ' ' + statusText)
			.end()
		.show();
	
	}, lag);
	
}

/**
 * how to turn markdown text into html
 */
function htmlify(text) {
	
	var
		
		rand = Math.random,
		
		pretags = {};
	
	// callback for stripping out preformatted text
	function strip(match, start, content) {
		var key = (rand() + '').replace( /\D/g, '');
		pretags[key] = [start, content];
		return '<!--@PRE@' + key + '@PRE@-->';
	}
	
	// callback for reinserting preformatted text
	function reinsert(match, key) {
		var pair = pretags[key];
		$pad.text(pair[1]);
		return pair[0] + $pad.html() + '</pre>';
	}
	
	// strip tags, make html, then reinsert
	text = text.replace(/(<pre[^>]*>)([\s\S]*?)<\/pre>/g, strip);
	text = converter.makeHtml(text);
	text = text.replace(/<!--@PRE@([^@]+)@PRE@-->/g, reinsert);
	
	// return html
	return text;
	
}

/**
 * what to do when loading the content was successful.
 */
function success(text) {
	
	setTimeout(function(){
	
	// hide notice
	$notice
		.hide();
	
	// show content
	$content
		.hide()
		.html(htmlify(text))
		.show("slow");
	
	// syntax highlighting
	$content
		.find('pre')
			.each(function(elem) {
				SyntaxHighlighter.highlight({}, elem);
			});
	
	// update document title
	var segments = [];
	$('h1')
		.each(function(index, elem) {
			segments.push($(elem).text());
		});
	segments.reverse();
	document.title = segments.join(' : ');
	
	}, lag);
	
}

/**
 * cancel the current load operation.
 */
function cancel() {
	
	if (xhr) {
		
		// hide notice
		$notice
			.hide();
		
		// cancel ajax
		xhr.abort();
		
	}
	
}

$(window).bind('hashchange', function(e){
	
	if (e.fragment) {
		load(e.fragment);
	}
	
});

// for testing, set content explicitly
load(document.location.hash || "index");

// google analytics
window._gaq = [['_setAccount', 'UA-1201880-1'], ['_trackPageview']];
(function(d, t) {
	var
		g = d.createElement(t),
		s = d.getElementsByTagName(t)[0];
	g.async = true;
	g.src = ('https:' === location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	s.parentNode.insertBefore(g, s);
})(document, 'script');

})(window,document);

