/* $Id: module-ead-xslt.js 12611 2008-10-29 09:28:02Z jcwiklinski $ */
/**
Copyright (C) 2003-2008 AJLSM, Anaphore
Voir le fichier LICENCE
**/
/* Ce fichier de configuration fait partie de la distribution standard
de Pleade. Vous pouvez le modifier à votre guise. */
/*
	Code Javascript propre à la fenêtre de consultation des documents EAD.

	Les variables globales suivantes sont déclarées directement dans la page HTML:
		archdescID
		eadid
		mode
*/

// Enregistrer la fonction d'initialisation et de redimensionnement
Event.observe(window, 'load', init);
Event.observe(window, 'resize', adjustHeight);

/**
*	Initialisation une fois la page chargée.
*/
function init(){
	// On initialise la hauteur
	adjustHeight();
	// On initialise les onglets
	initTabs();
	// On charge le contenu principal en Ajax (qid est une variable globale déclarée dans le html cf. ead2html-index.xsl, peut être une chaine vide)
	loadContent(archdescID, true, qid);
	// On initialise la table des matières et des index
	initToc();
	//initIndex();	// TODO: seulement lorsqu'on clique sur l'onglet?
	var qidParam = ""
	if(!qid.blank() && qid!=null) qidParam = "?qid=" + qid;
	initTreeView("pl-pgd-index", "functions/ead/get-index/" + eadid + "/pleade-index.json" + qidParam);
}

/**
*	Dimensionnement de la page.
*/
function adjustHeight() {
	var above = Position.cumulativeOffset($("pl-pg-body-main-lcol"))[1];
	// FIXME: d'où vient le pixel ?
	var below = getHeight($("pl-pg-footer"), true) + getHeight($("pl-pg-brdr-b"), true)  + getHeight($("pl-pg-brdr-b"), true) + getHeight($("pl-pg-body-bottom"), true) + parseInt($("body").getStyle("margin-bottom")) + parseInt($("body").getStyle("padding-bottom")) + 1;
	var h = YAHOO.util.Dom.getClientHeight() - above - below;
  /* DEBUG (MP) Ecart de 4px entre IE Firefox (en trop dans IE) du a un above different
  alert("h:"+h+
        "\nabove:"+Position.cumulativeOffset($("pl-pg-body-main-lcol"))[1]+
        "\npl-pg-footer:"+getHeight($("pl-pg-footer"), true)+
        "\npl-pg-brdr-b:"+getHeight($("pl-pg-brdr-b"), true)+
        "\npl-pg-body-bottom:"+getHeight($("pl-pg-body-bottom"), true)+
        "\nbody.margin-bottom:"+parseInt($("body").getStyle("margin-bottom"))+
        "\nbody.padding-bottom:"+parseInt($("body").getStyle("padding-bottom"))+
        "\ngetClientHeight:"+YAHOO.util.Dom.getClientHeight()
        );
  */
  setTotalHeight($("pl-pg-body-main-lcol"), h);
	$("pl-pg-body-main-lcol").setStyle( {overflow: "auto"} );
	setTotalHeight($("tabs"), h);
	setTotalHeight($("pl-pg-body-main-hdl-bg"), h);
  // Petit travail sur le coeur : si on a un conteneur EAD, on le prend. sinon
  // on utilise le coeur de page.
  var mcol = $("pl-pg-body-main-mcol");
  setTotalHeight(pgd, h);
  var pgd = $("pl-pgd-cnt");
  var tlbx = $("pl-pg-body-tool-box");
  var pgdh=h;
  if(tlbx){
    pgdh -= getHeight(tlbx, true);
  }
  if(pgd!=null){
    setTotalHeight(pgd, pgdh);
    pgd.setStyle( {overflow: "auto"} );
    if (mcol!=null){
      mcol.setStyle( {overflow: "hidden"} );
    }
  }
  else{
    mcol.setStyle( {overflow: "auto"} );
  }
}

/**
*	Initialisation des onglets avec YUI.
*/
function initTabs(){
	// On ne fait que créer un objet qu pointe sur l'ID du div
	var tabs = new YAHOO.widget.TabView("tabs");
}

