//Just like the prototype, it returns a function wrapped in a context

Function.prototype.bind = function(context){

	var closure = this;

	var tmp_fnc = function(){

		return closure.apply(context, arguments);

	}

	return tmp_fnc;

}



Object.prototype.merge = function(object){

	for(attr in object){

		this[attr] = object[attr];

	}

}



document.navigators = {

	settings: {

		interval: 100, //The interval which the verification for new data will be done (in miliseconds)

		helper: true, //Specify if the onnavigate function will return the helper, do not change!

		iframe_src: "control.htm" //The location of the file control.htm, absolute path please

	},

	initialize: function(){

		this.is_ie = (navigator.userAgent.toLowerCase().indexOf("msie") > -1) ? true : false;

		if(this.is_ie){

			this.settings.iframe_src = this.settings.iframe_src.replace(/(\?|#).*$/, "");

			window.attachEvent("onload", (function(){

				//this.running = true; The iFrame that needs to make it running

				this.iframe = document.createElement("iframe");

				this.iframe.setAttribute("src", this.settings.iframe_src);

				this.iframe.style.display = "none";

				document.getElementsByTagName("body")[0].appendChild(this.iframe);

			}).bind(this));

		} else {this.running = true;}

	},

	//The function that is called by the user and puts new data in the hash to be called

	helper: function(data, force){

		var navs = document.navigators; var data =this.id +  data;

		if(force){navs.data_buffer = "";} //If force is true then calling sequentially the same helper works

		if(navs.is_ie){navs.iframe.src = navs.settings.iframe_src + "?id=" + data;}

		else{window.location.hash = "#" + data;}

	},

	called: false,

	history: [],

	data_buffer: ""

};



function onnavigate(id, callback){

	var navs = document.navigators; navs[id] = {};

	if(!navs.running){navs.initialize();}

	setInterval(function(){if(navs.running){

		var url = window.location.href;

		var hash = window.location.hash.replace(/#/, "");

		var theid = "#" + id;

		if(url.indexOf(theid) > -1){ //If the call is with us!

			var data = url.split(theid)[1] || "";

			var new_data = theid + data;

			if(navs.data_buffer != new_data){ //If the old content is diferent

				callback(data); //Calling the callback function!

				navs.called = true; //To make sure was already called to fix the index state

				navs.history.push(new_data);

				navs.data_buffer = new_data;

			}

		} else if (!hash && navs.called){ //If the navigators was called and the page is in index state (no hashes), it means reload!

			navs.running = false; //To stop the others Intervals to dont make it the same way and broke something

			//window.location = ((url.indexOf("#") > -1) ? url.split("#")[0] : url) + "#";

			window.location.reload();

	

		}

	}}, navs.settings.interval);

	navs[id].merge({callback: callback});

	if(navs.settings.helper){

		navs[id].helper = navs.helper.bind({id: id}); return navs[id].helper;

	}

}