// Requiert util.js

/** 
 * @class
 * Pour l'utiliser :
 * On cree un tableau HTML qui a exactement 2 tr.
 * Le premier tr contient des th, un par titre d'onglet.
 * Le deuxieme tr contient un seul td (avec colspan = nombre d'onglets),
 * qui contient autant de div que d'onglets.
 * On donne un id au tableau, et en JavaScript on ecrit juste :
 * mesOnglets = new TabbedPane(idDuTableau, cssClasses);
 *
 * @constructor
 * @param idTable id du table qui contient les onglets
 * @param cssClasses objet pouvant avoir 3 proprietes :<ul>
 * <li>foreground (classe CSS de l'onglet d'avant plan), 
 * par defaut tabbedPaneOn</li>
 * <li>background (celle des onglets en arriere-plan), 
 * par defaut tabbedPaneOff</li>
 * <li>content (celle de la zone de detail), par defaut 
 * tabbedContent</li></ul>
 */

function TabbedPane(idTable, cssClasses) {
  // Elements du bloc d'onglets
  /** id du table qui contient les onglets @type String */
  this.id = idTable;
  /** Elément table contenant les onglets */
  this.root = document.getElementById(idTable);
  /** Onglets */
  this.tabs = null;
  /** Zone de contenu */
  this.content = null;
  /** Eléments div contenant le détail pour chaque onglet */
  this.divs = null;
  
  // Les classes CSS
  var cssClasses = (cssClasses) ? cssClasses : new Object();
  /** Classe CSS de l'onglet sélectionné (en avant-plan) */
  this.foregroundClass = cssClasses.foreground || "tabbedPaneOn";
  /** Classe CSS des onglets non sélectionnés (en arriere-plan) */
  this.backgroundClass = cssClasses.background || "tabbedPaneOff";
  /** Classe CSS de la zone de contenu */
  this.contentClass = cssClasses.content || "tabbedPaneContent";
  // Calculer tabs, content et divs
  this.setTabsAndDivs();
  // Specifier la reaction des onglets aux clics
  this.setBehaviour();
  // Ajuster l’apparence
  this.setLayout();
  // Selectionner le premier onglet
  this.setTab(0);
  // Faire du premier onglet l'onglet courant ou celui 
  // figurant dans l'url sous la forme #idTable_noOnglet
  // Fonctionne mal dans Mozilla : quand on change de page et
  // revient, ne garde pas le bon onglet dans l'url
  var id = window.location.hash;
  var regexp = new RegExp("^#" + this.id + "_\\d+$");
  var no = (id && regexp.test(id)) ?  id.substr(this.id.length+2) : 0;
  this.setTab(1);
}


TabbedPane.prototype = {
  /** Verifier que le tableau a la forme requise :
   * 2 tr, et autant de th dans le 1er tr que de divs dans le td
   * de la 2e ligne, celui-ci ayant un colspan egal au nombre de th
   */
  setTabsAndDivs: function() {
  	var tBody = Element.getChildElements(this.root, "tbody")[0];
  	if (Element.getChildElements(tBody, "tr").length != 2) {
  		Log.error("Table " + this.id + " must have 2 'tr'");
  	}
  	// Les onglets
  	var headerRow = Element.getChildElements(tBody, "tr")[0];
  	this.tabs = Element.getChildElements(headerRow, "th");
  	// Le td de contenu
  	var bodyRow = Element.getChildElements(tBody, "tr")[1];
  	var tds = Element.getChildElements(bodyRow, "td");
  	if (tds.length != 1) {
  		Log.error("Table " + this.id + 
        " must have in its 2d 'tr' a single 'td'");
  	}
  	// Les contenus correspondants
  	this.content = tds[0]
  	this.divs = Element.getChildElements(this.content, "div");
  	if (this.tabs.length != this.divs.length) {
  		Log.error("Table " + this.id + " must have as many 'th'"
        + " in 1rst 'tr' as 'div' in the 'td' of the 2d 'tr'");
  	}
  },

  /** Specifie l'apparence des onglets, en fonction des styles CSS */
  setLayout: function() {
    this.root.setAttribute("cellspacing", 0);
    this.root.cellSpacing = "0";
  	// Meme largeur pour tous les onglets
  	for (var i=0 ; i<this.tabs.length ; i++) {
  		this.tabs[i].style.width = Math.round(100/this.tabs.length) + "%";
  		this.tabs[i].style.cursor = "pointer";
  	}
  	// La zone de contenu
  	this.content.className = this.contentClass;
    // Forcer son colspan au nb d'onglets
  	this.content.setAttribute("colspan", this.divs.length);
  	// Ceci pour IE qui ignore le setAttribute sur colspan
  	this.content.colSpan = this.divs.length;
    // Dimensionner le td de contenu au dimensions max des div
    var height = 0, width = 0, display;
    for (i=0 ; i<this.divs.length ; i++) {
      // Hauteur quand l'onglet i est selectionne
      this.setTab(i);
      if (this.content.offsetHeight > height) {
        height = this.content.offsetHeight;
      }
      if (this.content.offsetWidth > width) {
        width = this.content.offsetWidth;
      }
    }
    this.content.style.height = height;
    this.content.style.width = width;
  },

  /** Faire reagir les onglets aux clics */
  setBehaviour: function() {
	//Mémoriser le tabbedPane courant pour les onclick
	var tabbedPane = this;
	for (var i=0; i<this.tabs.length; i++) {
	  //Mémoriser dans le th (longlet) son rang
	  this.tabs[i].setAttribute("index", i);
	  //La réaction de l'onglet
	  this.tabs[i].onclick = function() {
		//Ici this désigne le th
		tabbedPane.setTab(this.getAttribute("index"));
	  }
	}
  },

  /** Mettre en avant-plan l'onglet de rang index
   * (et en arriere-plan tous les autres) 
   * @param index index de l'onglet à sélectionner
   */
  setTab: function(index) {
	//Mettre l'onglet cliqué au style avant-plan
	this.tabs[index].className = this.foregroundClass+index;
	//Montrer le div correspondant
	this.divs[index].style.display = "block";
	//Mettre les autres onglets à un style arrière-plan
	for (var i=0; i<this.tabs.length; i++) {
	  if (i != index) {
		this.tabs[i].className = this.backgroundClass+i;
		//Masquer le contenu correspondant
		this.divs[i].style.display = "none";
	  }
	}
  }
};


TabbedPane.prototype.constructor = TabbedPane;