/**
*	Chargement du contenu principal en Ajax.
*	@param {String} L'identifiant du fragment à charger par défaut, s'il n'y a pas de # dans l'URL
*/
function loadContent(defaultFragmentID, checkC, qid){
	// une variable qui contient la partie de querystring sur le qid (est vide si qid vide)
	var qidParam = "";
	//DEBUG alert('qid:'+ qid + '\ncheckC:'+ checkC + '\ndefaultFragmentID:' + defaultFragmentID);
	if(qid!=null && !qid.blank())
		qidParam = "&qid=" + qid;
	// On indique qu'on va charger du contenu
	startFragmentLoading();
	// L'URL à appeler diffère selon qu'on est en statique ou dynamique
	if (mode == "static") {
		new Ajax.Updater('pl-pg-body-main-mcol', "fragments/" + getfragmentID(defaultFragmentID, checkC) + '.html' + qidParam, {
			method: 'get',
            evalScripts: true,
			onComplete: stopFragmentLoading
		});
	}
	else {
		new Ajax.Updater('pl-pg-body-main-mcol', "ead-fragment.xsp?c=" + getfragmentID(defaultFragmentID, checkC) + qidParam , {
			method: 'get',
            evalScripts: true,
			onComplete: stopFragmentLoading
		});
	}
}

/**
*	Retourne l'identifiant d'un fragment à afficher.
*	@param {String} defaultFragmentID	Celui retourné si on ne trouve rien d'autre.
*/
//TODO: comprendre ceci...
function getfragmentID(defaultFragmentID, checkC){
	if (!checkC) return defaultFragmentID;
	var url = window.location.href;
	// FIXME: les lignes concernant le hash (#) sont commentées, mais
	// elles pourraient probablement être supprimées
	//var hash = window.location.hash;
	//var identifier
	//if (hash.indexOf("?") == -1) { identifier = hash.substring( 1, hash.length) }
	//else { identifier = hash.substring( 1, hash.indexOf("?") ) }
	var query = url.toQueryParams();
	//if (identifier == undefined || identifier == ""){
	if(query['c'] == undefined){
		return defaultFragmentID
	}
	else { return query['c'] }
	//}
	//else { return identifier }
}

/**
	Initialisation d'un TreeView, qui peut être la table des matières ou
	une liste d'index.
*/
function initTreeView(elementId, url) {

	// L'arbre YUI
	var tvRoot = (new YAHOO.widget.TreeView(elementId)).getRoot();

	// On appelle la fonction qui demande des noeuds
	jsonTreeViewHandler(tvRoot, null, url, true);

}

/**
*	Fonction qui permet de charger des noeuds de l'arbre depuis des fichiers JSON.
*	Elle est appelée comme un callback par YUI.
*	@param node {Node} Le noeud du Treeview concerné
*	@param fnLoadComplete {function} La fonction à appeler une fois terminé de charger
*/
function jsonTreeViewHandler(parent, fnLoadComplete, url, draw) {
	var realUrl = url;
	if ( !realUrl ) realUrl = parent.href;
	var req = new Ajax.Request(realUrl, {
			method: "get",
			onSuccess: function(r) { // mettre dans une variable type function à part ?
				// On reçoit un objet ou un ensemble d'objets
				var obj = r.responseText.evalJSON();
				var entries = $A(obj);
				if (!entries[0]) entries[0] = obj;	// Si jamais on a une seule entrée, $A est un Array mais sans entrée
				// On boucle sur les objets obtenus et on construit pour chacun un noeud dans l'arbre
				entries.each(function(n) {
					var newNode = new YAHOO.widget.TextNode(n.label, parent, false);
					if (n.href) { // Il pourrait ne pas y avoir de lien
						newNode.href = n.href;
						if ( n.nb && n.nb > 1 ) {
							// On doit faire une recherche TODO
							newNode.onLabelClick = onLabelClickIndexMultiple;
						}
						else if (n.nb && n.nb == 1) {
							// On doit lier directement
							newNode.onLabelClick = onLabelClickIndexSingle;
						}
						else {
							newNode.onLabelClick = onLabelClickDoNothing;
						}
					}
					if (n.hasChildren) newNode.setDynamicLoad(jsonTreeViewHandler);
					if (fnLoadComplete) fnLoadComplete();
				});
				if (draw) parent.tree.draw();
			}
		}
	);
}

/**
*	Fonctions appelée lorsqu'on clique sur un libellé dans un index mais pour lequel
*	il ne faut pas suivre de lien, par exemple le nom d'un index.
*/
function onLabelClickDoNothing(n) {
	return false;
}

