/**
 * Objeto encargado de gestionar la ayuda contextual
 * [ EJEMPLO ] Documento xml empleado para poblar el objeto
 * 
 *  <help>
 *  	<section id="seccion1">
 *  		<block id="bloque1">
 *  			<title>Título del bloque 1</title>
 *  			<body>Contenido del bloque 2</title>
 * 			</block>
 * 
 * 			<block id="bloque2">
 * 				<title>Tí­tulo del bloque 2</title>
 * 				<body>Contenido del bloque 2</body>
 * 			</block>
 *  	</section>
 *  </help>
 *  
 *  [ EJEMPLO ] Cómo invocar la ayuda contextual
 *  <input type="button" value="help!" onclick="ddlHelpDialog.show( 'seccion1', 'bloque1' );" />
 * 
 *  @var ddlHelpDialog ( Object )
 */
 
var ddlHelpDialog = 
{ 
 /**
  * Listado de información sobre el estado del objeto
  * @param status ( Array )
  */
		
 status: { 
	  section: null,
	  block: null 
	 },
		
 /**
  * Listado de elementos organizados según sección y bloque
  * @param _items ( Array )
  */

 _items: new Array(),
 
 /**
  * Listado de argumentos por defecto que serán empleados al mostrar el diálogo
  * 
  * @var _config ( Array )
  * @see http://www.ericmmartin.com/projects/simplemodal/
  */
 
 _config: {
	  close: true,
	  maxWidth: 700, 
	  maxHeight: 500, 
	  minWidth: 400, 
	  minHeight: 300,
	  autoResize: false,
	  autoPosition: true,
	  containerCss: 'basic-modal-content',
	  parameters: {}
     }
};

/**
 * Añade contenidos para la sección y bloque especificados en los 2 primeros parámetros
 * 
 * @function addItem
 * @access public
 * 
 * @param sSectionId ( String )
 * @param sBlockId ( String )
 * @param [ oItemInfo ] ( Array )
 * @return ( undefined )
 */

ddlHelpDialog.addItem = function( sSectionId, sBlockId, oItemInfo )
{
 if( typeof( this._items[ sSectionId ] ) == "undefined" )
  this._items[ sSectionId ] = new Array();
  
 this._items[ sSectionId ][ sBlockId ] = oItemInfo;
}

/**
 * Muestra la ventana de ayuda contextual, volcando el tí­tulo y contenido
 * asociados a la sección y bloque especificados en los parámetros
 * 
 * Recibe el parámetro opcional 'mCloseCallBack', que reconoce los siguientes formatos:
 *  - ( Function ): Función que será invocada al cerrar la ventana modal
 *  - ( String ): Código fuente ejecutado al cerrar la ventana modal
 *  
 * Recibe el parámetro opcional 'oDialogArgumentList', que permite definir argumentos personalizados
 * que serán empleados para mostrar la ventana modal. Cualquier Ãíndice definido en este listado
 * sobreescribirá los valores por defecto cargados en la función
 * 
 * @function show
 * @access public
 * 
 * @param sSectionId ( String )
 * @param sBlockId ( String )
 * @param [ nDelay ] ( Number ) Tiempo (seg.) que se mantendrá visible el mensaje ( por defecto siempre )
 * @param [ mCloseCallBack ] ( mixed )
 * @param [ oDialogArgumentList ] ( Array )
 * @return ( undefined )
 */

