﻿/**
 * pour memoire:
 * - !document.all renvoie false pour IE, true pour FF
 * - display: block; fonctionne sur les table avec IEx et FF2
 *
 * Variables définies au niveau du html:
 * @global treeNode currentNode noeud correspondant à la page en cours
 *                              null pour la page d'accueil
 * @global String   dataPath    chemin relatif de la racine des données
 * @global String   imgPath     chemin relatif des images
 *
 * @version $Id:: nav.js 10315 2011-11-10 16:00:05Z sanchop                    $
 */

// TODO: ...
// - construction sur demande du DOM nav (pour les très gros projet)
// - placement de tout le matos nav dans un objet nav
//

// indexOf n'est pas implemente dans IE
if (!Array.prototype.indexOf) {
    /**
     * Recherche l'index d'une valeur dans un tableau
     *
     * @param mixed val valeur a tester
     *
     * @return Boolean
     */
    Array.prototype.indexOf = function(elt)
    {
        var len = this.length;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0) {
            from += len;
        }

        for (; from < len; from++) {
            if (from in this && this[from] === elt) {
                return from;
            }
        }
        return -1;
    };
}

/**
 * Recherche une valeur dans un tableau
 *
 * @param mixed val valeur a tester
 *
 * @return Boolean
 */
Array.prototype.inArray = function(val)
{
    for(var i = 0, l = this.length; i < l; i++) {
        if (this[i] == val) {
            return true;
        }
    }
    return false;
}

/**
 * Retire une valeur dans un tableau
 *
 * @param mixed val valeur a tester
 *
 * @return void
 */
Array.prototype.removeValue = function(val)
{
    var i = this.indexOf(val);
    if (i >= 0) {
        this.splice(i, 1);
    }
}

/**
 * Verifie si un className contient un nom de classe specifie
 *
 * @param string val nom de la classe
 *
 * @return Boolean
 */
String.prototype.hasClass = function(val)
{
    var classArr = this.split(' ');
    return classArr.inArray('val');
}

/**
 * Retire une classe du className
 *
 * @param string val nom de la classe a retirer
 *
 * @return string
 */
String.prototype.removeClass = function(val)
{
    var classArr = this.split(' ');
    classArr.removeValue(val);
    return classArr.join(' ');
}

/**
 * Ajoute une classe au className
 *
 * @param string val nom de la classe
 *
 * @return string
 */
String.prototype.insertClass = function(val)
{
    var classArr = this.split(' ');
    classArr.splice(0, 0, val);
    return classArr.join(' ');
}

/**
 * Interaction
 *
 * @param Event evenement event declenchant l'appel
 *
 * @return void
 */
function toggleN1(evenement)
{
    if (context!='preview') {
        evenement = (evenement) ? evenement : ((event) ? event : null);
        var trigger = (evenement.target)
            ? evenement.target : evenement.srcElement;
        if (trigger.nodeType == 3) {
            trigger = trigger.parentNode;
        }
        if (trigger.nodeName == 'TD') {
            trigger = trigger.parentNode;
        }
        var classArr = trigger.className.split(' ');
        var target = trigger.nextSibling;
        if (target.style.display == '') {
            trigger.className = trigger.className.removeClass('n1unfold');
            target.style.display = 'none';
        } else {
            trigger.className = trigger.className.insertClass('n1unfold');
            target.style.display = '';
        }
    }
}

/**
 * Interaction
 *
 * @param Event evenement event declenchant l'appel
 *
 * @return void
 */
function toggleSubFolder(evenement)
{
    if (context!='preview') {
        evenement = (evenement) ? evenement : ((event) ? event : null);
        var trigger = (evenement.target)
            ? evenement.target : evenement.srcElement;
        if (trigger.nodeType == 3) {
            trigger = trigger.parentNode;
        }
        var target = trigger.nextSibling;
        if (target.style.display == "") {
            trigger.className = "folderTitle navDossierFold";
            target.style.display = "none";
        } else {
            trigger.className = "folderTitle subFolderUnfold";
            target.style.display = "";
        }
    }
}

/**
 * initialise les variables globales de la nav
 *
 * @param String rootPubPath URL relative vers la racine de la publication
 *
 * @return void
 */
