/**
 * ajaxHistory - histórico de comandos para navegação por Ajax
 * -----------------------------------------------
 * autor: Cau Guanabara <caugb@ibest.com.br>
 * data: 2006-06-07 :: 2006-11-07
 * -----------------------------------------------
 * O objeto ajaxHistory permite trabalhar com o histórico do navegador
 * em páginas com sistema de navegação por ajax, onde para se mostrar um
 * conteúdo não há o carregamento de uma nova página, mas apenas a execução de
 * um comando em javascript. Para que tudo funcione, é preciso adicionar
 * itens ao histórico manualmente, a cada comando que mude o conteúdo exibido,
 * com o método ajaxHistory.add().
 * -----------------------------------------------
 */

/**
Propriedades
------------
ajaxHistory.items -> array - contém os itens do histórico (comandos em forma de texto)
ajaxHistory.captions -> array - contém os títulos para os itens do histórico (opcional)
ajaxHistory.currentIndex -> inteiro - índice do item atual no array ajaxHistory.items
ajaxHistory.activeHistory -> boleano - true se os botões de histórico foram ativados

Métodos públicos
----------------
ajaxHistory.activateBrowserHistory -> function - ativa os botões de histórico do navegador
                                      Deve ser executada apenas uma vez, no onload da página.
ajaxHistory.add -> function - adiciona um item ao histórico
  @param str - comando JS em forma de string para ser executado ao mostrar o item
  @param cap - string para ser usada como title da página no carregamento do item
ajaxHistory.go -> function - recebe um número x e avança ou retrocede x itens no histórico
  @param ref - inteiro indicando quantos itens avançar (pos.) ou retroceder (neg.) no histórico
ajaxHistory.goTo -> function - recebe um número x e mostra o item x do histórico
  @param ind - inteiro indicando o índice do item do histórico a exibir
ajaxHistory.hasBack -> function - testa se há um item anterior ao atual
ajaxHistory.hasForward -> function - testa se há um item à frente do atual

Métodos privados
----------------
ajaxHistory.makeIframe -> function - cria o iframe (IExplore)
ajaxHistory.checkHash -> function - checa se há mudanças no hash (Mozilla)
ajaxHistory.setHash -> function - aplica a mudança no hash
*/

/**
 * Para usar os botões de histórico do navegador, é preciso ter o arquivo 'historyframe.html',
 * na mesma pasta da página que está usando o objeto ajaxHistory (não do arquivo ajax_history.js).
 * O arquivo 'historyframe.html' será incluído na página, em um iframe (apenas para o IExplorer).

 historyframe.html
 -----------------
 <html><head><script type="text/javascript" language="javascript">
  function checkHistory() {
  var pi = parent.location.hash.replace(/#/,''), si = location.href.replace(/^.+\?/,'') || false;
    if(si && pi && (parent.ajaxHistory || false)) 
      if(pi != si) parent.ajaxHistory.goTo(si);
  }
  </script></head><body onLoad="checkHistory();"></body></html>
 */

var ajaxHistory = {
  'items': [],
  'captions': [],
  'currentIndex': 0,
  'go': function(ref) {
    if(this.hasKey(this.currentIndex + ref)) this.currentIndex += ref;
    else return;
  this.setHash();  
    if(this.captions[this.currentIndex]) document.title = this.captions[this.currentIndex];
  new Function(this.items[this.currentIndex])();
  },
  'goTo': function(ind) {
    if(this.hasKey(ind)) this.currentIndex = ind;
    else return;
  this.setHash();
    if(this.captions[this.currentIndex]) document.title = this.captions[this.currentIndex];
  new Function(this.items[this.currentIndex])();
  },
  'add': function(str, cap) { 
    if(str == this.items[this.currentIndex]) return false;
  this.currentIndex = this.items.length;
  this.items.push(str);
  this.captions.push(cap || false);
  this.setHash();  
  return true;
  },
  'hasKey': function(key) { return (this.items[key] || false) ? true : false; },
  'hasBack': function() { return (this.items[this.currentIndex - 1] || false) ? true : false; },
  'hasForward': function() { return (this.items[this.currentIndex + 1] || false) ? true : false; },
  'activeHistory': false,
  'activateBrowserHistory': function() {
    if(document.all) this.makeIframe();
    else setInterval("ajaxHistory.checkHash()", 100);
  this.activeHistory = true;
  },
  'makeIframe': function() {
  this.iframe = document.createElement('iframe');
  this.iframe.src = 'historyframe.html';
  this.iframe.style.display = 'none';
  document.getElementsByTagName('body')[0].appendChild(this.iframe);
  },
  'checkHash': function() {
  var curHash = location.hash.replace(/#/,'');
    if(this.currentIndex != curHash) this.goTo(curHash);
  },
  'setHash': function() {
	  if(!this.activeHistory) return; 
  top.location.hash = this.currentIndex;
    if(!document.all) return;
	this.iframe.contentWindow.location.href = 'historyframe.html?'+this.currentIndex;
  }
};