/**
*	Fonction appelée lorsqu'on clique sur un libellé d'un terme d'index avec plusieurs occurrences
*	@param tmpNode {Node} Le noeud concerné.
*/
function onLabelClickIndexMultiple(tmpNode){
	updateDocumentResults("pl-pg-body-main-mcol", tmpNode.href);
	/* new Ajax.Updater('pl-pg-body-main-mcol', tmpNode.href, {
		method: 'get',
		evalScripts: true,
		onComplete: stopFragmentLoading
	}); */
	return false ;
}
/**
*	Fonction appelée lorsqu'on clique sur un libellé d'un terme d'index
*	@param tmpNode {Node} Le noeud concerné.
*/
function onLabelClickIndexSingle(tmpNode){
	loadFragment(tmpNode.href);
	return false ;
}
/**
*	Chargement du contenu d'un fragment en Ajax
*	@param {String} L'identifiant du fragment à charger
*/
function loadFragment(url){
	// On indique qu'on va charger du contenu
	startFragmentLoading();
	new Ajax.Updater('pl-pg-body-main-mcol', url, {
		method: 'get',
		onComplete: stopFragmentLoading
	});
}

/**
*	Fonction appelée à la fin du chargement d'un fragment.
*/
function stopFragmentLoading() {
	$("body").setStyle({cursor: 'auto'});
	adjustHeight();
	initAcronyms();
}

/**
	Initialisation de la liste des index.
*/
function initIndex() {
	// L'arbre YUI et sa racine
	var tvIndex = new YAHOO.widget.TreeView("pl-pgd-index");
	var tvIndexRoot = tvIndex.getRoot() ;

	// On affiche immédiatement les entrées de premier niveau depuis le fichier {eadid}.json
	// L'URL diffère selon le mode
	var url = "index/" + eadid + ".json" ;	// Mode statique TODO
	if ( mode == "dyn") { url = "functions/ead/get-index/" + eadid + "/pleade-index.json" }
	// On va chercher le fichier JSON en Ajax
	var req = new Ajax.Request(url, {
			method: "get",
			onSuccess: function(transport) {
				// On boucle sur les noeuds reçus et on construit un noeud YUI pour chacun
				$A(transport.responseText.evalJSON()).each(function(n, i) {
					var tmpNode = new YAHOO.widget.TextNode(n.label, tvIndexRoot, false);
					tmpNode.href = n.href;
					tmpNode.onLabelClick = onLabelClick;
					if(n.hasChildren == true){tmpNode.setDynamicLoad(loadNode);} // FIXME (MP) : Impossible que cela fonctionne : loadNode est une fonction attachee au sommaire, pas les index !
				});
				tvIndex.draw();
				// FIXME : si on mets tvIndex.draw() plus bas ça ne marche plus !!! (il l'exécute en premier avant l'ajax !)
			}
		}
	);
}

/**
*	Initialisation de la table des matières.
*/
function initToc() {
	// L'arbre YUI et sa racine
	tvToc = new YAHOO.widget.TreeView("pl-pgd-toc");
	var tvTocRoot = tvToc.getRoot() ;

	// On affiche immédiatement les entrées de premier niveau depuis le fichier {eadid}.json
	// L'URL diffère selon le mode
	var url = "toc/" + eadid + ".json" ;	// Mode statique
	if ( mode == "dyn") { url = "functions/ead/get-toc-fragment/" + eadid + "/" + eadid +".json" }
	// On va chercher le fichier JSON en Ajax
	var req = new Ajax.Request(url, {
			method: "get",
			onSuccess: function(transport) {
				// On boucle sur les noeuds reçus et on construit un noeud YUI pour chacun
				$A(transport.responseText.evalJSON()).each(function(n, i) {
					var tmpNode = new YAHOO.widget.TextNode(n.label, tvTocRoot, false);
					tmpNode.href = n.href;
					tmpNode.onLabelClick = onLabelClick;
					if(n.hasChildren == true){tmpNode.setDynamicLoad(loadNode);}
				});
				tvToc.draw();
				// FIXME : si on mets tvToc.draw() plus bas ça ne marche plus !!! (il l'exécute en premier avant l'ajax !)
			}
		}
	);
}

