/**
 * Método construtor do HTMLTabController. 
 * @param sys - Indica o código do sistema.
 * @param formID - Indica o código do formulário.
 * @param posX - Posição do componente na tela em relação ao eixo X.
 * @param posY - Posição do componente na tela em relação ao eixo Y.
 * @param width - Largura do componente.
 * @param heigth - ALtura do componente.  
 */
function HTMLTabController(sys, formID, posX, posY, width, height, hideTab) {
  this.sys = sys;
  this.formID = formID;
  this.posX = posX;
  this.posY = posY;
  this.width = width;
  this.height = height;
  this.tabs = new Array();
  this.tabsByName = new Array();
  this.table = getTable(1,0)[0];
  this.tr = this.table.firstChild.firstChild;
  this.showTabButtons = true;
  this.useReadOnlyDiv = true;
  this.hideTab = hideTab;
  
  this.searchTab = null; // Aba Localizar
  this.currentTab = null; // Aba selecionada
  this.lastCreatedTab = null; // Última aba criada

  this.empty = true;

  if (!this.hideTab) {
	  preload(skin+'ntab_back.gif');
	  preload(skin+'ntab_back_sel.gif');
	  preload(skin+'ntab_down.gif');
	  preload(skin+'ntab_down_left.gif');
	  preload(skin+'ntab_down_left_sel.gif');
	  preload(skin+'ntab_down_right.gif');
	  preload(skin+'ntab_down_right_sel.gif');
	  preload(skin+'ntab_down_sel.gif');
	  preload(skin+'ntab_left.gif');
	  preload(skin+'ntab_left_sel.gif');
	  preload(skin+'ntab_right.gif');
	  preload(skin+'ntab_right_sel.gif');
	  preload(skin+'ntab_top.gif');
	  preload(skin+'ntab_top_left.gif');
	  preload(skin+'ntab_top_left_sel.gif');
	  preload(skin+'ntab_top_right.gif');
	  preload(skin+'ntab_top_right_sel.gif');
	  preload(skin+'ntab_top_sel.gif');
  }
}

/**
 * Herança do componente.
 */
HTMLTabController.inherits(HTMLElementBase);

HTMLTabController.prototype.name = 'HTMLTabController';

/**
 * Retorno o name do componente.
 * @return '[object ' concateaado com o name do objeto. 
 */
HTMLTabController.prototype.toString = function() {
  return '[object '+this.name+']';
}

/**
 * Exibe as abas ao entrar no formulário.
 */
HTMLTabController.prototype.view = function() {
  for (i=0;i<this.tabs.length;i++) {    
    this.tabs[i].view();
  }
}

/**
 * Exibe as abas no momento em que o formulário esta para inserção/alteração.
 */
HTMLTabController.prototype.edit = function() {
  for (i=0;i<this.tabs.length;i++) {
    this.tabs[i].edit();
  }
}

/**
 * Indica se a aba 'Localizar' irá aparecer ou não no formulário.
 * @param visible - TRUE indica que a aba 'Localizar' será visível. 
 */
HTMLTabController.prototype.setSearchTabVisible = function(visible) {
  var searchTab = this.searchTab;
  if (searchTab) {
    searchTab.setVisible(visible);
  }
}

/**
 * Adiciona uma aba ao formulário.
 * @param description - Descrição do Aba.
 * @param onclick - Evento onclick da Aba.
 * @param onexit - 
 * @param imgSrc - imagem associada a Aba. 
 */
HTMLTabController.prototype.add = function(description, onclick, onexit, imgSrc) {  	
  return this.addTab(description, onclick, onexit, imgSrc, false);
}

/**
 * Adiciona a aba Localizar ao formulário.
 * @param description - Descrição do Aba.
 * @param onclick - Evento onclick da Aba.
 * @param onexit - 
 * @param imgSrc - imagem associada a Aba. 
 */
HTMLTabController.prototype.addSearchTab = function(description, onclick, onexit, imgSrc) {
	return this.addTab(description, onclick, onexit, imgSrc, true);
}

/**
 * Adiciona as ao formulário.
 * @param description - Descrição do Aba.
 * @param onclick - Evento onclick da Aba.
 * @param onexit - 
 * @param imgSrc - imagem associada a Aba. 
 * @param searchTab - TRUE indica que a aba Localizar será adicionada ao formaulário.
 */