ddlHelpDialog.show = function( sSectionId, sBlockId, nDelay, mCloseCallBack, oDialogArgumentList )
{
 /**
  * Contenido volcado sobre la ventana modal
  * @var sDialogContent ( String )
  */
	
 var sDialogContent = new String(); 

 /**
  * Fuerza la creación de la función de callback de cierre
  */
 
 if( typeof mCloseCallBack == "string" )
  mCloseCallBack = new Function( mCloseCallBack );
 	 
 /**
  * No encuentra la sección y/o el bloque
  * Vuelca un mensaje informativo predeterminado
  */
 
 if( !this._items[ sSectionId ] || !this._items[ sSectionId ][ sBlockId ] )
 {
  sDialogContent = "<h1>Help block not found</h1>";
  sDialogContent += "<p>Section: " + sSectionId + "<br />Block: " + sBlockId + "</p>";
 }
  
 /**
  * Vuelca la información contenida en 'this._items'
  * Esta información es cargada mediante el método 'load', a partir de ficheros xml
  */
 
 else
 {
  sDialogContent = "<h1>" + this._items[ sSectionId ][ sBlockId ][ 0 ] + "</h1><hr />";
  sDialogContent += "<p>" + this._items[ sSectionId ][ sBlockId ][ 1 ] + "</h1>";
 }
  
 /**
  * Aplica los argumentos enviados sobreescribiendo los argumentos por defecto
  */
 
 for( var i in oDialogArgumentList )
  this._config[ i ] = oDialogArgumentList[ i ];
 
 /**
  * Muestra la ventana modal
  * [ NOTA ] El índice 'onClose', a excepción del resto, se rige por el parámetro 'mCloseCallBack'
  */
 
 if( typeof mCloseCallBack == "function" )
  this._config.onClose = mCloseCallBack;
 
 /**
  * - Invoca el método 'hide' para refrescar el contenido de la capa
  * - Ejecuta el bloque de código fuente ( si ha sido definido ) asociado a la sección y bloque indicados 
  */
 
 if( this.hide() != false )
 { 
  $.modal( sDialogContent, this._config );
  this.execute( sSectionId, sBlockId );
 }
 
 /**
  * Comprueba si el parámetro 'nDelay' es numérico y mayor que '0', 
  * en cuyo caso aplicará un retardo antes de cerrar automáticamente la ventana
  */
 
 if( !isNaN( nDelay ) && nDelay > 0 )
  window.setTimeout( 'ddlHelpDialog.hide();', nDelay * 1000 );
 
 /**
  * Actualiza el estado
  * [ IMPORTANTE ] Efectuar esta acción DESPUÉS de invocar la ventana modal
  */
	 
 this.status.section = sSectionId;
 this.status.block = sBlockId; 
}

/**
 * Ejecuta un bloque de código fuente asociado a la sección y bloque especificados
 * 
 * @function execute
 * @access public
 * 
 * @param sSectionId ( String )
 * @param sBlockId ( String )
 * @return ( undefined )
 */

ddlHelpDialog.execute = function( sSectionId, sBlockId )
{
 try
 { eval( this._items[ sSectionId ][ sBlockId ][ 2 ] ); }
 
 catch( e )
 {}
}

/**
 * Oculta la ventana modal
 * 
 * @function hide
 * @access public
 * @return ( undefined )
 */

ddlHelpDialog.hide = function()
{ return( $.modal.close() ); }

/**
 * Carga bloques de información a partir de un fichero xml
 * Recibe un parámetro opcional que permite definir la función ejecutada tras cargar el fichero
 * 
 * @function load
 * @param sSectionFileName ( String )
 * @param [ mLoadCallBack ] ( Function )
 * @return ( undefined )
 */

ddlHelpDialog.load = function( sSectionFileName, mLoadCallBack )
{
 $.ajax( {
	 
	/**
	 * Función invocada al cargar correctamente el fichero
	 *  - Extrae los nodos 'block' ubicados bajo los nodos 'section'
	 *  - Extrae los subnodos 'title' y 'body' de cada bloque
	 *  - Extrae el subnodo 'script', que permite ejecutar código fuente tras mostrar el diálogo
	 *  - AÃ±ade la información al listado interno 'this._items'
	 */
	 
 	success: function( xml ) 
	{
	 $( xml ).find( 'section block' ).each( function(){
	    	
	    var sSectionId = $( this ).parent().attr( 'id' );
    	var sBlockId = $( this ).attr( 'id' );
		var sTitle = $( this ).find( 'title' ).text();
		var sBody = $( this ).find( 'body' ).text();
		var sSource = $( this ).find( 'script' ).text();
		
		ddlHelpDialog.addItem( sSectionId, sBlockId, [ sTitle, sBody, sSource ] );
			
     } );	
	 
	 /**
	  * Invoca el callback de carga, si ha sido definido
	  */
	 
	 if( typeof mLoadCallBack == "function" )
	  mLoadCallBack.call( ddlHelpDialog, $( xml ) );
    },
    
    /**
     * Parámetros de carga por ajax
     */
    
    type: "GET",
	url: sSectionFileName,
	dataType: "xml"    
 });
}

/**
 * Carga los documentos xml por defecto
 * [ TODO ] Cargar el archivo 'manual_es.xml' sólo cuando se pulse explícitamente en un botón de ayuda contextual

$( document ).ready( function(){ ddlHelpDialog.load( '/admin/help/xml/manual_es.xml' ) } );
$( document ).ready( function(){ ddlHelpDialog.load( '/admin/help/xml/alerts_es.xml' ) } );
$( document ).ready( function(){ ddlHelpDialog.load( '/admin/help/xml/wizard_templates_es.xml' ) } );
*/
