/** @fileoverview Script de load des librairies YUI
 * <pre>
 * Permet egalement de loader d'autres librairies (plugins ou perso)
 * type :
 * - yui => librairie de base YUI
 * - css => fichier CSS
 * - js  => librairie quelconque, donner le chemin dans base
 * - code => function JS - sera lancee APRES le OnDomReady
 *
 * yui_req : pour type=js, permet d'indiquer apres QUELLE lib YUI devra etre chargee le script
 *
 * chaque section peut etre declinee en N versions, setables via DMLOADER.profile
 * Pour etendre les possibilites : seter par ex
 * DMLOADER.yui_infos.ma-rubrique = [
 *   {type: 'js' , lib: 'mon-script.js', base: 'js/', yui_req:'connection'}
 * ];
 * DMLOADER.yui_infos.ma-rubrique_debug = [
 *   {type: 'js' , lib: 'mon-script-debug.js', base: 'js/', yui_req:'connection'}
 * ];
 *
 * puis yui_load('ma-rubrique');
 * </pre>
 * @author  Damien Mangin dmangin@france-examen.fr
 * @copyright France-examen 2007
 * @version $Id: yui_loader.js,v 1.13 2008/03/07 14:19:44 nicolas Exp $
 * @namespace DMLOADER
 *
 * @todo DAM TODO 2007-10-19 : revoir la base si appel depuis rep different quid ?
 * @todo DAM TODO 2007-10-19 : pouvoir loader les version -min en prod
 */

var $DEBUG = 0;//(window.document.URL.match(/debug/i));
setDebug();

// Fct a lancer APRES load des lib
YAHOO_config = {
  listener: _OnYUILoad
};

/** Constantes globales de load des librairies YUI
 * <pre>
 * Permet egalement de loader d'autres librairies (plugins ou perso)
 * type :
 * - yui => librairie de base YUI
 * - css => fichier CSS
 * - js  => librairie quelconque, donner le chemin dans base
 * - code => function JS - sera lancee APRES le OnDomReady
 * </pre>
 * @class DMLOADER
 * @constructor
 */
var DMLOADER = window.DMLOADER || {};

/** liste des fonctions a executer sur event OnDomReady.
 * Utilisation par DMLOADER.ODRlisteners.push(...) depuis page appelante
 * @member DMLOADER
 * @type array of functions
 */
DMLOADER.ODRlisteners = [];
DMLOADER.yuilisteners = {};
DMLOADER.loaded = [];
/** profile courant a charger :
 * <pre>
 * sera ajoute a tout appel de yui_load a la fct de base :
 * ex si profile = "vt" => la section "common_vt" sera lue au lieu de "common"
 *
 * Profiles existants
 * - 2_3_1 => forcer l'utilisation des YUI 2.3.1 au lieu de 2.4.1 (defaut)
 * - debug => appelé automatiquement si url de type ?debug
 * </pre>
 * @member DMLOADER
 * @type string
 */
DMLOADER.profile = '';
//DMLOADER.profile = '2_3_1'; // 2007-12-05 : YUI V2.4.0

/** liste des scripts/css a charger par profile et type. format :
 * <code>
 * section : [
 *   {
 *     type (css, js, ...)
 *     lib (ex dm_widget.js)
 *     base (repertoire de depart)
 *     yui_req (nom d'une section YUI devant declencher le load)
 *   },
 *   ...
 * ]
 * </code>
 * @member DMLOADER
 * @type object
 */