HTMLTabController.prototype.addTab = function(description, onclick, onexit, imgSrc, searchTab) {
	if (this.tr.childNodes.length > 0) {
    var space = document.createElement("td");
    space.style.width = 1;
    if (this.showTabButtons) this.tr.appendChild(space);
  }

  var cell = document.createElement("td");
  if (this.showTabButtons) this.tr.appendChild(cell);

  var tb = new HTMLTab(description, this, onclick, onexit, imgSrc);
  tb.searchTab = searchTab;
  tb.showTabButtons = this.showTabButtons;
  tb.color = this.color;
  
  if (searchTab) {
  	this.searchTab = tb;
  }
  
  if (!this.currentTab) {
    this.currentTab = tb;
  }

  tb.design(cell, this.empty);

  this.tabs.push(tb);
  this.tabsByName[description] = tb;

  if (this.empty)
    this.selected = tb;

  this.lastCreatedTab = tb;
  this.empty = false;
  
  return tb.div;
}
/**
 * @deprecated 
 */
HTMLTabController.prototype.showTab = function() {
}

/**
 * Retorna objeto a partir do name passado como parâmetro.
 * @param name - nome do objeto.
 * @return objeto HTMLTabController. 
 */
HTMLTabController.prototype.getTabByName = function(name) {
   return this.tabsByName[name];
}

HTMLTabController.prototype.getTabByDiv = function(div) {
  for (var i = 0; i < this.tabs.length; i++) {
    if (this.tabs[i].div == div) {
      return this.tabs[i];
    }
  }
}

HTMLTabController.prototype.getDiv = function(name) {
  if (!name)
    return this.lastCreatedTab.div;
  else {
    var t = this.tabsByName[name];
    if (t) return t.div;
  }
}

/**
 * Retorna o indice da aba selecionada no formulario.
 * @return index - indica o indice da aba. 
 */
HTMLTabController.prototype.getSelectedTabIndex = function() {
  var index = -1;

  for (var i = 0; i < this.tabs.length; i++) {
    if (this.tabs[i].selected) {
      index = i;
      break;
    }
  }

  return index;
}

/**
 * Retorna a aba selecionda ou null caso n exista abas no formulário.
 */
HTMLTabController.prototype.getSelectedTab = function() {	
  var index = this.getSelectedTabIndex();
  
  if (index >= 0) {
  	return this.tabs[index];
  }
  
  return null;
}

/**
 * Retorna a aba conforme o indice passado como parametro.
 * @param tab - retorna a aba ou null caso n exista.
 */
HTMLTabController.prototype.openTabByIndex = function(index) {
  var tab = this.tabs[index];
  if (tab && tab.getVisible()) {
  	tab.clickAction();
  	return tab;
  }
  return null;
}

HTMLTabController.prototype.getTabInterval = function() {
  var firstTabPosition = 0;
  for (var j = 0; j < this.tabs.length; j++) {
    if (this.tabs[j] && this.tabs[j].getVisible()) {
      firstTabPosition = j;
      break;
    }
  }

  var lastTabPosition = this.tabs.length - 1;
  for (var j = (this.tabs.length - 1); j >= 0; j--) {
    if (this.tabs[j] && this.tabs[j].getVisible()) {
      lastTabPosition = j;
      break;
    }
  }
  
  return {first: firstTabPosition, last: lastTabPosition};
}

/**
 * Retorna a aba ANTERIOR à aba atual. 
 * @return NULL caso n exista uma aba anterior. 
 */
HTMLTabController.prototype.openPreviousTab = function() {
  var selectedTabIndex = this.getSelectedTabIndex();

  var tabInterval = this.getTabInterval();
  var first = tabInterval.first;
  var last = tabInterval.last;

  if (first < last) {
    if (selectedTabIndex == first) {
      return this.openTabByIndex(last);
    } else if (selectedTabIndex > 0) {
      return this.openTabByIndex(selectedTabIndex - 1);
    }
  }
  
  return null;
}

/**
 * Retorna a POSTERIOR à aba atual.
 * @return NULL caso n exista uma próxima aba. 
 */