/**
*	Fonction qui permet de charger des noeuds de l'arbre depuis des fichiers JSON.
*	Elle est appelée comme un callback par YUI.
*	@param node {Node} Le noeud du Treeview concerné
*	@param fnLoadComplete {function} La fonction à appeler une fois terminé de charger
*/
function loadNode(node, fnLoadComplete) {
	// L'URL à appeler diffère selon le mode FIXME: rationaliser avec l'autre utilisation
	var url = "toc/" + node.href.gsub('\.html','.json');
	if ( mode == "dyn") { url = "functions/ead/get-toc-fragment/" + eadid + "/" + node.href.gsub('\.html','.json') }
	// On appelle le chargement en Ajax
	var req = new Ajax.Request(url, {
			method: "get",
			onSuccess: function(transport) { // mettre dans une variable type function à part ?
				// On boucle sur les noeuds obtenus et on construit pour chacun un noeud dans l'arbre
				var obj = transport.responseText.evalJSON();
				var entries = $A(obj);
				if (!entries[0]) entries[0] = obj;	// Si jamais on a une seule entrée, $A est un Array mais sans entrée
				entries.each(function(n, i) {
					var tmpNode = new YAHOO.widget.TextNode(n.label, node, false);
					tmpNode.href = n.href;
					tmpNode.onLabelClick = onLabelClick ;
					if(n.hasChildren == true){tmpNode.setDynamicLoad(loadNode);}
					if ( fnLoadComplete ) {
						fnLoadComplete();
					}
				});
			}
		}
	);
}

/**
*	Fonction appelée lorsqu'on clique sur un libellé dans la table des matières.
*	@param tmpNode {Node} Le noeud concerné.
*
*	FIXME: une fois qu'on aura des HTMLNode, ce ne sera plus appelé
*/
var onLabelClick = function(tmpNode){
	if ( tmpNode.href.indexOf('?') < 0 ) {
		// Le fragment dépend du href
		var fragmentID = tmpNode.href.gsub('\.html','');
		// On le charge
		loadContent(fragmentID, false, qid); // qid variable globale déclarée dans ead2html-index.xsl (peut etre vide)
		// TODO: il faudrait déplier l'arbre ici...
	}
	return false ;
}
var hs = new Array(); // Un tableau contenant les hauteurs de notice
var cs = new Array(); // Un tableau contenant les notices eac recuperees
var toggleEacBlock = function(eacId, cible){
  if(!eacId) return false;
  if(!cible) cible=$('divEadDoc_'+eacId);
  if(!cible) cible=$$('div.div-eac-doc')[0];
  if(!cible) return false;

  // Masquer
  if(cible.visible())
  {
    // Masquage non anime
    // cible.hide();
    // Pour animer le masquage
    if ( hs && !hs[cible.id] ) {
      var h = getHeightForAnim(cible);
      hs[cible.id] = h;
    }
    var d = 300;
    var anim = new YAHOO.util.Anim(cible, {height: {to: 0}}, d/1000, YAHOO.util.Easing.EaseOut);
    anim.animate();
    setTimeout(function() {cible.hide();adjustHeight();}, d+20);
  }

  // Afficher
  else
  {

    var childs = cible.childElements();
    if(cs && cs[cible.id] && childs!=null && childs.size() > 1)
    {
      // le doc est deja la
      animateEacBlock(cible);
    }
    else
    {

      new Ajax.Updater(cible, "eac.ajax?id="+eacId, {
        method: 'get',
        insertion: Insertion.Bottom,
        onCreate: startEacBlockLoading(cible),
        onComplete: stopEacBlockLoading(cible)
      });
    }

  }

  return true;

}

var getHeightForAnim = function(cible){
  if (!cible) return null;
  var h = cible.getHeight();
  try{
    var prev = cible.previous();
    if (prev) h+= prev.getHeight();
  } catch(e){}
  return h;
}

var startEacBlockLoading = function(cible){
}
var stopEacBlockLoading = function(cible){
  return function(){
    cs[cible.id]=true;
    animateEacBlock(cible);
    // $("body").setStyle({cursor: 'default'});
  }
}

var animateEacBlock = function(cible){
  // Affichage non anime
  // cible.show();
  // Pour animer l'affichage
  var h;
  if (!hs[cible.id])
    h = getHeightForAnim(cible);
  else
    h = hs[cible.id];
  cible.setStyle({height: '1px'});
  var anim = new YAHOO.util.Anim(cible, {height: {from: 0, to: h}}, 0.5, YAHOO.util.Easing.EaseOut);
  anim.animate();
  cible.show();
  adjustHeight();
}