DMLOADER.yui_infos =
{
  base: "http://yui.yahooapis.com/2.4.1/build/" ,
  //base: "http://localhost/yui/build/" ,
  base_2_3_1: "http://yui.yahooapis.com/2.3.1/build/" ,
  //base_debug: "http://admn.france-examen.com/HomePageDam/js/yui/build/",
  common: [
    {type: 'yui-css', lib: 'fonts/fonts-min.css'},
    {type: 'yui', lib: 'utilities/utilities.js'}   // = Yahoo Global Object * Event * Dom * Connection Manager * Animation * Drag & Drop * element
  ],
  common_vt: [
    {type: 'yui-css', lib: 'fonts/fonts-min.css'},
    {type: 'yui', lib: 'yahoo/yahoo-min.js'},
    {type: 'yui', lib: 'dom/dom-min.js'},
    {type: 'yui', lib: 'event/event-min.js'},
    {type: 'yui', lib: 'connection/connection-min.js'},
    {type: 'yui', lib: 'animation/animation-min.js'},
    {type: 'yui', lib: 'dragdrop/dragdrop-min.js'},
    {type: 'yui', lib: 'element/element-beta-min.js'}
  ],
  visualiseur: [
    {type: 'inc', lib: 'common_vt'},
    {type: 'yui-css', lib: 'container/assets/container.css'},
    {type: 'yui-css', lib: 'container/assets/skins/sam/container.css'},
    {type: 'yui', lib: 'yahoo-dom-event/yahoo-dom-event.js'},
    {type: 'yui', lib: 'container/container-min.js'}
  ],
  tabview: [
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'tabview/assets/skins/sam/tabview.css'},
    {type: 'yui', lib: 'tabview/tabview-min.js'}
    //{type: 'js' , lib: 'dispatcher.js', base: 'js/', yui_req:'connection'}
  ],
  button_2_3_1: [
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'button/assets/skins/sam/button.css'},
    {type: 'yui-css', lib: 'menu/assets/skins/sam/menu.css'},
    {type: 'yui', lib: 'container/container_core-min.js'},
    {type: 'yui', lib: 'menu/menu-min.js'},
    {type: 'yui', lib: 'button/button-beta-min.js'}
  ],

  button: [
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'button/assets/skins/sam/button.css'},
    {type: 'yui-css', lib: 'menu/assets/skins/sam/menu.css'},
    {type: 'yui', lib: 'container/container_core-min.js'},
    {type: 'yui', lib: 'menu/menu-min.js'},
    // DAM 2007-12-05 passage en YUI 2.4.0
    {type: 'yui', lib: 'button/button-min.js'}
  ],

  dragdrop: [
    {type: 'inc', lib: 'common'}
    //{type: 'yui', lib: 'dragdrop/dragdrop-min.js'} // inclu dans utilities
  ],
  table:[
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'datatable/assets/skins/sam/datatable.css'},
    {type: 'yui-css', lib: 'calendar/assets/skins/sam/calendar.css'},
    //{type: 'yui', lib: 'element/element-beta-min.js'}, // inclu dans utilities
    {type: 'yui', lib: 'datasource/datasource-beta-min.js'},
    {type: 'yui', lib: 'container/container_core-min.js'},
    //{type: 'yui', lib: 'calendar/calendar-debug.js'},
    {type: 'yui', lib: 'calendar/calendar-min.js'},
    {type: 'yui', lib: 'datatable/datatable-beta-min.js'}
  ],
  table_debug:[
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'datatable/assets/skins/sam/datatable.css'},
    {type: 'yui-css', lib: 'calendar/assets/skins/sam/calendar.css'},
    //{type: 'yui', lib: 'element/element-beta-min.js'}, // inclu dans utilities
    {type: 'js', lib: 'http://admn.france-examen.com/HomePageDam/js/yui/build/datasource/datasource-beta.js'},
    {type: 'yui', lib: 'container/container_core-min.js'},
    //{type: 'yui', lib: 'calendar/calendar-debug.js'},
    {type: 'yui', lib: 'calendar/calendar-min.js'},
    {type: 'js', lib: 'http://admn.france-examen.com/HomePageDam/js/yui/build/datatable/datatable-beta.js'}
  ],
  logger:[
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'logger/assets/skins/sam/logger.css'},
    {type: 'yui', lib: 'logger/logger-min.js'},
    {type: 'code' , lib: ShowLogger}
  ],
  menu:[
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'menu/assets/skins/sam/menu.css'},
    {type: 'yui', lib: 'yahoo-dom-event/yahoo-dom-event.js'},
    {type: 'yui', lib: 'container/container_core-min.js'},
    {type: 'yui', lib: 'menu/menu-min.js'}
  ],
  dmw:[
    {type: 'inc', lib: 'table'},
    {type: 'css', lib:'dm_widget.css' , base: 'css/'},
    {type: 'js' , lib: 'dispatcher.js', base: 'js/', yui_req:'connection'},
    {type: 'js' , lib: 'yui_ddresize.js', base: 'js/', yui_req:'dragdrop'},
    {type: 'js' , lib: 'dm_widget.js', base: 'js/', yui_req:'datatable'},
    {type: 'yui', lib: 'json/json-beta-min.js'}
  ],
  dmtabview:[
    {type: 'inc', lib: 'tabview'},
    {type: 'css', lib:'dm_tabview.css' , base: 'css/'},
    {type: 'js' , lib: 'dm_tabview.js', base: 'js/', yui_req:'tabview'}
  ],
  tabview_debug: [
    {type: 'inc', lib: 'common'},
    {type: 'yui-css', lib: 'tabview/assets/skins/sam/tabview.css'},
    {type: 'js', lib: 'http://admn.france-examen.com/HomePageDam/js/yui/build/element/element-beta-debug.js'},
    {type: 'js', lib: 'http://admn.france-examen.com/HomePageDam/js/yui/build/tabview/tabview-debug.js'}
    //{type: 'js' , lib: 'dispatcher.js', base: 'js/', yui_req:'connection'}
  ]

};