HTMLTabController.prototype.openNextTab = function() {
  var selectedTabIndex = this.getSelectedTabIndex();
  
  var tabInterval = this.getTabInterval();
  var first = tabInterval.first;
  var last = tabInterval.last;

  if (first < last) {
    if (selectedTabIndex == last) {
      return this.openTabByIndex(first);
    } else if (selectedTabIndex >= 0) {
      return this.openTabByIndex(selectedTabIndex + 1);
    }
  }
  
  return null;
}

/**
 * Adiciona as abas ao corpo do formulario.
 * @param doc - documento onde as abas sao inseridas. 
 */
HTMLTabController.prototype.design = function(doc) {
  this.navdiv = getDiv('', 0, 0, this.width, (!this.showTabButtons?0:20), 2, true);
  this.div = getDiv('', this.posX, this.posY, this.width, this.height, 1, true);
  this.navdiv.appendChild(this.table);
  this.div.appendChild(this.navdiv);
  doc.appendChild(this.div);
  this.doc = doc;
}

/**
 * Remove os eventos associados as abas.
 */
HTMLTabController.prototype.flush = function() {
  for (i=0;i<this.tabs.length;i++)
    this.tabs[i].flush();

  for (var i in this) {
    if (this[i]) {
      removeEvents(this[i]);
      this[i] = null;
    }
  }
}

/**
 * Seta a propriedade Visible de todas as abas do formulário. 
 * @param v - TRUE torna visíveis as abas do formulário.
 */
HTMLTabController.prototype.setVisible = function(name, v) {
  var t = this.tabsByName[name];
  if (t) {
    if (!v && t.selected) {
      var foundTabPosition = -1;
      for (var i in this.tabs) {
        if (this.tabs[i] && this.tabs[i].description == name) {
        	foundTabPosition = i;
          break;
        }
      }

      var firstTabPosition = 0;
      for (var j = 0; j < this.tabs.length; j++) {
        if (this.tabs[j] && this.tabs[j].getVisible()) {
          firstTabPosition = j;
          break;
        }
      }

      var lastTabPosition = this.tabs.length - 1;
      for (var j = (this.tabs.length - 1); j >= 0; j--) {
        if (this.tabs[j] && this.tabs[j].getVisible()) {
          lastTabPosition = j;
          break;
        }
      }

      if (foundTabPosition == firstTabPosition) {
        var j = foundTabPosition;
        while (++j < this.tabs.length) {
          var temp = this.tabs[j];
          if (temp && temp.getVisible()) {
            this.openTab(temp.description);
            break;
          }
        }
      } else if (foundTabPosition == lastTabPosition) {
        for (var j = lastTabPosition - 1; j >= firstTabPosition; j--) {
          var temp = this.tabs[j];
          if (temp && temp.getVisible()) {
            this.openTab(temp.description);
            break;
          }
        }
      } else {
        var j = foundTabPosition;
        while (--j != foundTabPosition) {
          var temp = this.tabs[j];
          if (temp && temp.getVisible()) {
            this.openTab(temp.description);
            break;
          } else if (j == firstTabPosition) {
            j = this.tabs.length;
          }
        }
      }
    }

    t.setVisible(v);
  }
}

HTMLTabController.prototype.openSearchTab = function() {
	if (this.searchTab) {
		this.searchTab.clickAction();
	}
}

HTMLTabController.prototype.openTab = function(name) {
  var t = this.tabsByName[name];
  if (t) t.clickAction();
}

/*******
   Abas
*****/

/**
 * Método construtor do HTMLTab. Cria as abas do formulário. 
 * @param description - Descrição do Aba.
 * @param onclick - Evento onclick da Aba.
 * @param onexit - 
 * @param imgSrc - imagem associada a Aba. 
 */
function HTMLTab(description, parent, onclick, onexit, imgSrc) {
  this.showTabButtons = true;
  this.sys = parent.sys;
  this.formID = parent.formID;
  this.description = description;
  this.onclick = onclick;
  this.onexit = onexit;
  this.parent = parent;
  this.selected = false;
  this.self = this;
  this.imgSrc = imgSrc;
  this.captionHeight = 19;
  this.editMode = false;
  this.useReadOnlyDiv = parent.useReadOnlyDiv;
  this.searchTab = false;
  if (imgSrc) {
    preload(skin+imgSrc);
    preload(skin+imgSrc.replace('.gif', '_sel.gif'));
  }
}

