// The constructor should be called with
// the parent object (optional, defaults to window).

function Timer(){
	this.obj = (arguments.length)?arguments[0]:window;
	return this;
}

// The set functions should be called with:
// - The name of the object method (as a string) (required)
// - The millisecond delay (required)
// - Any number of extra arguments, which will all be
// passed to the method when it is evaluated.

Timer.prototype.setInterval = function(func, msec){
	var i = Timer.getNew();
	var t = Timer.buildCall(this.obj, i, arguments);
	Timer.set[i].timer = window.setInterval(t,msec);
	return i;
}

Timer.prototype.setTimeout = function(func, msec){
	var i = Timer.getNew();
	Timer.buildCall(this.obj, i, arguments);
	Timer.set[i].timer = window.setTimeout("Timer.callOnce("+i+");",msec);
	return i;
}

// The clear functions should be called with
// the return value from the equivalent set function.

Timer.prototype.clearInterval = function(i){
	if(!Timer.set[i]) return;
	window.clearInterval(Timer.set[i].timer);
	Timer.set[i] = null;
}

Timer.prototype.clearTimeout = function(i){
	if(!Timer.set[i]) return;
	window.clearTimeout(Timer.set[i].timer);
	Timer.set[i] = null;
}

// Private data

Timer.set = new Array();
Timer.buildCall = function(obj, i, args){
	var t = "";
	Timer.set[i] = new Array();
	if(obj != window){
		Timer.set[i].obj = obj;
		t = "Timer.set["+i+"].obj.";
	}
	t += args[0]+"(";
	if(args.length > 2){
		Timer.set[i][0] = args[2];
		t += "Timer.set["+i+"][0]";
		for(var j=1; (j+2)<args.length; j++){
			Timer.set[i][j] = args[j+2];
			t += ", Timer.set["+i+"]["+j+"]";
		}
	}
	t += ");";
	Timer.set[i].call = t;
	return t;
}

Timer.callOnce = function(i){
	if(!Timer.set[i]) return;
	eval(Timer.set[i].call);
	Timer.set[i] = null;
}

Timer.getNew = function(){
	var i = 0;
	while(Timer.set[i]) i++;
	return i;
}




// Auxiliary functions for Back and Bookmark
function PageLocator(propertyToUse, dividingCharacter) {
  this.propertyToUse = propertyToUse;
  this.defaultQS = 1;
  this.dividingCharacter = dividingCharacter;
}
PageLocator.prototype.getLocation = function() {
  return eval(this.propertyToUse);
}
PageLocator.prototype.getHash = function() {
  var url = this.getLocation();
  if(url.indexOf(this.dividingCharacter)>-1) {
    var url_elements = url.split(this.dividingCharacter);
    return url_elements[url_elements.length-1];
  } else {
    return this.defaultQS;
  }
}
PageLocator.prototype.getHref = function() {
  var url = this.getLocation();
  var url_elements = url.split(this.dividingCharacter);
  return url_elements[0];
}
PageLocator.prototype.createHash = function(text) {
	var hash = "";
	for(i = 0; i <text.length; i++){
		hash = hash + text.charCodeAt(i);
		if(i < text.length - 1){
			hash = hash + ";";
		}
	}
	return hash;
}

PageLocator.prototype.getHashValue = function() {
	var hash = this.getHash();
	if(typeof(hash) == 'string'){
		var text = "";
		chars = hash.split(';');
		for(i = 0; i <chars.length; i++){
			text = text + String.fromCharCode(chars[i]);
		}
		return text;
	}
	return hash;
}
		
PageLocator.prototype.makeNewLocation = function(new_qs) {
  return this.getHref() + this.dividingCharacter + new_qs;
}

function setContent(new_content) {
  if(!document.getElementById || !document.getElementsByTagName) return;
  var container = document.getElementById("content");
  container.innerHTML = new_content;
}


// URL Fixer for non IE browsers
function AjaxUrlFixer() {
  this.linkIds = new Array();	
  
  this.locator = new PageLocator("window.location.href", "#");
  this.timer = new Timer(this);
}

AjaxUrlFixer.prototype.startTimer = function () {
  this.checkWhetherChanged(0);
}

AjaxUrlFixer.prototype.fixLinks = function () {
  for(var i=0; i<this.linkIds.length; i++) {
  	var link = document.getElementById(this.linkIds[i]);
	if(link){
		var href = link.href;
		var hashPart = href.substr(href.indexOf("hash=")+5);
		link.href = "#"+this.locator.createHash(hashPart);
	}
  }
}
AjaxUrlFixer.prototype.checkWhetherChanged = function(location){
  if(this.locator.getHash() != location) {
    var hash = this.locator.getHashValue(); 
	if(typeof(hash) == "string"){
		if(hash.indexOf("script:") > -1){
			eval(hash.substring(7));
		}
	}
  }
  this.timer.setTimeout("checkWhetherChanged", 200, this.locator.getHash());
}



// URL Fixer for IE
function AjaxIframesFixer(iframeid) {
  this.iframeid = iframeid;
  if (document.getElementById('ajaxnav')) {
  	this.linkIds = new Array();

    this.locator = new PageLocator("window.frames['"+this.iframeid+"'].getLocation()", "?hash=");
    this.windowlocator = new PageLocator("window.location.href", "#");
    this.timer = new Timer(this);
  }
}
AjaxIframesFixer.prototype.fixLinks = function (iframeid) { 
  for(var i=0; i<this.linkIds.length; i++) {
  	var link = document.getElementById(this.linkIds[i]);
	if(link){
		var href = link.href;
		var hashPart = href.substr(href.indexOf("hash=")+5);
		link.href = "Javascript:document.getElementById('"+this.iframeid+"').setAttribute(\"src\", \"mock-page.php?hash="+this.locator.createHash(hashPart)+"\");";
	}
  }
}
AjaxIframesFixer.prototype.startTimer = function(){
  this.timer.setTimeout("checkBookmark", 100, "");
}
AjaxIframesFixer.prototype.checkBookmark = function(){
  //window.location = this.windowlocator.makeNewLocation(this.locator.getHash());
  this.checkWhetherChanged(0);
}
AjaxIframesFixer.prototype.checkWhetherChanged = function(location){
  if(this.locator.getHash() != location) {
    var hash = this.locator.getHashValue(); 
	if(typeof(hash) == "string"){
		if(hash.indexOf("script:") > -1){
			window.location = this.windowlocator.makeNewLocation(this.locator.getHash());
			eval(hash.substring(7));
		}
	}
  }
  this.timer.setTimeout("checkWhetherChanged", 200, this.locator.getHash());
}


// Auxiliary functions for creating the appropriate URL Fixer
function getAjaxUrlFixer() {
	var fix = null;
	if(!document.getElementById || !document.getElementsByTagName) return;
	if(document.iframesfix) {
		fix = new AjaxIframesFixer('ajaxnav');
	} else {
		fix = new AjaxUrlFixer();
	}
	return fix;
}
	
var detect = navigator.userAgent.toLowerCase();
if(detect.indexOf("msie")>-1)document.iframesfix = true;