/*
  
  Instructions
    
    - $.ajaxHistory.init(callback:Function, params:Object)
        - call this first and pass a function to it to be called once as an init callback (the function can recieve the current URI as an argument). Optionally pass params such as baseURL, defaultTitle and baseTitle
        - will return true if a non default url was found
        - must be called on or after dom ready
        
    - $.ajaxHistory.addHistory(newHash:String, newTitle:String)
        - use this to update the hash and window title when you navigate to a new page via ajax
    
    - $.ajaxHistory.addCallback(callback:Function)
        - register a function to be called if the hash changes (ie user clicks back/forwards). Callback function can recieve new URI as an argument
*/

$.ajaxHistory = {
  
  historyInited     : false,
  currentHash       : '',
  callbacks         : [],
  pageTitles        : {},
  titlePrefix       : '',
  defaultTitle      : '',
  baseURL           : '',
  startURL          : '',
  startTitle        : '',
  hostAndProtocol   : location.protocol+"//"+location.host,
  
  init:function(initCallback, params){
    
    if(!$.ajaxHistory.historyInited){
      
      $.ajaxHistory.historyInited = true;
      
      
      //setup startURL (use for when the user hits back enough times )
      $.ajaxHistory.startURL = location.href.replace($.ajaxHistory.hostAndProtocol, "");
      var urlSplit = $.ajaxHistory.startURL.split("#");
      if(urlSplit.length > 1){
        $.ajaxHistory.startURL = urlSplit[1];
      } else {
        $.ajaxHistory.startURL = $.ajaxHistory.startURL.replace(/\.[^\.]*$/, '');
      }
      $.ajaxHistory.startURL = $.ajaxHistory.startURL.replace(/\/$/, '');
      if($.ajaxHistory.startURL.charAt(0) !="/") $.ajaxHistory.startURL = "/"+$.ajaxHistory.startURL;
      $.ajaxHistory.startTitle = document.title;
      
      //title prefix - prepend this to everything
      if(params.titlePrefix != undefined) $.ajaxHistory.titlePrefix = params.titlePrefix;
      //default title - for pages with no title defined
      if(params.defaultTitle != undefined) $.ajaxHistory.defaultTitle = params.defaultTitle;
      
      //baseURL Handling (for when starting on an empty hash)
      if(params.baseURL != undefined) $.ajaxHistory.baseURL = params.baseURL;
      
      //prepare IE
      if($.browser.msie){
        
        $("body").prepend('<iframe id="IE_history_iframe" name="IE_history_iframe" src="" style="display: none;"></iframe>');
        var iframeDoc = $("#IE_history_iframe").get(0).contentWindow.document;
        
        iframeDoc.open();
        iframeDoc.close();
        iframeDoc.location.hash = location.hash;
        
      }
      
      //do the first check with the init callback
      $.ajaxHistory.checkURI(function(newHash){
        initCallback(newHash);
      }); 
      
      //create the interval that checks for changes in the hash and fires any callbacks added with addCallback();
      setInterval(function(){
        $.ajaxHistory.checkURI($.ajaxHistory.checkCallbacks);
      }, 200);
      
    }
  },
  
  checkURI:function(callback, allowBase){
    
    var uri = location.hash;
    
    //if its IE, get the hash from the iframe
    if($.browser.msie){
      var iframeDoc = $("#IE_history_iframe").get(0).contentWindow.document;
      if(iframeDoc.location.hash != "#"+$.ajaxHistory.currentHash){
        uri = iframeDoc.location.hash;
      }
    }
    
    var key = uri.replace(/^#/, '');
    
    //update the window title every time for IE (it messes it up if you modify the DOM after its set)
		if($.browser.msie) document.title = $.ajaxHistory.getPageTitle(key);
    
		//check to see if the hash has changed
    if($.ajaxHistory.currentHash != key){
      
      $.ajaxHistory.currentHash = key;
      
      //update page title
      document.title = $.ajaxHistory.getPageTitle(key);
      
      //Make sure IE sets the main hash to the correct uri
      if($.browser.msie){
        if(location.hash != uri) location.hash = uri;
      }
      
      var isBase = false;
      
      if(key == ''){ //we have hit back enough times to hit the base
        
        key = $.ajaxHistory.startURL; //use the url we started on
        if(key.length < 2) key = $.ajaxHistory.baseURL; //if its empty still, use the custom baseURL defined
        isBase = true;
        
      } else {
        
        //More dealing with IE
        if($.browser.msie){
          var iframeDoc = $("#IE_history_iframe").get(0).contentWindow.document;
          if(iframeDoc.location.hash != uri){
            iframeDoc.open();
            iframeDoc.close();
            iframeDoc.title = document.title;
            iframeDoc.location.hash = uri;
          }
        }
      }
      
      //do callback if it exists, pass the hash and also wether this hash was substituted from ''
      if(callback) callback(key, isBase);
      
      return true;
      
    }
    
    return false;
    
  },
  
  addCallback:function(callback){
    $.ajaxHistory.callbacks.push(callback);
  },
  
  checkCallbacks:function(newHash, isBase){
    for(var i = 0; i<$.ajaxHistory.callbacks.length; i++){
      $.ajaxHistory.callbacks[i](newHash, isBase);
    }
  },
  
  addHistory:function(newHash, pageTitle){
    //clean up passed hash
    newHash = newHash.replace(/^http:\/\/[^\/]+/, '');
    newHash = newHash.replace(/#/, '');
    newHash = newHash.replace(/\/$/, '');
    
		//only add to history if the hash passed is actually new, and if its not the start/base url being called from an empty hash
    if($.ajaxHistory.currentHash != newHash ){
      
      //dont add this to the history if we are recieving a request for the base/start page after hitting an empty hash
      if($.ajaxHistory.currentHash == ''){
        if(newHash.replace(/#/, '').replace(/\/$/, '').replace(/^\//, '') == $.ajaxHistory.startURL.replace(/#/, '').replace(/\/$/, '').replace(/^\//, '')) return;
        if(newHash.replace(/#/, '').replace(/\/$/, '').replace(/^\//, '') == $.ajaxHistory.baseURL.replace(/#/, '').replace(/\/$/, '').replace(/^\//, '')) return;
      }
      
      //more cleanup of hash
      var hash = '';
      if(location.hash.indexOf('#') > -1 ) hash += '#'; //some browsers have # in the location.hash var, some dont
      hash += newHash;
      
      location.hash = hash;
  		$.ajaxHistory.currentHash = newHash;
  		
  		//update title
      document.title = $.ajaxHistory.getPageTitle(newHash, pageTitle);
  		
  		//Deal with IE
  		if($.browser.msie){
  		  var iframeDoc = $("#IE_history_iframe").get(0).contentWindow.document;
    		iframeDoc.open();
        iframeDoc.close();
        iframeDoc.title = document.title;
        iframeDoc.location.hash = hash;
      }
    }
    
  },
  
  getPageTitle:function(newHash, pageTitle){
    
    if($.ajaxHistory.pageTitles[newHash]) return $.ajaxHistory.pageTitles[newHash]; //its already set, return it
    
    if(pageTitle){
      pageTitle = $.trim(pageTitle);
      //add the default title to the start of the string if it exists, and its not already in the string
      if($.ajaxHistory.titlePrefix && pageTitle.indexOf($.ajaxHistory.titlePrefix) != 0 ) pageTitle = $.ajaxHistory.titlePrefix+" - "+pageTitle;
    } else {
      if(newHash == ''){
        pageTitle = $.ajaxHistory.startTitle; //use the start title for an empty key
      } else {
        pageTitle = $.ajaxHistory.defaultTitle; //just use default
      }
    }
    
    $.ajaxHistory.pageTitles[newHash] = pageTitle; //store page title for later
    
    return pageTitle;
    
  },
  
  makeSlug:function(string){
    string = string.replace(/\s/g,'_');
		string = string.replace(/[^a-zA-Z0-9_]/g,'');
    return "/"+string;
  }

}