HTMLTab.inherits(HTMLObject);

HTMLTab.prototype.name = 'HTMLTab';

/**
 * Responsável por construir o HTML de cada aba do formulário.
 * @param doc - documento onde a aba será inserida.
 * @param select  
 */
HTMLTab.prototype.design = function(doc, select) {
  if (!this.showTabButtons)	
    this.captionHeight = 0;

  this.selected = select?true:false;
  
  if (!this.parent.hideTab) {
	  var captionTab = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr OnMouseDown=\"return false;\" OnSelectStart=\"return false;\">";
	  if (this.imgSrc) {
	    captionTab += "<td>&nbsp;</td>";
	    captionTab += "<td><img src=\"" + skin + this.imgSrc + "\" border=\"0\"></td>";
	  }
	  captionTab += "<td>&nbsp;<a href=\"javascript:;\" class=\"clickText\" id=\"tabID\">" + this.description.replace(/\s/g, "&nbsp;") + "</a>&nbsp;</td></tr></table>";
	
	  var b = "";
	  var sel = "";
	  if (select) sel = "_sel";
	  
	  b = b + "<table class=cur border=0 cellspacing=0 height=20 cellpadding=0 background=\""+skin+"ntab_back"+sel+".gif\">";
	  b = b + "<tr><td width=1 height=1><img src=\""+skin+"ntab_top_left"+sel+".gif\"></td><td height=1 background=\""+skin+"ntab_top"+sel+".gif\"></td>";
	  b = b + "<td width=1 height=1><img src=\""+skin+"ntab_top_right"+sel+".gif\"></td></tr><tr><td width=1 background=\""+skin+"ntab_left"+sel+".gif\"></td>";
	
	  b = b + "<td width=\"100%\" align=\"center\" valign=\"middle\">" + captionTab + "</td>";
	  b = b + "<td width=1 background=\""+skin+"ntab_right"+sel+".gif\"></td></tr>";
	  b = b + "<tr><td width=1 height=1 background=\""+skin+"ntab_down_left"+sel+".gif\"><img ignore=\"true\" src=\""+skin+"ntab_down_left"+sel+".gif\"></td><td height=1 background=\""+skin+"ntab_down"+sel+".gif\"></td>";
	  b = b + "<td width=1 height=1  background=\""+skin+"ntab_down_right"+sel+".gif\"><img src=\""+skin+"ntab_down_right"+sel+".gif\"></td></tr></table>";
	
	  doc.innerHTML = b;
	  
	  this.tab = doc;
	
	  this.content = doc.firstChild;
	
	  this.attachEvent(this.content, 'mouseover', this.onMouseOver);
	  this.attachEvent(this.content, 'mouseout', this.onMouseOut);
	  this.attachEvent(this.content, 'click', this.clickAction);
  }

  this.div = getDiv("", 0, this.captionHeight, this.parent.width, this.parent.height-this.captionHeight, 1, this.selected);

  this.div.className = 'tabArea';

  if (this.color)
    this.div.style.background = this.color;
    
  if (!this.showTabButtons)
    this.div.style.border = 0;
    
  this.div['focus'] = this.getAction('focus');
  EventCache.add(this.div, 'focus', this.div['focus']);


  this.attachEvent(this.div, 'onmousedown', this.cantSelect);
  this.attachEvent(this.div, 'selectstart', this.cantSelect);

  this.div['canFocus'] = this.getAction('canFocus');
  EventCache.add(this.div, 'canFocus', this.div['focus']);

  this.div['tabName'] = this.description;

  this.parent.div.appendChild(this.div);

  if (this.parent.useReadOnlyDiv) {
    this.viewDiv = getDiv('', 0, 0, this.parent.width, this.parent.height-this.captionHeight, 99998, true);
    this.viewDiv.innerHTML = "<table width=100% height=100%><tr><td>&nbsp;</td></tr></table>";

    this.attachEvent(this.viewDiv, 'dblclick', this.dblClickAction);

    this.div.appendChild(this.viewDiv);
  }  

  this.attachEvent(this.div, 'click', this.clickDivAction);
}