function navInit(rootPubPath)
{
    dataPath = rootPubPath + '_data/';
    imgPath = rootPubPath + 'img/';
    if (context == 'backoffice' || context == 'direct') {
        // publication HTML
        navLinkPrefix = dataPath;
        navLinkSuffix = '.html';
    } else if (context == 'frontoffice') {
        // publication XML habillé
        var scriptExt;
        if (engine == 'php') {
            scriptExt = 'php';
        } else {
            scriptExt = 'aspx';
        }
        navLinkPrefix = 'page.' + scriptExt + '?fichierXml=' + dataPath;
        navLinkSuffix = '.xml&fichierXsl=../xslt/start_mis.xsl';
    } else {
        // prévisu
        navLinkPrefix = 'javascript:void(0) /*';
        navLinkSuffix = '*/';
    }
}

/**
 * jumpTo() calcule le lien direct et redirige vers celui-ci
 *
 * @param String id ID du treeNode vers lequel se rediriger.
 *
 * @return void
 */
function jumpTo(id) {
    document.location.href = navLinkPrefix + tree[id].getPath() + navLinkSuffix;
}

/**
 * construit les objets html nécessaires pour la nav
 *
 * @param Element navContainer element html contenant la nav
 *
 * @return void
 */
function makeNav(navContainer)
{
    var table = document.createElement('table');
    navContainer.appendChild(table);
    var col = document.createElement('col');
    table.appendChild(col);
    col.className = 'picto';
    var col = document.createElement('col');
    table.appendChild(col);
    var tbody = document.createElement('tbody');
    table.appendChild(tbody);
    for (var i = 0, l = pubRoot.children.length; i < l; i++) {
        addNavNodeN1(tbody, pubRoot.children[i]);
    }
}

/**
 * ajoute un noeud N1 dans la nav
 *
 * @param Element  container element html contenant dans lequel ajouter
 *                           le fragment html
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavNodeN1(container, treeNode)
{
    if (treeNode.show) {
        if (treeNode.type < 4) {
            addNavFolderNodeN1(container, treeNode);
        } else {
            addNavResourceNodeN1(container, treeNode);
        }
    }
}

/**
 * ajoute un noeud N1 de type folder|doc|section à la nav
 *
 * @param Element  container element contenant dans lequel ajouter le titre et
 *                           la descendance
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavFolderNodeN1(container, treeNode)
{
    // TR
    var trTitle = document.createElement('tr');
    container.appendChild(trTitle);
    trTitle.className = 'n1';
    // TD picto
    var td = document.createElement('td');
    trTitle.appendChild(td);
    td.className = 'picto';
    // TD titre
    var tdTitle = document.createElement('td');
    trTitle.appendChild(tdTitle);
    tdTitle.className = 'title';
    tdTitle.appendChild(document.createTextNode(treeNode.name));
    // traitement de la descendance
    if (treeNode.hasShownChildren()) {
        trTitle.onclick = toggleN1;
        trTitle.style.cursor = 'pointer';
        // Créer le TR/TD descendance
        var trContent = document.createElement('tr');
        container.appendChild(trContent);
        trContent.className = 'n1content';
        var tdContent = document.createElement('td');
        trContent.appendChild(tdContent);
        tdContent.colSpan = 2;
        if (treeNode.isAncestorOf(currentNode)) {
            trTitle.className += ' n1unfold';
            tdTitle.className += ' titleCurrent';
            trContent.style.display = '';
        } else {
            trContent.style.display = 'none';
        }
        for (var i = 0, l = treeNode.children.length; i < l; i++) {
            addNavNode(tdContent, treeNode.children[i]);
        }
    } else {
        // ne rien faire
    }
    // TR/TD de separation
    var tr = document.createElement('tr');
    container.appendChild(tr);
    tr.className = 'n1sep';
    var td = document.createElement('td');
    tr.appendChild(td);
    td.colSpan = 2;
}

/**
 * ajoute un noeud N1 de type topic|unit à la nav
 *
 * @param Element  container element contenant dans lequel ajouter le titre et
 *                           la descendance
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavResourceNodeN1(container, treeNode)
{
    // TR
    var trTitle = document.createElement('tr');
    container.appendChild(trTitle);
    trTitle.className = 'n1 n1empty';
    // TD picto
    var td = document.createElement('td');
    trTitle.appendChild(td);
    td.className = 'picto';
    // TD titre
    var tdTitle = document.createElement('td');
    trTitle.appendChild(tdTitle);
    tdTitle.className = 'title';
    if (treeNode == currentNode) {
        tdTitle.appendChild(document.createTextNode(treeNode.name));
        tdTitle.className += ' titleCurrent';
    } else {
        // création du lien
        aLink = document.createElement('a');
        tdTitle.appendChild(aLink);
        aLink.appendChild(document.createTextNode(treeNode.name));
        if (treeNode.type == 6) {
            aLink.href = dataPath + treeNode.getPath();
        } else {
            aLink.href = navLinkPrefix + treeNode.getPath() + navLinkSuffix;
        }
    }
    // TR/TD de separation
    var tr = document.createElement('tr');
    container.appendChild(tr);
    tr.className = 'n1sep';
    var td = document.createElement('td');
    tr.appendChild(td);
    td.colSpan = 2;
}

/**
 * ajoute un noeud dans la nav
 *
 * @param Element  container element html contenant dans lequel ajouter
 *                           le fragment html
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavNode(container, treeNode)
{
    if (treeNode.show) {
        if (treeNode.type < 4) {
            addNavFolderNode(container, treeNode);
        } else {
            addNavResourceNode(container, treeNode);
        }
    }
}

/**
 * ajoute un noeud de type folder|doc|section à la nav
 *
 * @param Element  container element contenant dans lequel ajouter le titre et
 *                           la descendance
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavFolderNode(container, treeNode)
{
    // le titre
    // création du P titre
    var elementP = document.createElement('p');
    container.appendChild(elementP);
    elementP.className = 'folderTitle';
    elementP.appendChild(document.createTextNode(treeNode.name));
    // traitement de la descendance
    if (treeNode.hasShownChildren()) {
        elementP.onclick = toggleSubFolder;
        elementP.style.cursor = 'pointer';
        // Créer le DIV descendance
        var elementDiv = document.createElement('div');
        elementDiv.className = 'navDossierContenu';
        container.appendChild(elementDiv);
        if (treeNode.isAncestorOf(currentNode)) {
            elementP.className += ' subFolderUnfold';
            elementDiv.style.display = 'block';
        } else {
            elementP.className += ' navDossierFold';
            elementDiv.style.display = 'none';
        }
        for (var i = 0, l = treeNode.children.length; i < l; i++) {
            addNavNode(elementDiv, treeNode.children[i]);
        }
    } else {
        elementP.className += ' subFolderEmpty';
    }
}

/**
 * ajoute un noeud de type topic|unit à la nav
 *
 * @param Element  container element contenant dans lequel ajouter le titre et
 *                           la descendance
 * @param treeNode treeNode  noeud à ajouter
 *
 * @return void
 */