/** chargement d'une section de DMLOADER.yui_infos dans le DOM
 * @member DMLOADER
 * @param {string} fct : la section de DMLOADER.yui_infos a charger
 * @param {string} base : repertoire de base pour les js
 * @param {string} basecss : repertoire de base pour les css
 * @see DMLOADER.yui_infos
 */
DMLOADER.yui_load = function(fct, base, basecss)
{
  // profile si donne, sinon base
  var _profile = DMLOADER.profile || '';
  if (_profile !== '') {
    _profile = '_' + _profile;
  }

  // debug : on force _profile a _debug
  if ($DEBUG) {
    _profile = '_debug';
  }

  var l = DMLOADER.yui_infos[fct + _profile] || DMLOADER.yui_infos[fct];
  
  if (l === null) {
    alert('Erreur lors du chargement de ' + fct);
    return;
  }

  var keybase = 'base' + _profile,
      yuibase = DMLOADER.yui_infos[keybase] || DMLOADER.yui_infos.base;

  // return if already loaded
  if (DMLOADER.loaded[fct] == true)
    return;

  for(var i=0; i < l.length; i++)
  {
    if (!l[i]) {
      alert('Erreur lors du chargement de ' + fct);
      continue;
    }
    l[i].base = l[i].base || '';
    switch (l[i].type) {
      case "inc" :
        DMLOADER.yui_load(l[i].lib);
        break;
      case "css" :
        var url   = ((basecss) ? basecss : l[i].base) + l[i].lib,
            media = (l[i].media) ? l[i].media : "";
        DMLOADER.css_include(url, media);
        break;
      case "yui-css" :
        DMLOADER.css_include(yuibase + l[i].lib);
        break;
      case "js"  :
        var url = ((base) ? base : l[i].base) + l[i].lib;
        if (l[i].yui_req) {
          if (typeof DMLOADER.yuilisteners[l[i].yui_req] == 'undefined') {
            DMLOADER.yuilisteners[l[i].yui_req] = [];
          }
          DMLOADER.yuilisteners[l[i].yui_req].push(url);
        } else {
          DMLOADER.js_include(url);
        }
        break;
      case "yui" :
        //var yuijs = ($DEBUG) ? l[i].lib.replace(/\-min\.js/, '-debug.js') : l[i].lib; //'-debug.js'
        var yuijs = l[i].lib;
        DMLOADER.js_include(yuibase + yuijs);
        break;
      case "code":
        DMLOADER.ODRlisteners.push(l[i].lib);
        break;
    }
  }
  DMLOADER.loaded[fct] = true;
  return;
};

/** inclusion d'un script js dans le DOM
 * @member DMLOADER
 * @param {string} $script : url + nom complet
 */
DMLOADER.js_include = function($script)
{
  if (DMLOADER.loaded[$script] == true)
    return;
  try {
    var script = document.createElement('script');
    script.src = $script;
    script.type = 'text/javascript';
    // ATTENTION sous IE il FAUT etre synchrone => Ne pas utiliser head.append
    if (navigator.userAgent.toLowerCase().indexOf('msie') > -1) {
      document.write('<scr' + 'ipt type="' + script.type + '" src="' + script.src + '">' + '</script>' );
    } else {
      //var head = document.getElementsByTagName('head').item(0);
      //head.appendChild(script);
      document.write('<scr' + 'ipt type="' + script.type + '" src="' + script.src + '">' + '</script>' );
    }
    DMLOADER.loaded[$script] = true;

    if ($DEBUG) {
      document.write('<pre>loaded ' + $script + '</pre>');
    }

  } catch(e) {
    alert('Erreur js_include ' + $script + ': ' + e);
  }
}