/**
 * Retorna contexto da Aba Localizar.
 * @return aba localizar. 
 */
HTMLTab.prototype.isSearchTab = function() {
	return this.searchTab;
}

/**
 * Evento click da aba. 
 */
HTMLTab.prototype.clickDivAction = function(e) {
  var target = e.target || e.srcElement;
  if (target == this.div)
    controller.activeElement = this;
}

HTMLTab.prototype.cantSelect = function(e) {
  var target = e.target || e.srcElement;
  if (target == this.div)
    return false;
  else
    return true;
}

/**
 * Evento duplo clique. Muda aba para modo de inserção/alteração.
 */
HTMLTab.prototype.dblClickAction = function() {
  if (this.parent.nav) {
    var nav = this.parent.nav;
    if (nav.canEdit) {
      nav.focusXY = true;
      nav.mX = mX;
      nav.mY = mY;
      nav.findPosY = findPosY(this.content);

      nav.actEdit();

    }
  }
}

/**
 * Evento onfocus da aba.
 */
HTMLTab.prototype.canFocus = function() {
  //!this.useReadOnlyDiv é usado para os casos em que não houver navegação, permitindo assim a tabulação
  var r = this.editMode || !this.useReadOnlyDiv;
  
  if (r && !this.parent.showTabButtons) {
  	r = r && this == this.parent.selected;
  }
  
  return r;
}

HTMLTab.prototype.focus = function() {
  return this.select();
}

/**
 * Torna a DIV que a aba esta inserida visível no momento que o formulário esta no modo de visualizacao.
 */
HTMLTab.prototype.view = function() {
  if (this.parent.useReadOnlyDiv)	
    visibleDiv(this.viewDiv, true);
  this.editMode = false;
}

/**
 * Torna a DIV qua a aba esta inserida visível no momento que o form esta como inserção/alteração.
 */
HTMLTab.prototype.edit = function() {
  if (this.parent.useReadOnlyDiv)
    visibleDiv(this.viewDiv, false);
  this.editMode = true;
}

HTMLTab.prototype.blur = function() {  return true; }

/**
 * Evento clique da ABA.
 */
HTMLTab.prototype.clickAction = function(e) {

  if (this.parent.currentTab) {
    if (this.parent.currentTab.onexit) this.parent.currentTab.onexit();
  }
  this.parent.currentTab = this.self;

  if (this.onclick) {
    if (this.onclick.load) {
      this.onclick.load(e);
    } else {
      this.onclick(e);
    }
  }

  this.select();
}

/**
 * Seta a visibilidade da Div.
 */
HTMLTab.prototype.setVisible = function(v) {
  visibleDiv(this.content, v);
}

/**
 * Renomeia a aba
 * @param description - nova descrição da aba.  
 */
HTMLTab.prototype.rename = function(description) {
  this.description = description;
  this.div['tabName'] = description;

  //
  var tabsByNameNew = new Array();
  for (var index in this.tabsByName) {
    if (typeof index == 'function') continue;
    if (index == description) {
      tabsByNameNew[index] = this;
    } else {
      tabsByNameNew[index] = this.tabsByName[index];
    }
  }
  this.tabsByName = tabsByNameNew;

  //
  findNode(this.tab, "tabID").innerHTML = this.description.toString().replace(/\s/g, "&nbsp;");
}

/**
 * Retorna o name da aba criada.
 */
HTMLTab.prototype.toString = function() {
  return '[object HTMLTab '+this.description+']';
}

HTMLTab.prototype.select = function() {
  if (!isVisibleDiv(this.content))
    return false;
  if (this.parent.selected != this) {
    if (this.editMode && controller.activeElement && controller.activeElement.blur)
      controller.activeElement.blur();
    this.selected = true;
    this.mark(this.content);
    visibleDiv(this.div, true);
    if (this.parent.selected) this.parent.selected.unSelect();
    this.parent.selected = this;
    this.parent.currentTab = this;
    //Meio Alternativo para corrigir um bug que não esconde camadas já escondidas no IE
    if (IE) {
      if (this.parent.useReadOnlyDiv) {	
        if (!isVisibleDiv(this.viewDiv)) {
          visibleDiv(this.viewDiv, true);
          visibleDiv(this.viewDiv, false);
        }
      }
      if (!this.elems)
        this.elems = controller.getElementsByTab(this);

      for (var i=0;i<this.elems.length;i++) {
        if (this.elems[i].ensureVisibility)
          this.elems[i].ensureVisibility();
      }

    }
    if (this.editMode) controller.focusTabFirst();
  }
  return true;
}