function addNavResourceNode(container, treeNode)
{
    // création du P titre
    var elementP = document.createElement('p');
    if (treeNode == currentNode) {
        elementP.className = 'navRessourceCourante';
    } else {
        elementP.className = 'navRessource';
    }
    if (treeNode.getIndex() % 2) {
        elementP.className += ' navOdd';
    }
    container.appendChild(elementP);
    if (treeNode == currentNode) {
        elementP.appendChild(document.createTextNode(treeNode.name));
    } else {
        // création du lien
        elementA = document.createElement('a');
        elementP.appendChild(elementA);
        elementA.appendChild(document.createTextNode(treeNode.name));
        if (treeNode.type == 6) {
            elementA.href = dataPath + treeNode.getPath();
        } else {
            elementA.href = navLinkPrefix + treeNode.getPath() + navLinkSuffix;
        }
    }
}

/**
 * Crée un tableau html avec entête
 *
 * @param Element container  Objet html contenant le tableau
 * @param String  styleClass Classe CSS
 * @param Array   header     (facultatif) libellés de l'entête
 *
 * @return Element Objet TBODY
 */
function addTable(container, styleClass, header)
{
    var elementTable, elementThead, elementTbody, elementTr, elementTh;

    // création du TABLE
    elementTable = document.createElement('table');
    container.appendChild(elementTable);
    elementTable.className = styleClass;
    // création du THEAD si nécessaire
    if (header) {
        elementThead = document.createElement('thead');
        elementTable.appendChild(elementThead);
        elementTr = document.createElement('tr');
        elementThead.appendChild(elementTr);
        for (var i = 0, l = header.length; i < l; i++) {
            elementTh = document.createElement('th');
            elementTr.appendChild(elementTh);
            elementTh.appendChild(document.createTextNode(header[i]));
        }
    }
    // création du TBODY
    elementTbody = document.createElement('tbody');
    elementTable.appendChild(elementTbody);
    return elementTbody;
}
