/***********************************************************************************************************/
/* LocationManager */
	function LocationManager(dom_property_that_indicates_current_url, hash_mark)
	{
		this.dom_property_that_indicates_current_url = dom_property_that_indicates_current_url;
		if(default_hash_for_this_page)
			this.default_hash = default_hash_for_this_page;
		else
			this.default_hash = "home_index";
		this.hash_mark = hash_mark;
	}


	LocationManager.prototype.get_current_url = function()
	{
		return eval(this.dom_property_that_indicates_current_url);
	}


	LocationManager.prototype.get_hash_value = function()
	{
		var url = this.get_current_url();
		if(url.indexOf(this.hash_mark)>-1) {
			var url_elements = url.split(this.hash_mark);
			return url_elements[url_elements.length-1];
		} else {
			return this.default_hash;
		}
	}

	LocationManager.prototype.get_base_href = function()
	{
		var url = this.get_current_url();
		var url_elements = url.split(this.hash_mark)
		return url_elements[0];
	}


	LocationManager.prototype.build_url_from_hash = function(hash_value)
	{
		return this.get_base_href() + this.hash_mark + hash_value;
	}



/***********************************************************************************************************/
/* FrameBasedContentLoader */
	function FrameBasedContentLoader(iframeid)
	{
		this.iframeid = iframeid;
		if (document.getElementById('iframe_tracker')) {
			this.update_page_links();

			this.hidden_location_manager = new LocationManager("document.frames['"+this.iframeid+"'].get_frame_url()", "#hash=");
			this.window_location_manager = new LocationManager("window.location.href", "#");
			//this.timer = new Timer(this);

			this.delayInit(); // required or IE doesn't fire
		}
	}

	FrameBasedContentLoader.prototype.update_page_links = function (iframeid)
	{
		return;
		/*
		var links = document.getElementsByTagName("A");
		for(var i=0; i<links.length; i++) {
			var href = links[i].getAttribute("href");
			if(href)
			{
				var hash = href.substr(href.indexOf("hash=")+5);
				links[i].setAttribute("href","javascript:document.getElementById('"+this.iframeid+"').setAttribute('src', '/iframe-tracker.html#hash="+hash+"');");
			}
		}
		*/
	}

	FrameBasedContentLoader.prototype.delayInit = function()
	{
		//this.timer.setTimeout("synchronize_on_initial_page_load", 100, "");
		setTimeout("content_loader.synchronize_on_initial_page_load()",100)
	}

	FrameBasedContentLoader.prototype.synchronize_on_initial_page_load = function()
	{
		current_window_hash = this.window_location_manager.get_hash_value();
		current_hidden_hash = this.hidden_location_manager.get_hash_value();
		if((current_window_hash!="") && (current_hidden_hash!=default_hash_for_this_page))
			window.location = this.window_location_manager.build_url_from_hash(current_hidden_hash);
		this.check_for_address_bar_change(initial_hash_on_load,initial_hash_on_load);
		
	}

	FrameBasedContentLoader.prototype.check_for_address_bar_change = function(address_bar_hash_when_timeout_was_created, hidden_hash_when_timer_was_created)
	{
		current_address_bar_hash = this.window_location_manager.get_hash_value();
		current_hidden_hash = this.hidden_location_manager.get_hash_value();
		thing = new Date();
		
		if(current_hidden_hash != hidden_hash_when_timer_was_created)
		{
		
			//Loader_DoFSCommand("alert", thing.getSeconds() + ": sync window with hidden : " + hidden_hash_when_timer_was_created + " -> " + current_hidden_hash);	
			retrieve_and_display_content(current_hidden_hash);
			window.location =  this.window_location_manager.build_url_from_hash(current_hidden_hash);
			current_address_bar_hash = current_hidden_hash;
			
		}
		else if(current_address_bar_hash != address_bar_hash_when_timeout_was_created) 
		{
			//Loader_DoFSCommand("alert", thing.getSeconds() + ": sync hidden with window : " + current_address_bar_hash);	
			retrieve_and_display_content(current_address_bar_hash);
			// synchronize hidden frame to address bar, which forces this item into the history
			tracker = document.getElementById('iframe_tracker')
			tracker.setAttribute('src', '/iframe-tracker.html#hash=' + current_address_bar_hash);
			
			current_hidden_hash = current_address_bar_hash;
		}
		
				
		content_loader_timeout = setTimeout("content_loader.check_for_address_bar_change('" + current_address_bar_hash + "', '" + current_hidden_hash + "')",500);
	}


/***********************************************************************************************************/
/* SimpleContentLoader */
	function SimpleContentLoader() {
		this.update_page_links();

		this.primary_location_manager = new LocationManager("window.location.href", "#");
		this.check_for_address_bar_change(initial_hash_on_load);
	}


	SimpleContentLoader.prototype.update_page_links = function () 
	{
		return;
		/*
		var links = document.getElementsByTagName("A");
		for(var i=0; i<links.length; i++) {
			var href = links[i].getAttribute("href");
			if(href)
			{
				var hash = href.substr(href.indexOf("hash=")+5);
				links[i].setAttribute("href","#"+hash);
			}
		}
		*/
	}

	SimpleContentLoader.prototype.check_for_address_bar_change = function(hash_when_timeout_was_created){
		current_address_bar_hash = this.primary_location_manager.get_hash_value();
		
		if(current_address_bar_hash != hash_when_timeout_was_created) 
		{
			//Loader_DoFSCommand("alert", "js: addres bar change: " + hash_when_timeout_was_created + " -> "+ current_address_bar_hash);
			retrieve_and_display_content(current_address_bar_hash);
		}
	
		content_loader_timeout = setTimeout("content_loader.check_for_address_bar_change('" +current_address_bar_hash + "')", 500);
	}



	
/***********************************************************************************************************/
function setup_back_and_bookmark_without_reload()
{
	if(!document.getElementById || !document.getElementsByTagName) return;
	if(document.use_frame_based_content_loader) {
		content_loader = new FrameBasedContentLoader('iframe_tracker');
	} else {
		content_loader = new SimpleContentLoader();
	}
}



/***********************************************************************************************************/
function create_content_tracker_frame()
{
	if(document.use_frame_based_content_loader) 
	{
		var window_location_manager = new LocationManager("window.location.href", "#");
		document.write("<iframe id='iframe_tracker' name='iframe_tracker' src='/iframe-tracker.html#hash="+window_location_manager.get_hash_value()+"' style='display: none;'></iframe>");
	}
}

/***********************************************************************************************************/
var detect = navigator.userAgent.toLowerCase();
if(detect.indexOf("msie")>-1) document.use_frame_based_content_loader = true;
addEvent(window, "load", setup_back_and_bookmark_without_reload);

	