/**
 * Checa se a aba esta visível. 
 */
HTMLTab.prototype.getVisible = function() {
  return isVisibleDiv(this.content);
}

/**
 * Torna a aba invisível no contexto.
 */
HTMLTab.prototype.unSelect = function() {
  if (!isVisibleDiv(this.content))
    return false;

  this.selected = false;
  this.unMark(this.content);
  visibleDiv(this.div, false);

  return true;
}

/**
 *
 */
HTMLTab.prototype.mark = function(c) {
  if (c) {	
	  if (c.getAttribute) {
	    if (c.getAttribute('src') && c.getAttribute('src').length > 0 && c.getAttribute('src').indexOf('_sel') == -1) c.setAttribute('src', c.getAttribute('src').replace('.gif', '_sel.gif'));
	    if (c.getAttribute('background') && c.getAttribute('background').length > 0 && c.getAttribute('background').indexOf('_sel') == -1) c.setAttribute('background', c.getAttribute('background').replace('.gif', '_sel.gif'));
	  }
	  for (var i=0;i<c.childNodes.length;i++)
	    HTMLTab.prototype.mark(c.childNodes.item(i));
  }	    
}

/**
 * Disparado pelo evento 'onMouseOut' da aba, muda o background da mesma. 
 */
HTMLTab.prototype.unMark = function(c) {
  if (c) {	
	  if (c.getAttribute) {
	    if (c.getAttribute && c.getAttribute('src') && c.getAttribute('src').length > 0) c.setAttribute('src', c.getAttribute('src').replace('_sel.gif', '.gif'));
	    if (c.getAttribute && c.getAttribute('background') && c.getAttribute('background').length > 0) c.setAttribute('background', c.getAttribute('background').replace('_sel.gif', '.gif'));
	  }
	  for (var i=0;i<c.childNodes.length;i++)
	    HTMLTab.prototype.unMark(c.childNodes.item(i));
  }	    
}

/**
 * Disparado pelo evento 'onMouseOver' da aba, muda o background da mesma. 
 */
HTMLTab.prototype.markOver = function(o) {
    for (var i=0;i<o.childNodes.length;i++) {
      var c = o.childNodes.item(i);
      if (c.getAttribute) {
        if (c.getAttribute('src') && c.getAttribute('src').length > 0 && c.getAttribute('src').indexOf('_down') == -1) c.setAttribute('src', c.getAttribute('src').replace('.gif', '_sel.gif'));
        if (c.getAttribute('background') && c.getAttribute('background').length > 0 && c.getAttribute('background').indexOf('_down') == -1) c.setAttribute('background', c.getAttribute('background').replace('.gif', '_sel.gif'));
      }
      HTMLTab.prototype.markOver(c);
    }
}
/**
 * Evento 'onMouseOver' da aba.
 */
HTMLTab.prototype.onMouseOver = function(e, elem) {
  if (!this.selected)
    this.markOver(elem);
}

/**
 * Evento 'onMouseOut' da aba.
 */
HTMLTab.prototype.onMouseOut = function(e, elem) {
  if (!this.selected)
    this.unMark(elem);
}

/**
 * Remove eventos da aba.
 */
HTMLTab.prototype.flush = function() {
  for (var i in this) {
    if (this[i]) {
      removeEvents(this[i]);
    }
  }
}

/**
 * Remove a aba e a div que a mesma esta inserida.
 */
HTMLTab.prototype.free = function(notRemoveFromDoc) {
  if (this.parent && this.parent.div)
    this.parent.div.removeChild(this.div);

  if (this.tab && this.tab.parentNode)
    this.tab.parentNode.removeChild(this.tab);
  return this;
}