/** inclusion d'un appel CSS dans le DOM
 * @member DMLOADER
 * @param {string} $css : url + nom complet
 * @param {string} $media : ex screen, print
 */
DMLOADER.css_include = function($css, $media)
{
  if (DMLOADER.loaded[$css] == true)
    return;
  try {
    var css = document.createElement('link');
    css.rel = 'stylesheet';
    css.href = $css;
    css.type = 'text/css';
    if ($media) {
      css.media = $media;
    }
    var head = document.getElementsByTagName('head').item(0);
    head.appendChild(css);
    DMLOADER.loaded[$css] = true;
  } catch(e) {
    alert('Erreur css_include ' + $css + ': ' + e);
  }
};

/** Actions declenches lors de l'event OnDomReady : apres le chargement de la page,
 * mais AVANT le window.load.
 * @member DMLOADER
 * @return void
 * @private
 */
DMLOADER._OnDomReady = function()
{
  if ($DEBUG) {
    //alert('<pre>Entering OnDomReady</pre>');
  }
  for (var i in DMLOADER.ODRlisteners) {
    DMLOADER.ODRlisteners[i]();
  }
};

/** Appel des skins YUI SAM pour la window courante.
 * Est appele automatiquement lors du load de YAHOO 
 * @member DMLOADER
 */
DMLOADER.AddSamClass = function()
{
  YAHOO.util.Dom.addClass(document.body, "yui-skin-sam");
};

/** ajout d'un element a charger APRES telle librairie YUI
 * @member DMLOADER
 * @param {string} yui_lib : la librairie apres laquelle il faut charger, ex datatable, dm_widget, ...
 * @param {string|function} data : 
 * - si string => suppose etre un .js qui sera charge via js_include
 * - si function => sera executee apres le load de la librairie yui-lib
 */
DMLOADER.add_yui_listener = function(yui_lib, data)
{
  DMLOADER.yuilisteners[yui_lib] = DMLOADER.yuilisteners[yui_lib] || [];
  DMLOADER.yuilisteners[yui_lib].push(data);
};

/* ============= Alias ====================================================== */

var yui_load = DMLOADER.yui_load,
    js_include = DMLOADER.js_include,
    css_include = DMLOADER.css_include;

/** function executer lors du load d'une lib YAHOO
 * via YAHOO_config.listener
 * @param {string} info : la librairie qui vient d'etre chargee, ex datatable, dm_widget, ...
 * @private
 */
function _OnYUILoad(info)
{
  var yuit = info.name.toLowerCase();
  if (typeof DMLOADER.yuilisteners[yuit] != 'undefined') {
    for (var f in DMLOADER.yuilisteners[yuit]) {
      var _toexec = DMLOADER.yuilisteners[yuit][f]; 
      //alert(info.name + '=>'+_toexec);
      if (typeof _toexec === 'function') {
        _toexec.call();
      } else {
        DMLOADER.js_include(_toexec);
      }
    }
  }

  switch(yuit)
  {
    case 'yahoo' :
      DMLOADER.ODRlisteners.push(DMLOADER.AddSamClass);
      break;
    case 'event' :
      if ($DEBUG) {
        DMLOADER.yui_load('logger');
        DMLOADER.js_include('http://www.3site.eu/JPU/JPU.js');
      }
      break;
    case 'dom' :
      break;
    case 'connection' :
      YAHOO.util.Event.onDOMReady(DMLOADER._OnDomReady);
      break;
    case 'element' :
      break;
  }
};

/** Appel de YAHOO.widget.LogReader();
 * genere automatiquement si $DEBUG > 0 
 */
function ShowLogger()
{
  new YAHOO.widget.LogReader();
}

/** Set le niveau de debug en fonction de l'url :
 * http://...?debug => genere un debug de niveau 1.
 * http://...?debugN => genere un debug de niveau N.
 * Les widgets utilisent les liveaux 1 & 2.
 */
function setDebug()
{
  var _M = window.document.URL.match(/debug(\d+|)/i);
  if (_M) {
    $DEBUG = _M[1] ? Math.max(1, parseInt(_M[1])) : 1;
  }
}