/**
 * Ajax Page Loading
 * By Weston Ruter
 * Copyright 2010. Shepherd Interactive, LLC.  All Rights Reserved.
 * $Id: ajax-loading.js 657 2010-03-23 17:22:36Z weston $
 */

(function(window, document, $, undefined){

var ajax = window.AjaxLoading = {
	initialized:false,
	//allowedURIs:[],
	disallowedURIRegExp:null,
	hashchangeTimerInterval:100,
	stateKey: "ajaxloading",
	updateTitle: true,
	debug:false,
	blankURL:"about:blank",
	initialSlash:false,
	enabled:true
};

var divsForSWFObject = [];

/**
 * If true, then we'll be storing our location in an iframe
 */
var isOldIE = (window.ActiveXObject && /MSIE [1-7]\b/.test(navigator.userAgent));

/**
 * Initialize the 
 */
ajax.init = function(){
	try {
		if(ajax.initialized)
			return;
		ajax.land();
		ajax.initialized = true;
		
		//If not enabled, we're done
		if(!ajax.isEnabled())
			return;
		
		ajax.enable();
	}
	catch(err){
		if(ajax.debug)
			throw err;
		else
			ajax.disable();
	}
}

/**
 * This function gets called as soon as possible to redirect Ajax/non-Ajax state
 * based on whether AjaxLoading is enabled or not enabled respectively.
 * This function is also called whenever Ajax Loading is enabled or disabled.
 * @returns {boolean} True if the page is already landed, or false if it has to do a redirect
 */
ajax.land = function(){
	//Get the current URI and detect if Ajax is requested
	var isAjax = false;
	var uri = window.location.pathname;
	if(uri == '/'){
		uri = alwaysinitialshashit(location.hash.substr(1)); //.replace(/\?.*/, '');
		isAjax = true;
	}
	
	var isAjaxable = !ajax.disallowedURIRegExp || !ajax.disallowedURIRegExp.test(uri);
	
	var enabled = AjaxLoading.isEnabled();
	if(uri != '/'){
		//PROBLEM: body isn't found yet! SWFObject fails
		if(isAjaxable && enabled && !isAjax){
			location.replace("/#" + maybeinitialshashit(uri));
			return false;
		}
		else if(!enabled && isAjax) {
			location.replace(uri);
			return false;
		}
		else if(isAjax && !isAjaxable) {
			location.replace(uri);
			return false;
		}
	}
	return true;
}


/**
 * Detect if Ajax Loading is enabled based on stored cookie preference
 */
ajax.isEnabled = function(){
	//if(window.sessionStorage)
	//	return window.sessionStorage[stateKey] === false;
	//else
	if(!ajax.enabled || document.cookie.indexOf(ajax.stateKey+'=0') != -1)
		return false;
	//return /*ajax.enabled &&*/ document.cookie.indexOf(ajax.stateKey+'=0') == -1;
	return true;
};

//var ieHistoryDoc;
var ieHistoryIframe;


/**
 * Change the loaded page
 */
ajax.navigate = function(uri){
	if(ajax.disallowedURIRegExp && ajax.disallowedURIRegExp.test(uri)){
		window.location = uri;
	}
	else {
		updateLocationHash(maybeinitialshashit(uri));
	}
}


/**
 * Update the location.hash
 */
function updateLocationHash(newHash){
	window.location.hash = "#" + newHash;
	
	//Push the new state onto the iframe
	if(ieHistoryIframe){
		var newSrc = ieHistoryIframe.contentWindow.location.href.replace(/\?.*/, '') + '?' + newHash;
		if(newSrc != ieHistoryIframe.src)
			ieHistoryIframe.src = newSrc;
	}
}


/**
 * Click handler for links in the page via event delegation
 */
function link_onclick(e){
	
	// Abort if target is set
	if(e.target.target && e.target.target != "_self")
		return;
	
	// Only use href if it is for the same domain
	var index;
	if(e.target.href && (index = e.target.href.indexOf('//'+location.host)) != -1){
		var uri = e.target.href.substr(index + 2 + window.location.host.length);
		
		// Only use href if it is allowed
		if(!ajax.disallowedURIRegExp || !ajax.disallowedURIRegExp.test(uri)){
			//location.hash = "#" + uri.substr(1);
			updateLocationHash(maybeinitialshashit(uri));
			e.preventDefault();
		}
	}
}

/**
 * Timer for the interval which montors the hash
 */
var hashchangeTimerID;


/**
 * Hash change handler; this will get called at least once
 * @param {Object} e Event object if invoked as hashchange
 * @private
 */
var previousHash = window.location.hash;
function onhashchange(e){
	//Defer to native hashchange event
	if(!e)
		e = window.event;
	if(hashchangeTimerID && e && e.type.indexOf('hashchange') != -1){
		clearInterval(hashchangeTimerID);
		hashchangeTimerID = null;
	}
	
	//Stop if we've already handled this
	if(previousHash == window.location.hash)
		return;
	_previousHash = previousHash;
	previousHash = window.location.hash;
	
	var uri = ajax.getURI();
	var uriHashParts = maybeinitialshashit(uri).split(/#/, 2);
	
	//Check to see if the change is merely in the anchor target
	if(_previousHash.substr(1).split(/#/, 2)[0] == uriHashParts[0]){
		var target = document.getElementById(uriHashParts[1]);
		if(target){
			if(target.scrollIntoView)
				target.scrollIntoView();
		}
		//If new hash is empty, scroll to top
		else {
			window.scrollTo(0,0);
		}
		return;
	}
	
	//Change the page if not allowed, or otherwise load via Ajax
	if(ajax.disallowedURIRegExp && ajax.disallowedURIRegExp.test(uri)){
		window.location.replace(uri);
	}
	else {
		ajax.load(uri);
	}
}



/**
 * Enable Ajax Loading
 */
ajax.enable = function(){
	document.cookie = ajax.stateKey+'=1; path=/';
	ajax.enabled = true;
	
	if(ajax.land()){
		//Start loading the content for the other page right now and then populate
		// the page with its content
		var uri = ajax.getURI();
		if(uri != window.location.pathname){
			ajax.load(ajax.getURI(uri));
		}
		
		/**
		 * Monitor the location hash for changes; if a native 'hashchange' handler
		 * gets called, then this interval timer will be cleared.
		 */
		var intervalPreviousHash = window.location.hash;
		function checkHashchange(){
			if(intervalPreviousHash != window.location.hash){
				intervalPreviousHash = window.location.hash;
				onhashchange();
			}
		}
		
		//Start monitoring the location.hash for changes
		hashchangeTimerID = setInterval(checkHashchange, ajax.hashchangeTimerInterval);
		try {
			if(window.addEventListener)
				window.addEventListener('hashchange', onhashchange, false);
			else if(window.attachEvent)
				window.attachEvent('onhashchange', onhashchange);
		}
		catch(e){}
		
		//Watch for click events
		$("a").live('click', link_onclick);
		
		//Create iframe for MSIE
		if(isOldIE && !ieHistoryIframe){ //Only create the ieHistoryIframe once
			//Credit: http://alex.dojotoolkit.org/2006/02/what-else-is-burried-down-in-the-depths-of-googles-amazing-javascript/
			//ieHistoryDoc = new ActiveXObject("htmlfile"); // !?!
			//// make sure it's really scriptable
			//ieHistoryDoc.open();
			//ieHistoryDoc.write("<html>");
			////alert(location.protocol +  "//" + location.hostname + "/")
			////ieHistoryDoc.write("<script>document.domain='" + location.protocol +  "//" + location.hostname + "/" + "';</script>");
			//ieHistoryDoc.write("<script>document.domain='" + location.hostname + "';</script>");
			//ieHistoryDoc.write("</html>");
			//ieHistoryDoc.close();
			//// set the iframe up to call the server for data
			//var ifrDiv = ieHistoryDoc.createElement("div");
			//ieHistoryDoc.appendChild(ifrDiv);
			//// start communicating
			var src = ajax.blankURL.replace(/\?.*/, '') + '?' + maybeinitialshashit(ajax.getURI());
			//ifrDiv.innerHTML = "<iframe id='foo' src='" + src + "'></iframe><script>document.getElementById('foo').attachEvent('onload', function(){ alert(this.src) })";
			//ieHistoryIframe = ifrDiv.firstChild;
			//ieHistoryIframe.attachEvent('onload', function(){
			//	alert("Now at: " + ieHistoryIframe.contentWindow.location);
			//});
			//document.body.appendChild(ieHistoryIframe);
			ieHistoryIframe = document.createElement('iframe');
			ieHistoryIframe.style.cssText = "visibility:hidden; width:1px; height:1px; top:-100px; position:absolute;";
			ieHistoryIframe.src = src;
			$(function(){
				ieHistoryIframe.attachEvent('onload', function(){
					var newHash = ieHistoryIframe.contentWindow.location.search.substr(1);
					ieHistoryIframe.contentWindow.document.body.innerHTML = newHash;
					
					if(newHash != window.location.hash.substr(1)){
						ajax.navigate(alwaysinitialshashit(newHash));
					}
				});
				document.body.appendChild(ieHistoryIframe);
			});
			
			//var ieHistoryIframePrevSrc = ieHistoryIframe.src;
			//setInterval(function(){
			//	if(ieHistoryIframePrevSrc != ieHistoryIframe.src){
			//		alert("PAGE CHANGED! " + ieHistoryIframePrevSrc + " ==> " + ieHistoryIframe.src);
			//	}
			//}, 100);
		}
	}
	
	//Fire onenable event
	if(ajax.onenable){
		try {
			ajax.onenable();
		}
		catch(e){
			window.setTimeout(function(){
				throw e;
			}, 0);
		}
	}
};

/**
 * Disable Ajax Loading
 */
ajax.disable = function(){
	document.cookie = ajax.stateKey+'=0; path=/';
	ajax.enabled = false;
	
	//Undo all that was done by enable
	if(ajax.land()){
		
		//Remove monitoring the location.hash for changes
		clearInterval(hashchangeTimerID);
		hashchangeTimerID = null;
		try {
			if(window.removeEventListener)
				window.removeEventListener('hashchange', onhashchange, false);
			else if(window.attachEvent)
				window.detachEvent('onhashchange', onhashchange);
		}
		catch(e){}
		
		//Remove event delegation
		$("a").die('click', link_onclick);
		
		//Clean up the IE history
		if(ieHistoryIframe){
			if(ieHistoryIframe.parentNode)
				ieHistoryIframe.parentNode.removeChild(ieHistoryIframe);
			ieHistoryIframe = null;
			//try {
			//	ieHistoryDoc.close();
			//}
			//catch(e){}
			//ieHistoryDoc = null;
		}
	}
	
	//Fire ondisable event
	if(ajax.ondisable){
		try {
			ajax.ondisable();
		}
		catch(e){
			window.setTimeout(function(){
				throw e;
			}, 0);
		}
	}
};


/**
 * Get the Ajax or non-Ajax REQUEST_URI for the current page
 */
ajax.getURI = function(){
	var uri;
	if(ajax.isEnabled())
		uri = alwaysinitialshashit(window.location.hash.substr(1));
	else
		uri = window.location.pathname;
	return uri;
};


var pendingLoading = 0;


/**
 * Load the content at the supplied URI into the page
 */
ajax.load = function(uri){
	pendingLoading++;
	
	//Fire onloading event
	if(ajax.onloading){
		try {
			ajax.onloading();
		}
		catch(e){
			window.setTimeout(function(){
				throw e;
			}, 0);
		}
	}
	
	//Load the URI
	$.ajax({
		type:'GET',
		dataType:'xml',
		cache:false,
		url:uri.replace(/#.*/, ''),
		beforeSend:function(xhr){
			xhr.setRequestHeader('Accept', 'text/xml');
		},
		complete:function(xhr, textStatus){
			
			//Populate the page once it's ready
			$(function(){
				pendingLoading--;
				
				try {
					//XML Parse error
					if(!xhr.responseXML || !xhr.responseXML.documentElement){
						//Response XML will fail if navigating to another page
						// while one is currently loading; so only throw error
						// if none are pending.
						if(pendingLoading == 0){
							throw Error("XML not returned: " + xhr.responseText);
						}
						//Silently abort since another is pending
						else {
							return;
						}
					}
					var data = xhr.responseXML;
					
					//Update the title
					if(ajax.updateTitle){
						var title = $(data).find('head > title:first').text();
						if(title){
							document.title = title;
							
							//setTimeout(function(){
							//	document.title = title;
							//}, 100);
						}
					}
					
					//Update the content
					//AjaxLoading.selectors = [
					//	{selector:"body", attributes:['class']},
					//	{selector:"#breadcrumbs"},
					//	{selector:"#navigation li", attributes:['class']},
					//	{selector:"#content"}
					//];
					$(ajax.selectors).each(function(){
						var selector = this.selector;
						var attributes = this.attributes;
						
						var $targets = $(document).find(selector);
						var $sources = $(data).find(selector);
						
						//Replace only the select attributes
						if(attributes && attributes.length){
							$targets.each(function(i){
								$(attributes).each(function(){
									try {
										//For some reason, jQuery doesn't wrap this properly
										if(this == 'class'){
											$targets[i].className = $sources[i].getAttribute('class');
											//$targets[i].className = $sources[i].className;
											//$($targets[i]).attr(this, $sources[i].className);
										}
										else {
											$($targets[i]).attr(this, $($sources[i]).attr(this));
										}
									}
									catch(err){
										if(ajax.debug)
											throw err;
										else
											ajax.disable();
									}
								});
							});
						}
						//Replace all of the attributes and the contents
						else {
							$targets.each(function(i){
								var target = this;
								var source = $sources[i];
								try {
									try {
										source = document.importNode(source, true);
									}
									catch(e){
										source = source.cloneNode(true);
										if(document.adoptNode)
											document.adoptNode(source);
									}
									target.parentNode.replaceChild(source, target);
								}
								catch(e){
									source = convertXMLElementToHTML($sources[i]);
									target.parentNode.replaceChild(source, target);
									if(window.swfobject){
										while(divsForSWFObject.length){
											var obj = divsForSWFObject.pop();
											swfobject.embedSWF(
												obj.dataset.params.movie,
												obj.id,
												obj.dataset.attributes.width,
												obj.dataset.attributes.height,
												'8.0.0',
												null,
												null,
												obj.dataset.params,
												obj.dataset.attributes
											);
										}
									}
								}
							});
						}
					});
					
					//Check to see if the change is merely in the anchor target
					var hash = uri.replace(/.*#/, '');
					if(hash){
						var target = document.getElementById(hash);
						if(target && target.scrollIntoView)
							target.scrollIntoView();
					}
					//If new hash is empty, scroll to top
					else {
						window.scrollTo(0,0);
					}
				}
				catch(err){
					if(ajax.debug){
						throw err;
					}
					else {
						ajax.disable();
					}
				}
				
				//Fire onloaded event
				if(ajax.onloaded){
					try {
						ajax.onloaded();
					}
					catch(e){
						window.setTimeout(function(){
							throw e;
						}, 0);
					}
				}
			});
		}
	});
}








//AjaxLoading. = 
//ajax.blankPage = "/wp-content/themes/si-2.5/blank.html";
ajax.updateTitle = true;
ajax.selectors = [
	{selector:"body"}
];




/**
 * The following two functions are only needed by IE :-(
 */

//document.createElement replacement that is aware of MSIE issues
var createElement = (function(){
	try {
		var test = document.createElement('<div id="foo">');
	}
	catch(e){}
	
	if(test && test.nodeName.toLowerCase() == 'div' && test.id == 'foo'){
		return function(nodeName, attrs){
			var tag = '<' + nodeName;
			for(var name in attrs){
				tag += " " + name + '="' + attrs[name].replace(/"/g, '&quot;') + '"';
			}
			tag += '>';
			return document.createElement(tag);
		}
	}
	else {
		return function(nodeName, attrs){
			var el = document.createElement(nodeName);
			for(var name in attrs){
				el.setAttribute(name, attrs[name]);
			}
			return el;
		}
	}
})();

var preserveWhitespaceDepth = 0; //Required for MSIE <= 7

//Function which copies XML nodes into HTML ones if XML DOM can't be directly imported
var depth = 0;
function convertXMLElementToHTML(source){
	var sourceAttrs = {};
	for(var i = 0; i < source.attributes.length; i++){
		sourceAttrs[source.attributes[i].nodeName] = source.attributes[i].nodeValue;
	}
	
	//This is needed for msie
	if(source.nodeName.toLowerCase() == 'object'){
		
		var obj = createElement('div', {
			'id':source.getAttribute('id'),
			'class':source.getAttribute('class')
		});
		
		if(!obj.dataset) //HTML5
			obj.dataset = {};
		
		obj.dataset.params = {};
		obj.dataset.attributes = sourceAttrs;
		
		var params = source.getElementsByTagName('param');
		for(var i = 0; i < params.length; i++)
			obj.dataset.params[params[i].getAttribute('name')] = params[i].getAttribute('value');
		
		var img = source.getElementsByTagName('img')[0];
		if(img)
			obj.appendChild(convertXMLElementToHTML(img));
		divsForSWFObject.push(obj);
		
		return obj;
	}
	
	depth++;
	var dest = createElement(source.nodeName, sourceAttrs);
	for(var i = 0; i < source.childNodes.length; i++){
		var sourceNode = source.childNodes[i];
		switch(sourceNode.nodeType){
			case 1: /*Node.ELEMENT_NODE*/
				var nodeName = sourceNode.nodeName.toLowerCase();
				if(nodeName == 'pre')
					preserveWhitespaceDepth++;
				var child = convertXMLElementToHTML(sourceNode);
				if(nodeName == 'pre')
					preserveWhitespaceDepth--;
				if(child)
					dest.appendChild(child);
				break;
			case 3: /*Node.TEXT_NODE*/
			case 4: /*Node.CDATA_SECTION_NODE*/
				dest.appendChild(document.createTextNode(!preserveWhitespaceDepth ? sourceNode.nodeValue.replace(/\s\s+/g, ' ') : sourceNode.nodeValue));
				break;
			//case 7: /*Node.PROCESSING_INSTRUCTION_NODE*/
			//	dest.appendChild(document.createProcessingInstruction(sourceNode.nodeValue));
			//	break;
			case 8: /*Node.COMMENT_NODE*/
				dest.appendChild(document.createComment(sourceNode.nodeValue));
				break;
		}
	}
	depth--;
	return dest;
}

/** Thank you WordPress **/
//function maybeuninitialshashit(uri){
//	if(!ajax.initialSlash)
//		return uri.replace(/^\//, '');
//	return uri;
//}

function maybeinitialshashit(uri){
	//if(ajax.initialSlash && uri.substr(0, 1) != '/')
	//	return '/' + uri;
	//return uri;
	if(ajax.initialSlash){
		if(uri.substr(0, 1) != '/')
			uri = '/' + uri;
	}
	else {
		uri = uri.replace(/^\//, '');
	}
	return uri;
}

function alwaysinitialshashit(uri){
	if(uri.substr(0, 1) != '/')
		return '/' + uri;
	return uri;

	//if(ajax.initialSlash){
	//	if(uri.substr(0, 1) != '/')
	//		uri = '/' + uri;
	//}
	//else {
	//	uri = uri.replace(/^\//, '');
	//}
	//return uri;
}

})(window, document, jQuery /*, undefined*/);

//Redirect to Ajax or non-Ajax version of the page depending on enabled state

