/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones y definiciones base. No son vitales para el funcionamiento, de los componentes, pero al haber definiciones y funciones de check los scripts fallaran si no se carga.<br />
 * <b>Licencia: GPL</b></div>
 ** */


var config = new Array();
config["BASE_URL"] = "http://www.naguissa.com";
config["IMAGE_URL"] = config["BASE_URL"] + "/ngstk/image/";
config["BROWSER_URL"] = config["BASE_URL"] + "/usuarios.php?espacio";
config["SATAY_URL"] = config["BASE_URL"] + "/ngstk/satay.swf";
config["SYNTAX"] = false; // Para el editor RTE. Si se activa se han de cargar los archivo de Syntax Highlighter JS en el resultado. Estan en la carpeta del toolkit.
config["SYNTAX_URL"] = config["BASE_URL"] + "/ngstk/syntax/";




/* **
 *  <div class="ngstk_funcion">ngstk_getUniqueID()</div>
 *  <div class="ngstk_descripcion">Generacion de una ID <b>num&eacute;rica</b> &uacute;nica en cada llamada mediante un contador.</div>
 ** */
var ngstk_uniqueid=1;
function ngstk_getUniqueID() { return ngstk_uniqueid++; }


/* **
 * <div class="ngstk_funcion">ngstk_escapeHTML(str,euro)</div>
 * <div class="ngstk_descripcion">Substituci&oacute;n de &lt;, &gt; y &amp; por sus hexadecimales. Valido para (X)HTML y XML.<ul>
 *   <li><b>str:</b> Cadena a revisar</li>
 *   <li><b>debugw:</b> Si es true se procede a la substituci&oacute;n del s&iacute;mbolo euro. En caso contrario esta substituci&oacute;n no se lleva a cabo..</li>
 * </ul></div>
 ** */
function ngstk_escapeHTML(str,euro) {
 if( euro ) return str.split(String.fromCharCode(8364)).join("&#128;").split("<").join("&#60;").split(">").join("&#62;").split("&").join("&#38;");
 return str.split("<").join("&#60;").split(">").join("&#62;").split("&").join("&#38;");
 }


/* **
 * <div class="ngstk_funcion">ngstk_imgs</div>
 * <div class="ngstk_descripcion">Im&aacute;genes precargadas.</div>
 ** */
var ngstk_imgs = new Array();


/* **
 * <div class="ngstk_funcion">ngstk_preloadimg( imga )</div>
 * <div class="ngstk_descripcion">Hace el preload de un array de im&aacute;genes.<ul>
 *   <li><b>imga:</b> Array con las URIs de las im&aacute;genes.</li>
 * </ul></div>
 ** */
function ngstk_preloadimg( imga ) {
  var im;
  for( im in imga ) {
    ngstk_imgs[ngstk_imgs.length] = new Image();
    ngstk_imgs[ngstk_imgs.length-1].src = imga[im];
    }
  }



/* **
 * <div class="ngstk_funcion">ngstk_urlencode(str)</div>
 * <div class="ngstk_descripcion">Codifica una URL de la misma forma que lo hace PHP.<ul>
 *   <li><b>str:</b> Cadena a codificar</li>
 *   <li><b><i>@retorno</i>:</b> Retorna el string codificado.</li>
 * </ul></div>
 ** */
function ngstk_urlencode(str) {
  str = escape(str);
  str = str.replace('+', '%2B');
  str = str.replace('%20', '+');
  str = str.replace('*', '%2A');
  str = str.replace('/', '%2F');
  str = str.replace('@', '%40');
  return str;
  }


/* **
 * <div class="ngstk_funcion">ngstk_urldecode(str)</div>
 * <div class="ngstk_descripcion">Decodifica una URL de la misma forma que lo hace PHP.<ul>
 *   <li><b>str:</b> Cadena a decodificar</li>
 *   <li><b><i>@retorno</i>:</b> Retorna el string decodificado.</li>
 * </ul></div>
 ** */
function ngstk_urldecode(str) {
  str = str.replace('+', ' ');
  str = unescape(str);
  return str;
  }



















/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de compatibilidad cross-browser del DOM. Las funciones xml-rpc se suministran por separado.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_isDef()</div>
 *  <div class="ngstk_descripcion">Analisis de argumentos; estan definidos?</div>
 ** */
function ngstk_isDef(){
 for(var i=0; i<arguments.length; ++i) if(typeof(arguments[i])=='undefined') return false;
 return true;
 }


/* **
 *  <div class="ngstk_funcion">ngstk_isStr()</div>
 *  <div class="ngstk_descripcion">Analisis de argumentos; son strings?</div>
 ** */
function ngstk_isStr(){
 for(var i=0; i<arguments.length; ++i) if(typeof(arguments[i])!='string') return false;
 return true;
 }


/* **
 *  <div class="ngstk_funcion">ngstk_display(e,s)</div>
 *  <div class="ngstk_descripcion">Mostrar/ocultar elementos.<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *    <li><b>s:</b> Opci&oacute;n deseada (block, none).</li>
 *  </ul></div>
 ** */
function ngstk_display(e,s){
 if(!(e=ngstk_getElementById(e))) return false;
 if(e.style && ngstk_isDef(e.style.display)) {
  if (ngstk_isStr(s)) e.style.display = s;
  return e.style.display;
  }
  return false;
 }


/* **
 *  <div class="ngstk_funcion">ngstk_visibilidad(e,s)</div>
 *  <div class="ngstk_descripcion">Mostrar/ocultar elementos con true o false.<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *    <li><b>s:</b> Opci&oacute;n deseada (true -ver-, false -no ver-).</li>
 *  </ul></div>
 ** */
function ngstk_visibilidad(e,s){
 if(s) return ngstk_display(e,'block');
 return ngstk_display(e,'none');
 }


/* **
 *  <div class="ngstk_funcion">ngstk_getDisplay(e)</div>
 *  <div class="ngstk_descripcion">Retorna el estado de visibilidad de un elemento (block, none).<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *  </ul></div>
 ** */
function ngstk_getDisplay(e){
 if(!(e=ngstk_getElementById(e))) return false;
 if(e.style && ngstk_isDef(e.style.display)) return e.style.display;
 return false;
 }


/* **
 *  <div class="ngstk_funcion">ngstk_getVisibilidad(e)</div>
 *  <div class="ngstk_descripcion">Retorna el estado de visibilidad de un elemento (true -visible-, false -no visible-).<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *  </ul></div>
 ** */
function ngstk_getVisibilidad(e){
 if( ngstk_getDisplay(e) == 'block') return true;
 return false;
 }


/* **
 *  <div class="ngstk_funcion">ngstk_showhide(e)</div>
 *  <div class="ngstk_descripcion">Cambia el estado de visibilidad de un elemento.<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *  </ul></div>
 ** */
function ngstk_showhide(e) {
 return ngstk_visibilidad(e, !ngstk_getVisibilidad(e));
 }


/* **
 *  <div class="ngstk_funcion">ngstk_getElementById(e)</div>
 *  <div class="ngstk_descripcion">getElementByID cross-browser. Si no se encuentra el elemento retorna false.<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *  </ul></div>
 ** */
function ngstk_getElementById(e){
  var ret = false;
  if(typeof(e)=='string') {
    if(document.getElementById) ret=document.getElementById(e);
     else if(document.all) ret=document.all[e];
    }
  return ret;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_bg(e,s)</div>
 *  <div class="ngstk_descripcion">Cambia el estilo (css) del fondo del elemento.<ul>
 *    <li><b>e:</b> Id del elemento.</li>
 *    <li><b>s:</b> Par&aacute;tros css del fondo.</li>
 *  </ul></div>
 ** */
function ngstk_bg(e,s){
  e=ngstk_getElementById(e);
  if(!e) return false;
  if(e.style && ngstk_isDef(e.style.background)) {
    if (ngstk_isStr(s)) e.style.background = s;
    return e.style.background;
    }
  return false;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_addEvent(obj,type,fn)</div>
 *  <div class="ngstk_descripcion">Adjunta un evento de cualquier tipo a un objeto cualquiera del DOM.<ul>
 *    <li><b>obj:</b> Objeto del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *    <li><b>type:</b> Tipo de enevto (sin el on-; ejemplo. <s>onmouseover</s> --&gt; <b>mouseover</b>).</li>
 *    <li><b>fn:</b> Funci&oacute; disparada por el evento.</li>
 *  </ul></div>
 ** */
function ngstk_addEvent(obj,type,fn) {
 if (obj.addEventListener) obj.addEventListener( type, fn, false );
  else if (obj.attachEvent) obj.attachEvent( "on"+type, fn );
 }


/* **
 *  <div class="ngstk_funcion">ngstk_removeEvent( obj, type, fn )</div>
 *  <div class="ngstk_descripcion">Elimina un evento de cualquier tipo a un objeto cualquiera del DOM.<ul>
 *    <li><b>obj:</b> Objeto del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *    <li><b>type:</b> Tipo de enevto (sin el on-; ejemplo. <s>onmouseover</s> --&gt; <b>mouseover</b>).</li>
 *    <li><b>fn:</b> Funci&oacute; disparada por el evento.</li>
 *  </ul></div>
 ** */
function ngstk_removeEvent( obj, type, fn ) {
 if (obj.removeEventListener) obj.removeEventListener( type, fn, false );
  else if (obj.detachEvent) obj.detachEvent( "on"+type, obj[type+fn] );
 }


/* **
 *  <div class="ngstk_funcion">ngstk_moveObjectToXY(id, posx, posy)</div>
 *  <div class="ngstk_descripcion">Mueve un objeto del DOM dado por la id a una posicion X e Y dada.<ul>
 *    <li><b>id:</b> Id del objeto.</li>
 *    <li><b>posx:</b> Nueva posicion horizontal.</li>
 *    <li><b>posy:</b> Nueva posicion vertical.</li>
 *  </ul></div>
 ** */
function ngstk_moveObjectToXY(id, posx, posy) {
 var obj = ngstk_getElementById(id);
 if( obj ) {
  obj.style.left = posx;
  obj.style.top = posy;
  }
 }


/* **
 *  <div class="ngstk_funcion">ngstk_createObject(tipo, attr, cod)</div>
 *  <div class="ngstk_descripcion">Crea un elemento nuevo en el DOM y lo retorna.<ul>
 *    <li><b>tipo:</b> Tipo de elemento (p, div, li...).</li>
 *    <li><b>attr:</b> Array asociativo de atributos.</li>
 *    <li><b>cod:</b> Contenido de elemento, que ser&aacute; insertado mediante innerHTML. <b>Opcional.</b></li>
 *  </ul></div>
 ** */
function ngstk_createObject(tipo,attr,cod) {
  var z = document.createElement(tipo);
  for( var a in attr )
   if( a == "style" ) ngstk_applyCSS(z, attr[a]);
    else z.setAttribute(a, attr[a]);
  if( cod ) z.innerHTML = cod;
  return z;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_removeObject(id)</div>
 *  <div class="ngstk_descripcion">Elimina un elemento del DOM.<ul>
 *    <li><b>id:</b> Id del elemento a eliminar.</li>
 *  </ul></div>
 ** */
function ngstk_removeObject(id) {
 var obj = ngstk_getElementById(id);
 if( obj ) obj.parentNode.removeChild(obj);
 }



/* **
 *  <div class="ngstk_funcion">ngstk_findPos(obj)</div>
 *  <div class="ngstk_descripcion">Retorna un array con la posici&oacute; de un elemento del DOM de la forma [left, top,right, bottom].<ul>
 *    <li><b>obj:</b> Objeto del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *  </ul></div>
 ** */
function ngstk_findPos(obj) {
  var curleft = curtop = 0;
  var W = obj.offsetWidth;
  var H = obj.offsetHeight;
  if (obj.offsetParent) do {
    curleft += obj.offsetLeft;
    curtop += obj.offsetTop;
    } while (obj = obj.offsetParent);
  return [curleft,curtop,curleft+W,curtop+H];
  }


/* **
 *  <div class="ngstk_funcion">ngstk_trimL(str)</div>
 *  <div class="ngstk_descripcion">Elimina los espacios por la izquierda del string.<ul>
 *    <li><b>str:</b> String al cual aplicar la operaci&oacute;n.</li>
 *  </ul></div>
 ** */
function ngstk_trimL(str) {
  if( str ) return str.replace(/^\s+/,'');
   else return "";
  }


/* **
 *  <div class="ngstk_funcion">ngstk_trimR(str)</div>
 *  <div class="ngstk_descripcion">Elimina los espacios por la derecha del string.<ul>
 *    <li><b>str:</b> String al cual aplicar la operaci&oacute;n.</li>
 *  </ul></div>
 ** */
function ngstk_trimR(str) {
  if( str ) return str.replace(/\s+$/,'');
   else return "";
  }


/* **
 *  <div class="ngstk_funcion">ngstk_trim(str)</div>
 *  <div class="ngstk_descripcion">Elimina los espacios por la izquierda y la derecha del string.<ul>
 *    <li><b>str:</b> String al cual aplicar la operaci&oacute;n.</li>
 *  </ul></div>
 ** */
function ngstk_trim(str) {
  if( str ) return str.replace(/^\s+/,'').replace(/\s+$/,'');
   else return "";
  }


/* **
 *  <div class="ngstk_funcion">ngstk_applyCSS(o, css)</div>
 *  <div class="ngstk_descripcion">Aplica un string de propiedades CSS a un objeto.<ul>
 *    <li><b>o:</b> Objeto del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *    <li><b>css:</b> String CSS como el que usar&iacute;a en los tags html.</li>
 *  </ul></div>
 ** */
function ngstk_applyCSS(o, css) {
  if( o && css ) {
    var props = css.split(";");
    for( var i in props ) if( typeof(props[i]) == "string" && ngstk_trim(props[i]) != "") {
      var tmp = ngstk_trim(props[i]);
      var item = tmp.split(':');
      if( item[0] && item[1] ) {
        v = ngstk_trim(item[1]);
        if( ngstk_trim(item[0]) != "" ) switch( ngstk_trim(item[0]) ) {
          case "background": o.style.background = v; break;
          case "background-attachment": o.style.backgroundAttachment = v; break;
          case "background-color": o.style.backgroundColor = v; break;
          case "background-image": o.style.backgroundImage = v; break;
          case "background-position": o.style.backgroundPosition = v; break;
          case "background-repeat": o.style.backgroundRepeat = v; break;
          case "border": o.style.border = v; break;
          case "border-bottom": o.style.borderBottom = v; break;
          case "border-bottom-color": o.style.borderBottomColor = v; break;
          case "border-bottom-style": o.style.borderBottomStyle = v; break;
          case "border-bottom-width": o.style.borderBottomWidth = v; break;
          case "border-color": o.style.borderColor = v; break;
          case "border-left": o.style.borderLeft = v; break;
          case "border-left-color": o.style.borderLeftColor = v; break;
          case "border-left-style": o.style.borderLeftStyle = v; break;
          case "border-left-width": o.style.borderLeftWidth = v; break;
          case "border-right": o.style.borderRight = v; break;
          case "border-right-color": o.style.borderRightColor = v; break;
          case "border-right-style": o.style.borderRightStyle = v; break;
          case "border-right-width": o.style.borderRightWidth = v; break;
          case "border-style": o.style.borderStyle = v; break;
          case "border-top": o.style.borderTop = v; break;
          case "border-top-color": o.style.borderTopColor = v; break;
          case "border-top-style": o.style.borderTopStyle = v; break;
          case "border-top-width": o.style.borderTopWidth = v; break;
          case "border-width": o.style.borderWidth = v; break;
          case "clear": o.style.clear = v; break;
          case "clip": o.style.clip = v; break;
          case "color": o.style.color = v; break;
          case "cursor": o.style.cursor = v; break;
          case "display": o.style.display = v; break;
          case "filter": o.style.filter = v; break;
          case "font": o.style.font = v; break;
          case "font-family": o.style.fontFamily = v; break;
          case "font-size": o.style.fontSize = v; break;
          case "font-variant": o.style.fontVariant = v; break;
          case "font-weight": o.style.fontWeight = v; break;
          case "height": o.style.height = v; break;
          case "left": o.style.left = v; break;
          case "letter-spacing": o.style.letterSpacing = v; break;
          case "line-height": o.style.lineHeight = v; break;
          case "list-style": o.style.listStyle = v; break;
          case "list-style-image": o.style.listStyleImage = v; break;
          case "list-style-position": o.style.listStylePosition = v; break;
          case "list-style-type": o.style.listStyleType = v; break;
          case "margin": o.style.margin = v; break;
          case "margin-bottom": o.style.marginBottom = v; break;
          case "margin-left": o.style.marginLeft = v; break;
          case "margin-right": o.style.marginRight = v; break;
          case "margin-top": o.style.marginTop = v; break;
          case "overflow": o.style.overflow = v; break;
          case "padding": o.style.padding = v; break;
          case "padding-bottom": o.style.paddingBottom = v; break;
          case "padding-left": o.style.paddingLeft = v; break;
          case "padding-right": o.style.paddingRight = v; break;
          case "padding-top": o.style.paddingTop = v; break;
          case "page-break-after": o.style.pageBreakAfter = v; break;
          case "page-break-before": o.style.pageBreakBefore = v; break;
          case "position": o.style.position = v; break;
          case "float": o.style.styleFloat = v; break;
          case "right": o.style.right = v; break;
          case "bottom": o.style.bottom = v; break;
          case "text-align": o.style.textAlign = v; break;
          case "text-decoration": o.style.textDecoration = v; break;
          case "text-indent": o.style.textIndent = v; break;
          case "text-transform": o.style.textTransform = v; break;
          case "top": o.style.top = v; break;
          case "vertical-align": o.style.verticalAlign = v; break;
          case "visibility": o.style.visibility = v; break;
          case "width": o.style.width = v; break;
          case "z-index": o.style.zIndex = v; break;
          default: alert("Mensaje de ngstk:\n\nNo se ha identificado la propiedad CSS '" + item[0] + "'.");
          }
        }
      }
    }
  }


/* **
 *  <div class="ngstk_funcion">ngstk_copyCSS(o, d)</div>
 *  <div class="ngstk_descripcion">Copia el estilo de un objeto en otro.<ul>
 *    <li><b>o:</b> Objeto origen del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *    <li><b>d:</b> Objeto destino del DOM (se puede obtener mediante ngstk_GetElementById(e)).</li>
 *  </ul></div>
 ** */
function ngstk_copyCSS(o, d) {
  if( o && d ) {
    if(d.style.background) d.style.background = o.style.background;
    if(d.style.backgroundAttachment) d.style.backgroundAttachment = o.style.backgroundAttachment;
    if(d.style.backgroundColor) d.style.backgroundColor = o.style.backgroundColor;
    if(d.style.backgroundImage) d.style.backgroundImage = o.style.backgroundImage;
    if(d.style.backgroundPosition) d.style.backgroundPosition = o.style.backgroundPosition;
    if(d.style.backgroundRepeat) d.style.backgroundRepeat = o.style.backgroundRepeat;
    if(d.style.border) d.style.border = o.style.border;
    if(d.style.borderBottom) d.style.borderBottom = o.style.borderBottom;
    if(d.style.borderBottomColor) d.style.borderBottomColor = o.style.borderBottomColor;
    if(d.style.borderBottomStyle) d.style.borderBottomStyle = o.style.borderBottomStyle;
    if(d.style.borderBottomWidth) d.style.borderBottomWidth = o.style.borderBottomWidth;
    if(d.style.borderColor) d.style.borderColor = o.style.borderColor;
    if(d.style.borderLeft) d.style.borderLeft = o.style.borderLeft;
    if(d.style.borderLeftColor) d.style.borderLeftColor = o.style.borderLeftColor;
    if(d.style.borderLeftStyle) d.style.borderLeftStyle = o.style.borderLeftStyle;
    if(d.style.borderLeftWidth) d.style.borderLeftWidth = o.style.borderLeftWidth;
    if(d.style.borderRight) d.style.borderRight = o.style.borderRight;
    if(d.style.borderRightColor) d.style.borderRightColor = o.style.borderRightColor;
    if(d.style.borderRightStyle) d.style.borderRightStyle = o.style.borderRightStyle;
    if(d.style.borderRightWidth) d.style.borderRightWidth = o.style.borderRightWidth;
    if(d.style.borderStyle) d.style.borderStyle = o.style.borderStyle;
    if(d.style.borderTop) d.style.borderTop = o.style.borderTop;
    if(d.style.borderTopColor) d.style.borderTopColor = o.style.borderTopColor;
    if(d.style.borderTopStyle) d.style.borderTopStyle = o.style.borderTopStyle;
    if(d.style.borderTopWidth) d.style.borderTopWidth = o.style.borderTopWidth;
    if(d.style.borderWidth) d.style.borderWidth = o.style.borderWidth;
    if(d.style.bottom) d.style.bottom = o.style.bottom;
    if(d.style.clear) d.style.clear = o.style.clear;
    if(d.style.clip) d.style.clip = o.style.clip;
    if(d.style.color) d.style.color = o.style.color;
    if(d.style.cursor) d.style.cursor = o.style.cursor;
    if(d.style.display) d.style.display = o.style.display;
    if(d.style.filter) d.style.filter = o.style.filter;
    if(d.style.font) d.style.font = o.style.font;
    if(d.style.fontFamily) d.style.fontFamily = o.style.fontFamily;
    if(d.style.fontSize) d.style.fontSize = o.style.fontSize;
    if(d.style.fontVariant) d.style.fontVariant = o.style.fontVariant;
    if(d.style.fontWeight) d.style.fontWeight = o.style.fontWeight;
    if(d.style.height) d.style.height = o.style.height;
    if(d.style.left) d.style.left = o.style.left;
    if(d.style.letterSpacing) d.style.letterSpacing = o.style.letterSpacing;
    if(d.style.lineHeight) d.style.lineHeight = o.style.lineHeight;
    if(d.style.listStyle) d.style.listStyle = o.style.listStyle;
    if(d.style.listStyleImage) d.style.listStyleImage = o.style.listStyleImage;
    if(d.style.listStylePosition) d.style.listStylePosition = o.style.listStylePosition;
    if(d.style.listStyleType) d.style.listStyleType = o.style.listStyleType;
    if(d.style.margin) d.style.margin = o.style.margin;
    if(d.style.marginBottom) d.style.marginBottom = o.style.marginBottom;
    if(d.style.marginLeft) d.style.marginLeft = o.style.marginLeft;
    if(d.style.marginRight) d.style.marginRight = o.style.marginRight;
    if(d.style.marginTop) d.style.marginTop = o.style.marginTop;
    if(d.style.overflow) d.style.overflow = o.style.overflow;
    if(d.style.padding) d.style.padding = o.style.padding;
    if(d.style.paddingBottom) d.style.paddingBottom = o.style.paddingBottom;
    if(d.style.paddingLeft) d.style.paddingLeft = o.style.paddingLeft;
    if(d.style.paddingRight) d.style.paddingRight = o.style.paddingRight;
    if(d.style.paddingTop) d.style.paddingTop = o.style.paddingTop;
    if(d.style.pageBreakAfter) d.style.pageBreakAfter = o.style.pageBreakAfter;
    if(d.style.pageBreakBefore) d.style.pageBreakBefore = o.style.pageBreakBefore;
    if(d.style.position) d.style.position = o.style.position;
    if(d.style.right) d.style.right = o.style.right;
    if(d.style.styleFloat) d.style.styleFloat = o.style.styleFloat;
    if(d.style.textAlign) d.style.textAlign = o.style.textAlign;
    if(d.style.textDecoration) d.style.textDecoration = o.style.textDecoration;
    if(d.style.textDecorationBlink) d.style.textDecorationBlink = o.style.textDecorationBlink;
    if(d.style.textDecorationLineThrough) d.style.textDecorationLineThrough = o.style.textDecorationLineThrough;
    if(d.style.textDecorationNone) d.style.textDecorationNone = o.style.textDecorationNone;
    if(d.style.textDecorationOverline) d.style.textDecorationOverline = o.style.textDecorationOverline;
    if(d.style.textDecorationUnderline) d.style.textDecorationUnderline = o.style.textDecorationUnderline;
    if(d.style.textIndent) d.style.textIndent = o.style.textIndent;
    if(d.style.textTransform) d.style.textTransform = o.style.textTransform;
    if(d.style.top) d.style.top = o.style.top;
    if(d.style.verticalAlign) d.style.verticalAlign = o.style.verticalAlign;
    if(d.style.visibility) d.style.visibility = o.style.visibility;
    if(d.style.width) d.style.width = o.style.width;
    if(d.style.zIndex) d.style.zIndex = o.style.zIndex;
    }
  }


/* **
 *  <div class="ngstk_funcion">ngstk_get_xhtml(node, lang, encoding, need_nl, inside_pre)</div>
 *  <div class="ngstk_descripcion">Extrae el HTML de un nodo y lo convierte en XHTML v&aacute;lido:<ul>
 *    <li><b>node:</b> Objeto del DOM del cual extraer el XHTML.</li>
 *    <li><b>lang:</b> Idioma de la p&aacute;gina. <i>(opcional, neces&aacute si extraemos un nodo 'html')</i></li>
 *    <li><b>encoding:</b> Codificaci&oacute;n de la p&aacute;gina. <i>(opcional, neces&aacute si extraemos un nodo 'html')</i></li>
 *    <li><b>need_nl:</b> A&ntilde;ade un \n delante si est&aacute; en la lista need_nl_before <i>(opcional)</i>.</li>
 *    <li><b>inside_pre:</b> Indica si estamos dentro de un bloque 'pre'. Se usa en la recursividad, no usar desde fuera.</li>
 *  </ul>Un ejemplo de su uso podr&iacute;a ser: <span style="color:#dd0000;">ngstk_get_xhtml( ngstk_getElementById('id_objeto'));</span></div>
 ** */
function ngstk_get_xhtml(node, lang, encoding, need_nl, inside_pre) {
  var need_nl_before = '|div|p|table|tbody|tr|td|th|title|head|body|script|comment|li|meta|h1|h2|h3|h4|h5|h6|hr|ul|ol|option|link|';
  var need_nl_after = '|html|head|body|p|th|style|';
  var re_comment = new RegExp("^<!--(([a]|[^a])*)-->$");
  var i;
  var text = '';
  var children = node.childNodes;
  var child_length = children.length;
  var tag_name;
  var do_nl = need_nl?true:false;
  var page_mode = true;
  var media_align = '';
  var re_parsed_val = new Date().getTime();
  for (i=0;i<child_length;i++) {
    var child = children[i];
    if (document.all) {
      if (child.getAttribute && child.getAttribute('re_parsed') == re_parsed_val) continue;
      if (child.setAttribute) child.setAttribute('re_parsed', re_parsed_val);
      }
    if (child.parentNode && String(node.tagName).toLowerCase() != String(child.parentNode.tagName).toLowerCase()) continue;
    switch (child.nodeType) {
      case 1: { //ELEMENT_NODE
        var tag_name = String(child.tagName).toLowerCase();
        //store value of align attribute as IE cannot handle it properly
        if (document.all && tag_name == 'embed') {
          var parameter = /align=("[^\"]*"|'[^\']*'|[^\"\'\s]*)(\s|\>)/i;
          var align_code = String(child.outerHTML).match(parameter);
          if (align_code) {
            align_code = align_code[1];
            media_align = align_code.replace(/("|')/g,"");
            }
          }
        if (tag_name == '') break;
        if (tag_name == 'meta') {
          var meta_name = String(child.name).toLowerCase();
          if (meta_name == 'generator') break;
          }
        if (document.all && tag_name == 'object' && !(child.canHaveChildren || child.hasChildNodes())) {
          text += fix_object_code(child.outerHTML);
          continue;
          }
        if (!need_nl && tag_name == 'body') page_mode = false;
        if (tag_name == '!') {
          var parts = re_comment.exec(child.text);
          if (parts) {
            //the last char of the comment text must not be a hyphen
            var inner_text = parts[1];
            text += fix_comment(inner_text);
            }
          }
         else {
          if (tag_name == 'html') text = '<.?xml version="1.0" encoding="'+encoding+'"?>\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n';
          if (need_nl_before.indexOf('|'+tag_name+'|') != -1) {
            if ((do_nl || text != '') && !inside_pre) text += '\n';
             else do_nl = true;
            }
          text += '<'+tag_name;
          //add attributes
          var attr = child.attributes;
          var attr_length = attr.length;
          var attr_value;
          var attr_lang = false;
          var attr_xml_lang = false;
          var attr_xmlns = false;
          var is_alt_attr = false;
          for (j=0;j<attr_length;j++) {
            var attr_name = attr[j].nodeName.toLowerCase();
            if (attr_name == 're_parsed') continue;
            if (!attr[j].specified && attr_name != 'selected' && attr_name != 'style' && attr_name != 'value' && attr_name != 'shape' && attr_name != 'coords') continue; //IE 5.0
            if ((attr_name == 'shape' || attr_name == 'coords') && tag_name != 'area') continue;
            if (attr_name == 'selected' && !child.selected || attr_name == 'style' && child.style.cssText == '') continue;
            if (attr_name == '_moz_dirty' || attr_name == '_moz_resizing' || attr_name == '_moz-userdefined' || tag_name == 'br' && attr_name == 'type' && child.getAttribute('type') == '_moz') continue;
            var valid_attr = true;
            switch (attr_name) {
              case "style" :
                attr_value = child.style.cssText;
                break;
                case "class" :
               attr_value = child.className;
               break;
              case "http-equiv":
                attr_value = child.httpEquiv;
                break;
              case "noshade": //this set of choices will extend
              case "checked":
              case "selected":
              case "multiple":
              case "nowrap":
              case "disabled":
                attr_value = attr_name;
                break;
              case "name":
                attr_value = child.name?child.name:child.getAttribute('name');
                break;
              case "for":
                attr_value = child.htmlFor;
                break;
              default:
                try {
                  attr_value = child.getAttribute(attr_name, 2);
                  }
                 catch (e) {
                  valid_attr = false;
                  }
              }
            if (tag_name == 'embed') {
              switch (attr_name) {
                case 'align':
                  if (media_align) attr_value = media_align;
                   else attr_value = eval('child.'+attr_name);
                  break;
                case 'showstatusbar':
                case 'showcontrols':
                case 'autostart':
                case 'type':
                  attr_value = attr[j].nodeValue;
                  break;
                default:
                  break;
                }
              }
            if (attr_name == 'lang' && tag_name == 'html') {
              attr_lang = true;
              attr_value = lang;
              }
            if (attr_name == 'xml:lang') {
              attr_xml_lang = true;
              attr_value = lang;
              }
            if (attr_name == 'xmlns') attr_xmlns = true;
            if (tag_name == 'object' && attr_name == 'src' && document.all) attr_value = fix_object_src(child.outerHTML);
            if (valid_attr) if (!(tag_name == 'li' && attr_name == 'value')) text += ' '+attr_name+'="'+fix_attribute(attr_value)+'"';
            if (attr_name == 'alt') is_alt_attr = true;
            }
          if (tag_name == 'img' && !is_alt_attr) text += ' alt=""';
          if (tag_name == 'html') {
            if (!attr_lang) text += ' lang="'+lang+'"';
            if (!attr_xml_lang) text += ' xml:lang="'+lang+'"';
            if (!attr_xmlns) text += ' xmlns="http://www.w3.org/1999/xhtml"';
            }
          if (child.canHaveChildren || child.hasChildNodes()){
            text += '>';
            text += ngstk_get_xhtml(child, lang, encoding, true, inside_pre||tag_name=='pre'?true:false);
            text += '</'+tag_name+'>';
            }
           else {
            if (tag_name == 'style' || tag_name == 'title' || tag_name == 'script' || tag_name == 'textarea' || tag_name == 'a') {
              text += '>';
              var inner_text;
              if (tag_name == 'script') inner_text = child.text;
               else inner_text = child.innerHTML;
              if (tag_name == 'style') inner_text = String(inner_text).replace(/[\n]+/g,'\n');
              text += inner_text+'</'+tag_name+'>';
              }
             else text += ' />';
            }
          }
        break;
        }
      case 3: {
        if (!inside_pre) {
          if (child.nodeValue != '\n') text += fix_entities(fix_text(child.nodeValue));
          }
         else text += child.nodeValue;
        break;
        }
      case 8: {
        text += fix_comment(child.nodeValue);
        break;
        }
      default:
        break;
      }
    }
  if (!need_nl && !page_mode) text = text.replace(/<\/?head>[\n]*/gi, "").replace(/<head \/>[\n]*/gi, "").replace(/<\/?body>[\n]*/gi, "");
  return text;
  }

function fix_comment(text){
  var re_hyphen = new RegExp("-$");
  text = text.replace(/--/g, "__");
  if(re_hyphen.exec(text)) text += " ";
  return "<!--"+text+"-->";
  }

function fix_text(text) {
  var temp_text = String(text).replace(/\&lt;/g, "#h2x_lt").replace(/\&gt;/g, "#h2x_gt");
  temp_text = temp_text.replace(/\n{2,}/g, "\n").replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\u00A0/g, "&nbsp;");
  return temp_text.replace(/#h2x_lt/g, "&lt;").replace(/#h2x_gt/g, "&gt;");
  }

function fix_attribute(text) {
  var temp_text = String(text).replace(/\&lt;/g, "#h2x_lt").replace(/\&gt;/g, "#h2x_gt");
  temp_text = temp_text.replace(/\&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;");
  return temp_text.replace(/#h2x_lt/g, "&lt;").replace(/#h2x_gt/g, "&gt;");
  }

function fix_object_src(text) {
  var temp = String(text);
  var obj_tag_parts = text.match(/<object ([^>]+)>/i);
  if(obj_tag_parts){
    var src_value = obj_tag_parts[1].match(/src="([^"]+)"/i);
    if (!src_value) {
      src_value = obj_tag_parts[1].match(/src='([^']+)'/i);
      if (!src_value) src_value = obj_tag_parts[1].match(/src=([^ ]+)/i);
      }
    if (src_value) return src_value[1];
    }
  return '';
  }

function fix_object_code(text) {
  return String(text).replace(/ style=/gi, ' style=').replace(/ codeBase=/gi, ' codebase=').replace(/ height=/gi, ' height=').replace(/ width=/gi, ' width=').replace(/ align=/gi, ' align=').replace(/ classid=/gi, ' classid=').replace(/ src=/gi, ' src=').replace(/ NAME=/gi, ' name=').replace(/ VALUE=/gi, ' value=').replace(/ quality=/gi, ' quality=').replace(/ TYPE=/gi, ' type=').replace(/ PLUGINSPAGE=/gi, ' pluginspage=').replace(/<OBJECT /gi, '<object ').replace(/<\/OBJECT>/gi, '</object>').replace(/<PARAM /gi, '<param ').replace(/<\/PARAM>/gi, '</param>').replace(/<EMBED /gi, '<embed ').replace(/<\/EMBED>/gi, '</embed>');
  }

function fix_entities(text) {
  var i;
  var ents = {
    8364 : "euro",
    402  : "fnof",
    8240 : "permil",
    352  : "Scaron",
    338  : "OElig",
    381  : "#381",
    8482 : "trade",
    353  : "scaron",
    339  : "oelig",
    382  : "#382",
    376  : "Yuml",
    162  : "cent",
    163  : "pound",
    164  : "curren",
    165  : "yen",
    166  : "brvbar",
    167  : "sect",
    168  : "uml",
    169  : "copy",
    170  : "ordf",
    171  : "laquo",
    172  : "not",
    173  : "shy",
    174  : "reg",
    175  : "macr",
    176  : "deg",
    177  : "plusmn",
    178  : "sup2",
    179  : "sup3",
    180  : "acute",
    181  : "micro",
    182  : "para",
    183  : "middot",
    184  : "cedil",
    185  : "sup1",
    186  : "ordm",
    187  : "raquo",
    188  : "frac14",
    189  : "frac12",
    190  : "frac34",
    191  : "iquest",
    192  : "Agrave",
    193  : "Aacute",
    194  : "Acirc",
    195  : "Atilde",
    196  : "Auml",
    197  : "Aring",
    198  : "AElig",
    199  : "Ccedil",
    200  : "Egrave",
    201  : "Eacute",
    202  : "Ecirc",
    203  : "Euml",
    204  : "Igrave",
    205  : "Iacute",
    206  : "Icirc",
    207  : "Iuml",
    208  : "ETH",
    209  : "Ntilde",
    210  : "Ograve",
    211  : "Oacute",
    212  : "Ocirc",
    213  : "Otilde",
    214  : "Ouml",
    215  : "times",
    216  : "Oslash",
    217  : "Ugrave",
    218  : "Uacute",
    219  : "Ucirc",
    220  : "Uuml",
    221  : "Yacute",
    222  : "THORN",
    223  : "szlig",
    224  : "agrave",
    225  : "aacute",
    226  : "acirc",
    227  : "atilde",
    228  : "auml",
    229  : "aring",
    230  : "aelig",
    231  : "ccedil",
    232  : "egrave",
    233  : "eacute",
    234  : "ecirc",
    235  : "euml",
    236  : "igrave",
    237  : "iacute",
    238  : "icirc",
    239  : "iuml",
    240  : "eth",
    241  : "ntilde",
    242  : "ograve",
    243  : "oacute",
    244  : "ocirc",
    245  : "otilde",
    246  : "ouml",
    247  : "divide",
    248  : "oslash",
    249  : "ugrave",
    250  : "uacute",
    251  : "ucirc",
    252  : "uuml",
    253  : "yacute",
    254  : "thorn",
    255  : "yuml",
    913  : "Alpha",
    914  : "Beta",
    915  : "Gamma",
    916  : "Delta",
    917  : "Epsilon",
    918  : "Zeta",
    919  : "Eta",
    920  : "Theta",
    921  : "Iota",
    922  : "Kappa",
    923  : "Lambda",
    924  : "Mu",
    925  : "Nu",
    926  : "Xi",
    927  : "Omicron",
    928  : "Pi",
    929  : "Rho",
    931  : "Sigma",
    932  : "Tau",
    933  : "Upsilon",
    934  : "Phi",
    935  : "Chi",
    936  : "Psi",
    937  : "Omega",
    8756 : "there4",
    8869 : "perp",
    945  : "alpha",
    946  : "beta",
    947  : "gamma",
    948  : "delta",
    949  : "epsilon",
    950  : "zeta",
    951  : "eta",
    952  : "theta",
    953  : "iota",
    954  : "kappa",
    955  : "lambda",
    956  : "mu",
    957  : "nu",
    968  : "xi",
    969  : "omicron",
    960  : "pi",
    961  : "rho",
    962  : "sigmaf",
    963  : "sigma",
    964  : "tau",
    965  : "upsilon",
    966  : "phi",
    967  : "chi",
    968  : "psi",
    969  : "omega",
    8254 : "oline",
    8804 : "le",
    8260 : "frasl",
    8734 : "infin",
    8747 : "int",
    9827 : "clubs",
    9830 : "diams",
    9829 : "hearts",
    9824 : "spades",
    8596 : "harr",
    8592 : "larr",
    8594 : "rarr",
    8593 : "uarr",
    8595 : "darr",
    8220 : "ldquo",
    8221 : "rdquo",
    8222 : "bdquo",
    8805 : "ge",
    8733 : "prop",
    8706 : "part",
    8226 : "bull",
    8800 : "ne",
    8801 : "equiv",
    8776 : "asymp",
    8230 : "hellip",
    8212 : "mdash",
    8745 : "cap",
    8746 : "cup",
    8835 : "sup",
    8839 : "supe",
    8834 : "sub",
    8838 : "sube",
    8712 : "isin",
    8715 : "ni",
    8736 : "ang",
    8711 : "nabla",
    8719 : "prod",
    8730 : "radic",
    8743 : "and",
    8744 : "or",
    8660 : "hArr",
    8658 : "rArr",
    9674 : "loz",
    8721 : "sum",
    8704 : "forall",
    8707 : "exist",
    8216 : "lsquo",
    8217 : "rsquo",
    161  : "iexcl",
    977  : "thetasym",
    978  : "upsih",
    982  : "piv",
    8242 : "prime",
    8243 : "Prime",
    8472 : "weierp",
    8465 : "image",
    8476 : "real",
    8501 : "alefsym",
    8629 : "crarr",
    8656 : "lArr",
    8657 : "uArr",
    8659 : "dArr",
    8709 : "empty",
    8713 : "notin",
    8727 : "lowast",
    8764 : "sim",
    8773 : "cong",
    8836 : "nsub",
    8853 : "oplus",
    8855 : "otimes",
    8901 : "sdot",
    8968 : "lceil",
    8969 : "rceil",
    8970 : "lfloor",
    8971 : "rfloor",
    9001 : "lang",
    9002 : "rang",
    710  : "circ",
    732  : "tilde",
    8194 : "ensp",
    8195 : "emsp",
    8201 : "thinsp",
    8204 : "zwnj",
    8205 : "zwj",
    8206 : "lrm",
    8207 : "rlm",
    8211 : "ndash",
    8218 : "sbquo",
    8224 : "dagger",
    8225 : "Dagger",
    8249 : "lsaquo",
    8250 : "rsaquo"
    };
  var new_text = '';
  var temp = new RegExp("[a]|[^a]", "g");
  var parts = text.match(temp);
  if (!parts) return text;
  for (i=0; i<parts.length; i++) {
    var c_code = parseInt(parts[i].charCodeAt());
    if (ents[c_code]) new_text += "&"+ents[c_code]+";";
     else new_text += parts[i];
    }
  return new_text;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_windowInnerSize()</div>
 *  <div class="ngstk_descripcion">Caracter&iacute;sticas internas de la ventana:<ul>
 *    <li>Ancho, Alto de la ventana.</li>
 *    <li>Ancho, Alto total, contando el scroll, de la p&aacute;gina.</li>
 *    <li>La posici&oacute; x e y del scroll.</li>
 *  </ul></div>
 ** */
function ngstk_windowInnerSize() {
  if( document.body ) {
    var Width = document.compatMode=='CSS1Compat' && !window.opera ? document.documentElement.clientWidth:document.body.clientWidth;
    var Height = document.compatMode=='CSS1Compat' && !window.opera ? document.documentElement.clientHeight:document.body.clientHeight;
    var scrOfX = false;
    var scrOfY = false;
    var xWithScroll = false;
    var yWithScroll = false;
    if( window.scrollX ) {
      scrOfX = window.scrollX;
      scrOfY = window.scrollY;
      }
    //if ( document.documentElement && document.body && document.body.scrollTop ) {
     else {
      scrOfX = document.documentElement.scrollLeft + document.body.scrollLeft;
      scrOfY = document.documentElement.scrollTop + document.body.scrollTop;
      }
    if (window.innerHeight && window.scrollMaxY) { // FF
      yWithScroll = window.innerHeight + window.scrollMaxY;
      xWithScroll = window.innerWidth + window.scrollMaxX;
      }
     else if (document.body.scrollHeight > document.body.offsetHeight){ // Todo menos IE-Mac
      yWithScroll = document.body.scrollHeight;
      xWithScroll = document.body.scrollWidth;
      }
     else { // IE6 Strict, Mozilla (no FF) y Safari
      yWithScroll = document.body.offsetHeight;
      xWithScroll = document.body.offsetWidth;
      }
    return [Width, Height, xWithScroll, yWithScroll, scrOfX, scrOfY];
    }
  else return [0,0,0,0,0,0];
  }

































/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de control sobre el rat&oacute;n.<br />
 * <b>Licencia: GPL</b></div>
 ** */



/* **
 *  <div class="ngstk_funcion">ngstk_mouse[] ("Xarea", "Yarea", "Xpage", "Ypage")</div>
 *  <div class="ngstk_descripcion">Array global para controlar la posici&oacute;n del mouse en cualquier funci&oacute;n javascript. Mediante este array asociativo se puede saber en todo momento y en tiempo real la posici&oacute;n del puntero del rat&oacute;n.</div>
 ** */
var ngstk_mouse = new Array();
ngstk_mouse["Xarea"]=0;
ngstk_mouse["Yarea"]=0;
ngstk_mouse["Xpage"]=0;
ngstk_mouse["Ypage"]=0;


/* **
 *  <div class="ngstk_funcion">ngstk_MouseMove (e)</div>
 *  <div class="ngstk_descripcion">Control del rat&oacute; se recogen las posiciones y se guardan en sus correspondientes variables. Se usa con un evento mousemove para seguir el mouse.<ul>
 *    <li><b>e:</b> Variable para recoger el evento en Mozilla.</li>
 *  </ul></div>
 ** */

function ngstk_mouseMove(e) {
  if (!e) var e = window.event;
  ngstk_mouse["Xarea"] = e.clientX;
  ngstk_mouse["Yarea"] = e.clientY;
  if ( document.documentElement && document.body && document.body.scrollTop ) {
    ngstk_mouse["Xscroll"] = document.documentElement.scrollLeft + document.body.scrollLeft;
    ngstk_mouse["Yscroll"] = document.documentElement.scrollTop + document.body.scrollTop;
    }
   else {
    ngstk_mouse["Xscroll"] = window.scrollX;
    ngstk_mouse["Yscroll"] = window.scrollY;
    }
  ngstk_mouse["Xpage"] = ngstk_mouse["Xarea"] + ngstk_mouse["Xscroll"];
  ngstk_mouse["Ypage"] = ngstk_mouse["Yarea"] + ngstk_mouse["Yscroll"];
  }


/* **
 *  <div class="ngstk_funcion">ngstk_dragStart (id, e)</div>
 *  <div class="ngstk_descripcion">Inicio de la accion de arrastre.<ul>
 *    <li><b>id:</b> id del elemento a arrastrar.</li>
 *    <li><b>e:</b> Variable para recoger el evento en Mozilla.</li>
 *  </ul></div>
 ** */
var ngstk_dragObj = new Object(); // Objeto que se esta arrastrando.
ngstk_dragObj.zIndex = 0;
function ngstk_dragStart(id,e) {
 ngstk_dragObj.elNode = ngstk_getElementById(id);
 if( !ngstk_dragObj.elNode ) {
  alert("Naguissa Toolkit Error: Se inicia un dragg con un elemento no existente.");
  return;
  }
 // Guardamos las posiciones iniciales del cursor y del elemento.
 ngstk_dragObj.cursorStartX = ngstk_mouse["Xpage"];
 ngstk_dragObj.cursorStartY = ngstk_mouse["Ypage"];
 var tmp = ngstk_findPos(ngstk_dragObj.elNode);
 ngstk_dragObj.elStartLeft  = tmp[0];
 ngstk_dragObj.elStartTop   = tmp[1];
 if (isNaN(ngstk_dragObj.elStartLeft)) ngstk_dragObj.elStartLeft = ngstk_mouse["Xpage"];
 if (isNaN(ngstk_dragObj.elStartTop))  ngstk_dragObj.elStartTop  = ngstk_mouse["Ypage"];
 // Actualizamos el z-index del objeto.
 ngstk_dragObj.elNode.style.zIndex = ++ngstk_dragObj.zIndex;

 // Capturamos los eventos de movimiento y de stop.
 ngstk_addEvent(document,"mousemove",ngstk_dragGo);
 ngstk_addEvent(document,"mouseup",ngstk_dragStop);
 }

/* **
 *  <div class="ngstk_funcion">ngstk_dragGo (e)</div>
 *  <div class="ngstk_descripcion">Movimiento de un objeto, acci&oacute;n de arrastre.<ul>
 *    <li><b>e:</b> Variable para recoger el evento en Mozilla.</li>
 *  </ul></div>
 ** */
function ngstk_dragGo(e) {
 ngstk_dragObj.elNode.style.left = (ngstk_dragObj.elStartLeft + ngstk_mouse["Xpage"] - ngstk_dragObj.cursorStartX) + "px";
 ngstk_dragObj.elNode.style.top  = (ngstk_dragObj.elStartTop  + ngstk_mouse["Ypage"] - ngstk_dragObj.cursorStartY) + "px";
 if ( typeof(window.event) != "undefined") {
  if ( typeof(window.event.cancelBubble) != "undefined") window.event.cancelBubble = true;
  if ( typeof(window.event.returnValue) != "undefined") window.event.returnValue = false;
  }
 if ( typeof( e.preventDefault ) != "undefined" ) e.preventDefault();
 }


/* **
 *  <div class="ngstk_funcion">ngstk_dragStop (e)</div>
 *  <div class="ngstk_descripcion">Finalizar la acci&oacute;n de arrastre.<ul>
 *    <li><b>e:</b> Variable para recoger el evento en Mozilla.</li>
 *  </ul></div>
 ** */
function ngstk_dragStop(e) {
 ngstk_removeEvent(document,"mousemove",ngstk_dragGo);
 ngstk_removeEvent(document,"mouseup",ngstk_dragStop);
}


// Iniciamos el rastreo del raton.
ngstk_addEvent(document,"mousemove",ngstk_mouseMove);


/* **
 *  <div class="ngstk_funcion">ngstk_mouseAnimationMoveToArea (destx, desty, milis, wait)</div>
 *  <div class="ngstk_descripcion"><i>Desarrollo, actualmente solo Mozilla.</i> Mover un rat&oacute;n ficticio desde la posicion actual a un lugar x e y de la pantalla.<ul>
 *    <li><b>destx:</b> Posici&oacute;n X de la p&aacute;gina.</li>
 *    <li><b>desty:</b> Posici&oacute;n Y de la p&aacute;gina.</li>
 *    <li><b>milis:</b> Tiempo en ms. para completar la acci&oacute;n.</li>
 *    <li><b>wait:</b> Tiempo en ms. en los que el puntero virtual queda encendido hasta desvanecerse.</li>
 *  </ul></div>
 ** */
function ngstk_mouseAnimationMoveToArea(destx, desty, milis, wait) {
  ngstk_mouseAnimationMoveFromAreaToArea(ngstk_mouse["Xpage"],ngstk_mouse["Ypage"],destx, desty, milis, wait);
  }


/* **
 *  <div class="ngstk_funcion">ngstk_mouseAnimationMoveToObject (id, milis, wait)</div>
 *  <div class="ngstk_descripcion"><i>Desarrollo, actualmente solo Mozilla.</i> Mover un rat&oacute;n ficticio desde la posicion actual a la posici&oacute;n de otro objeto.<ul>
 *    <li><b>id:</b> id del objeto de destino.</li>
 *    <li><b>milis:</b> Tiempo en ms. para completar la acci&oacute;n.</li>
 *    <li><b>wait:</b> Tiempo en ms. en los que el puntero virtual queda encendido hasta desvanecerse.</li>
 *  </ul></div>
 ** */
function ngstk_mouseAnimationMoveToObject(id, milis, wait) {
 var obj = ngstk_getElementById(id);
 if( obj != false ) {
  var dest = ngstk_findPos(obj);
  ngstk_mouseAnimationMoveFromAreaToArea(ngstk_mouse["Xpage"],ngstk_mouse["Ypage"],(dest[0]+dest[2])/2, (dest[1]+dest[3])/2, milis, wait);
  }
 }


/* **
 *  <div class="ngstk_funcion">ngstk_mouseAnimationMoveFromAreaToArea (origx, origy, destx, desty, milis, wait, e)</div>
 *  <div class="ngstk_descripcion"><i>Desarrollo, actualmente solo Mozilla.</i> Mover un rat&oacute;n ficticio de una posici&oacute;n de la pantalla a otra.<ul>
 *    <li><b>origx:</b> Posici&oacute;n X inicial de la p&aacute;gina.</li>
 *    <li><b>origy:</b> Posici&oacute;n Y inicial de la p&aacute;gina.</li>
 *    <li><b>destx:</b> Posici&oacute;n X final de la p&aacute;gina.</li>
 *    <li><b>desty:</b> Posici&oacute;n Y final de la p&aacute;gina.</li>
 *    <li><b>milis:</b> Tiempo en ms. para completar la acci&oacute;n.</li>
 *    <li><b>wait:</b> Tiempo en ms. en los que el puntero virtual queda encendido hasta desvanecerse.</li>
 *  </ul></div>
 ** */
function ngstk_mouseAnimationMoveFromAreaToArea(origx, origy, destx, desty, milis, wait, e) {
 origx = parseInt(origx);
 origy = parseInt(origy);
 destx = parseInt(destx);
 desty = parseInt(desty);
 wait = parseInt(wait);
 milis = parseInt(milis);
 var actx = origx;
 var acty = origy;
 if( typeof(destx)!="number" ) destx = -1;
 if( typeof(desty)!="number" ) desty = -1;
 if( typeof(milis)!="number" ) milis = 1;
 if( typeof(wait)!="number" ) wait = 2000;
 if( milis < 1 ) milis = 1;
 if( wait < 1 ) wait = 1;
 if( destx >= 0 && desty >= 0 ) {
  // Creamos la imagen del puntero:
  z = document.createElement("img");
  z.setAttribute("src", config["IMAGE_URL"]+"puntero.gif");
  z.setAttribute("alt", "i");
  z.setAttribute("id", "ngstk_pointer");
  z.setAttribute("title", "Puntero simulado");
  z.setAttribute("border", "0");
  z.setAttribute("style", "position:absolute;top:" + ngstk_mouse["Ypage"] + "px;left:" + ngstk_mouse["Xpage"] + "px;z-index:99;");
  document.body.appendChild(z);
  // Programamaos sus moviemientos (maximo 100):
  var ciclos = milis;
  if (milis > 100) ciclos = 100;
  var retardo = milis/ciclos;
  incx = (destx - actx) / ciclos;
  incy = (desty - acty) / ciclos;
  for( var i = 1; i < ciclos; i++) {
   actx += incx;
   acty += incy;
   window.setTimeout("ngstk_moveObjectToXY('ngstk_pointer','" + actx +"px', '" + acty + "px')", parseInt(retardo*i));
   }
  window.setTimeout("ngstk_moveObjectToXY('ngstk_pointer', '" + destx + "px', '" + desty + "px')", parseInt(retardo*i));
  window.setTimeout("ngstk_removeObject('ngstk_pointer')", parseInt(milis+wait));
  }
 }

// Precargamos la imagen del puntero
tmp = new Array(config["IMAGE_URL"]+"puntero.gif");
ngstk_preloadimg(tmp);
























/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de compatibilidad cross-browser y simplificaci&oacute;n de peticiones XML-RPC mediante JavaScript.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_xml()</div>
 *  <div class="ngstk_descripcion">Clase principal</div>
 ** */
function ngstk_xml() {
/* **
 *  <div class="ngstk_funcion">ngstk_xmlreq()</div>
 *  <div class="ngstk_descripcion">Subclase con toda la funcionalidad.</div>
 ** */
 function ngstk_xmlreq() {
  // Variables locales de la clase:
  var xmlreq;
  var xmlokfun;
  var xmlstatusfun;
  var xmlextra;

  // Funcion local de estado. Maneja los cambios de estado de la peticion XML-RPC. Llama a xmlstatusfun y a xmlokfun si estan definidas
  function status() {
   if(xmlstatusfun) xmlstatusfun(xmlreq,xmlextra);
   if(xmlokfun) if (xmlreq.readyState == 4) if (xmlreq.status == 200) xmlokfun(xmlreq,xmlextra);
   }


  // Funcion publica combinada. Permite enviar datos mediante POST y espera la respuesta del sistema remoto.
  this.enviaryrecibir = function(url, xml, okfun, statusfun, extra) {
   xmlokfun = okfun;
   xmlstatusfun = statusfun;
   xmlextra = extra;
   if (window.XMLHttpRequest){
    xmlreq = new XMLHttpRequest();
    xmlreq.onreadystatechange = status;
    if(xml) {
     xmlreq.open("POST", url, true);
     xmlreq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     xmlreq.setRequestHeader("Content-length", xml.length);
     xmlreq.setRequestHeader("Connection", "close");
     xmlreq.send(xml);
     }
    else {
     xmlreq.open("GET", url, true);
     xmlreq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     xmlreq.send(null);
     }
    }
   else if (window.ActiveXObject) {
    xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
    xmlreq.onreadystatechange = status;
    if(xml) {
     xmlreq.open("POST", url, true);
     xmlreq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     xmlreq.setRequestHeader("Content-length", xml.length);
     xmlreq.setRequestHeader("Connection", "close");
     xmlreq.send(xml);
     }
    else {
     xmlreq.open("GET", url, true);
     xmlreq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
     xmlreq.send();
     }
    }
   else {
    alert("No se dispone de soporte XML-rpc");
    return false;
    }
   return true;
   }


  // Final de la subclase
  }


/* **
 *  <div class="ngstk_funcion">ngstk_xml.enviaryrecibir(url, xml, okfun, statusfun, extra)</div>
 *  <div class="ngstk_descripcion">Funcion publica combinada. Permite enviar datos mediante POST y espera la respuesta del sistema remoto.<ul>
 *    <li><b>url</b>: Url donde se enviar&aacute; la petici&oacute;n</li>
 *    <li><b>xml</b>: XML que se enviar&aacute;.</li>
 *    <li><b>okfun</b>: Funci&oacute;n que se ejecuta cuando se recibe la respuesta.</li>
 *    <li><b>statusfun</b>: Funci&oacute;n que se ejecuta en los cambios de estado.</li>
 *    <li><b>extra</b>: Datos extra que se pasar&aacute;n a las llamadas a las funciones de status y de ok.</li>
 *  </ul></div>
 ** */
 this.enviaryrecibir=function(url, xml, okfun, statusfun, extra) {
  var req = new ngstk_xmlreq();
  // Anyadimos un parametro para que no haga cache.
  if( url.indexOf( "?" ) == -1 ) url += "?";
   else url += "&";
  url += "ngstk_nocache=" + Math.random(1000);
  req.enviaryrecibir(url, xml, okfun, statusfun, extra);
  delete req;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_xml.enviar(url, xml, okfun, statusfun, extra)</div>
 *  <div class="ngstk_descripcion">Funcion publica de envio. Permite enviar datos mediante POST y espera la respuesta del sistema remoto.<ul>
 *    <li><b>url</b>: Url donde se enviar&aacute; la petici&oacute;n</li>
 *    <li><b>xml</b>: XML que se enviar&aacute;.</li>
 *    <li><b>okfun</b>: Funci&oacute;n que se ejecuta cuando se recibe la respuesta.</li>
 *    <li><b>statusfun</b>: Funci&oacute;n que se ejecuta en los cambios de estado.</li>
 *    <li><b>extra</b>: Datos extra que se pasar&aacute;n a las llamadas a las funciones de status y de ok.</li>
 *  </ul></div>
 ** */
  this.enviar=function(url, xml, okfun, statusfun, extra) {
   return this.enviaryrecibir(url, xml, okfun, statusfun, extra);
   }

/* **
 *  <div class="ngstk_funcion">ngstk_xml.recibir(url, okfun, statusfun, extra)</div>
 *  <div class="ngstk_descripcion">Funcion publica de recepcion. Permite enviar una peticion a una url y esperar la respuesta del sistema remoto.<ul>
 *    <li><b>url</b>: Url donde se enviar&aacute; la petici&oacute;n</li>
 *    <li><b>okfun</b>: Funci&oacute;n que se ejecuta cuando se recibe la respuesta.</li>
 *    <li><b>statusfun</b>: Funci&oacute;n que se ejecuta en los cambios de estado.</li>
 *    <li><b>extra</b>: Datos extra que se pasar&aacute;n a las llamadas a las funciones de status y de ok.</li>
 *  </ul></div>
 ** */
  this.recibir=function(url, okfun, statusfun, extra) {
   return this.enviaryrecibir(url, false, okfun, statusfun, extra);
   }

 // Final de la clase
 }

/* **
 *  <div class="ngstk_funcion">ngstk_xmlvar</div>
 *  <div class="ngstk_descripcion">Variable con la que podemos usar los m&eacute;todos de ngtk_xml directamente. Se pueden declarar otras.</div>
 ** */
var ngstk_xmlvar = new ngstk_xml();































/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de temporizadores. Aglutina todos los temporizadores en uno solo. Adem&aacute;s, permite pasar un par&aacute;metro a las funciones temporizadas.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_timer()</div>
 *  <div class="ngstk_descripcion">Clase principal</div>
 ** */
function ngstk_timer() {
  var eventos = new Array();
  // [0] = fn;
  // [1] = delay
  // [2] = interval
  // [3] = extra

  var next_pos;
  var next_time;
  var handle;
  var activo = false;
  var cnt = 0;

  // Funcion interna de actualizaciones.
  function Update() {
    var i;
    var dt = new Date();
    if( activo ) {
      clearTimeout( handle );
      activo = false;
      }
    for(i in eventos) if( eventos[i] ) if( ( !activo || eventos[i][1] <= next_time ) && dt.getTime() < eventos[i][1] ) {
      next_time = eventos[i][1];
      next_pos = i;
      activo = true;


      }
    if( activo ) handle = setTimeout( Play, next_time - dt.getTime() );
    }


/* **
 *  <div class="ngstk_funcion">AddTimeout(fn, d, e)</div>
 *  <div class="ngstk_descripcion">Ejecuta una funci&oacute;n pasado un intervalo de tiempo con un par&aacute;metro.<ul>
 *    <li><b>fn:</b> Funci&oacute;n a temporizar.</li>
 *    <li><b>d:</b> Milisegundos de retraso antes de la ejecuci&oacute;n.</li>
 *    <li><b>e:</b> Par&aacute;metro extra; se pasar&aacute; cuando se llame a la funci&oacute;n.</li>
 *  </ul></div>
 ** */
  this.AddTimeout = function(fn, d, e) {
    var dt = new Date();
    eventos[cnt] = new Array(fn, d + dt.getTime(),-1,e);
    cnt++;
    Update();
    return( cnt - 1);

    }


/* **
 *  <div class="ngstk_funcion">AddInterval(fn, d, t, e)</div>
 *  <div class="ngstk_descripcion">Ejecuta una funci&oacute;n pasado un intervalo de tiempo con un par&aacute;metro.<ul>
 *    <li><b>fn:</b> Funci&oacute;n a temporizar.</li>
 *    <li><b>d:</b> Milisegundos de retraso antes de la primera ejecuci&oacute;n.</li>
 *    <li><b>t:</b> Milisegundos entre ejecuciones.</li>
 *    <li><b>e:</b> Par&aacute;metro extra; se pasar&aacute; cuando se llame a la funci&oacute;n.</li>
 *  </ul></div>
 ** */
  this.AddInterval = function(fn, d, t, e) {
    var dt = new Date();
    eventos[cnt] = new Array(fn, d + dt.getTime(),t,e);
    cnt++;
    Update();
    return( cnt - 1);
    }


  // Funcion interna que realiza la ejecucion de los eventos.
  function Play() {
    var d = new Date();
    if( activo ) {
      eventos[next_pos][0](eventos[next_pos][3]);
      if( eventos[next_pos][2] > 0 ) eventos[next_pos][1] = d.getTime() + eventos[next_pos][2];
       else eventos[next_pos] = false;
      activo = false;
      }
    Update();
    }

/* **
 *  <div class="ngstk_funcion">Reset()</div>
 *  <div class="ngstk_descripcion">Elimina todos los eventos y se reinicia todo.</div>
 ** */
  this.Reset = function() {
    cnt = 0;

    if( activo ) {
      clearTimeout( handle );
      activo = false;
      }
    }

  // Final de la clase
  }


/* **
 *  <div class="ngstk_funcion">ngstk_timervar</div>
 *  <div class="ngstk_descripcion">Variable para la ejecuci&oacute;n de eventos. Se pueden definir mas, aunque se perder&iacute;a rendimiento.</div>
 ** */
var ngstk_timervar = new ngstk_timer();





















/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de audio compatibles con la mayor&iacute;a de navegadores. No se usa ni java ni flash, sino el reproductor predeterminado embedido.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_playActive</div>
 *  <div class="ngstk_descripcion">Variable global con el n&uacute;mero de archivos reproduci&eacute;ndose actualmente.</div>
 ** */
var ngstk_playActive = 0;


/* **
 *  <div class="ngstk_funcion">ngstk_audio</div>
 *  <div class="ngstk_descripcion">Variable boleana global para activar/desactivar el audio (true/false).</div>
 ** */
var ngstk_audio = true;


/* **
 *  <div class="ngstk_funcion">ngstk_playFile(audioFile, id, dur, del, ovln, force)</div>
 *  <div class="ngstk_descripcion">Reproducir un sonido.<ul>
 *    <li><b>audiofile:</b> URL del sonido a reproducir. Se pueden usar los archivos del toolkit, <i>ngstk.new.php?audiomensaje</i> y <i>ngstk.new.php?audioentrada</i>.</li>
 *    <li><b>id:</b> ID del sonido.</li>
 *    <li><b>dur:</b> Duraci&oacute;n del sonido en segundos. <b>No se autodetecta</b>, por lo que ha de ser correcta.</li>
 *    <li><b>del:</b> Retraso antes de iniciar la reproducci&oacute;n en milisegundos.</li>
 *    <li><b>ovln:</b> Si es true, permite que los siguientes sonidos se superpongan con ?ste. Si es false, los siguientes sonidos no se reproducir&aacute;n mientras se est&eacute; reproduciendo &eacute;ste.</li>
 *    <li><b>force:</b> Si esta opci&oacute;n est&aacute; a true, el se obviar&aacute; la regla anterior. &Uacute;til para sonidos de eventos importantes.</li>
 *  </ul></div>
 ** */
function ngstk_playFile(audioFile, id, dur, del, ovln, force) {
 if( ngstk_audio ) {
  if( !ovln ) ovln = false;
  if( !force ) force = false;
  duration = (dur*1000)+del+300;
  var fn = "ngstk_buildAudio('"+audioFile+"', '" + id + "', "+duration+", false, "+ovln+", "+force+");";
  setTimeout(fn, del);
  }
 }


/* **
 *  <div class="ngstk_funcion">ngstk_playDecrase()</div>
 *  <div class="ngstk_descripcion">Reduce en uno los archivos que se estan reproduciendo actualmente.</div>
 ** */
function ngstk_playDecrase() {
  ngstk_playActive--;
  }



/* **
 *  <div class="ngstk_funcion">ngstk_buildAudio(file, id, time, loop, ovln, force)</div>
 *  <div class="ngstk_descripcion">Reproducir un sonido.<ul>
 *    <li><b>file:</b> URL del sonido a reproducir. Se pueden usar los archivos del toolkit, <i>ngstk.new.php?audiomensaje</i> y <i>ngstk.new.php?audioentrada</i>.</li>
 *    <li><b>id:</b> ID del sonido.</li>
 *    <li><b>time:</b> Duraci&oacute;n del sonido en segundos. <b>No se autodetecta</b>, por lo que ha de ser correcta.</li>
 *    <li><b>loop:</b> Reproducci&oacute;n en bucle, replay.</li>
 *    <li><b>ovln:</b> Si es true, permite que los siguientes sonidos se superpongan con ?ste. Si es false, los siguientes sonidos no se reproducir&aacute;n mientras se est&eacute; reproduciendo &eacute;ste.</li>
 *    <li><b>force:</b> Si esta opci&oacute;n est&aacute; a true, el se obviar&aacute; la regla anterior. &Uacute;til para sonidos de eventos importantes.</li>
 *  </ul></div>
 ** */
function ngstk_buildAudio(file, id, time, loop, ovln, force) {
 if ( (force || ngstk_playactive == 0 ) && ngstk_audio ) {
  if( !ovln ) ngstk_playActive++;
  var attr = new Array();
  attr["id"] = id;
  attr["style"] = "top:0; left:0; position:absolute; z-index:-1;";
  y = ngstk_createObject("div", attr, false);
  document.body.appendChild(y);
  if (document.all) y.innerHTML="&nbsp;<bgsound src=\""+file+"\" autostart=\"true\" loop=\""+ loop + "\"></bgsound>";
   else y.innerHTML='&nbsp;<object width="1" height="1" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701" type="application/x-oleobject"><param name="fileName" value="' + file + '"><param name="animationatStart" value="0"><param name="transparentatStart" value="1"><param name="autoStart" value="1"><param name="ShowControls" value="0"><param name="ShowDisplay" value="0"><param name="ShowStatusBar" value="0"><param name="loop" value="' + loop + '"><embed type="application/x-mplayer2" pluginspage="http://microsoft.com/windows/mediaplayer/ en/download/" id="mediaPlayer" name="mediaPlayer" displaysize="4" autosize="0" bgcolor="transparent" showcontrols="0" showtracker="0" showdisplay="0" showstatusbar="0" videoborder3d="0" width="1" height="1" src="' + file + '" autostart="1" designtimesp="5311" loop="' + loop + '"></embed></object>';
  if( !ovln && time > 0 ) setTimeout("ngstk_playDecrase()", time);
  var fn = "ngstk_removeAudio("+id+")";
  setTimeout(fn, time);
  }
 }


/* **
 *  <div class="ngstk_funcion">ngstk_removeAudio(id)</div>
 *  <div class="ngstk_descripcion">Eliminar un sonido.<ul>
 *    <li><b>id:</b> ID del sonido a eliminar.</li>
 *  </ul></div>
 ** */
function ngstk_removeAudio(id) {
 var obj = ngstk_getElementById(id);
 if( obj ) {
   obj.innerHTML="";
   ngstk_removeObject(id);
   }
 }


/* **
 *  <div class="ngstk_funcion">ngstk_escucharAux(txt, lang, gn)</div>
 *  <div class="ngstk_descripcion">Eliminar un sonido.<ul>
 *    <li><b>txt:</b> Texto a dictar.</li>
 *    <li><b>lang:</b> Idioma (es).</li>
 *    <li><b>gn:</b> G&eacute;nero de la voz (ml -masculino- o fm -femenino-).</li>
 *  </ul></div>
 ** */
function ngstk_escucharAux(txt,lang,gn){
  var attr = new Array();
  attr["id"] = "ngstk_escuchar";
  attr["style"] = "z-index:-1;position:absolute;bottom:2px; right:2px;";
  y = ngstk_createObject("div", attr, false);
  window.document.body.appendChild(y);
  y.innerHTML="<iframe id=\"ngstk_escuchar_if\" name=\"ngstk_escuchar_if\" src=\"about:blank\" style=\"width:1px; height:1px;\"></iframe>";
  var d = window.document;

  // form
  fx_2g=d.createElement('form');
  y.appendChild(fx_2g);
  fx_2g.method='POST';
  fx_2g.target='ngstk_escuchar_if';
  fx_2g.action='http://vozme.com/text2voice.php';

  //text
  t=d.createElement('input');
  t.name='text';
  t.type='hidden';
  t.value=txt;
  fx_2g.appendChild(t);

  //lang
  l=d.createElement('input');
  l.name='lang';
  l.type='hidden';
  l.value=lang;
  fx_2g.appendChild(l);

  //gn

  g=d.createElement('input');
  g.name='gn';
  g.type='hidden';
  g.value=gn;
  fx_2g.appendChild(g);

  //interface
  i=d.createElement('input');
  i.name='interface';
  i.type='hidden';
  i.value='full';
  fx_2g.appendChild(i);

  //submit
  fx_2g.submit();
  delete fx_2g;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_escucharSeleccionStart( [arg1, arg2] )</div>
 *  <div class="ngstk_descripcion">Inicia la alocuci&oacute;n del texto seleccionado.<ul>
 *    <li><b>arg1:</b> Idioma (es).</li>
 *    <li><b>arg2:</b> G&eacute;nero de la voz (ml -masculino- o fm -femenino-).</li>
 *  </ul></div>
 ** */
function ngstk_escucharSeleccionStart(){
  var lang = arguments[0] || 'es';
  var gn = arguments[1] || 'ml'; // ml o fm
  var d=window.document;
  if(window.getSelection) txt=window.getSelection();
   else if(d.getSelection) txt=d.getSelection();
    else if(d.selection) txt=d.selection.createRange().text;
     else txt='';
  if( txt != "" ) ngstk_escucharAux(txt,lang,gn);
   else alert("Has de seleccionar antes el texto que quieres escuchar.");
  }

/* **
 *  <div class="ngstk_funcion">ngstk_escucharSeleccionStart( [arg1, arg2] )</div>
 *  <div class="ngstk_descripcion">Inicia la alocuci&oacute;n del texto seleccionado.<ul>
 *    <li><b>arg1:</b> Idioma (es).</li>
 *    <li><b>arg2:</b> G&eacute;nero de la voz (ml -masculino- o fm -femenino-).</li>
 *  </ul></div>
 ** */
function ngstk_escucharStop(){
  ngstk_getElementById("ngstk_escuchar").innerHTML="";
  ngstk_removeObject("ngstk_escuchar");

  }

























/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de gesti&oacute;n de ventanas. Permite crear  un entorno web persistente y recargar solo las partes neces&aacute;rias.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_wmCheckUrl(url,loc)</div>
 *  <div class="ngstk_descripcion">Comprueba la url y devuelve su tipo.<ul>
 *    <li><b>url:</b> url a comprobar.</li>
 *    <li><b>loc:</b> url con la que comprobar (generalmente location.href).</li>
 *    <li><u>retorno:</u><ul>
 *      <li><b>-2:</b> No se pasa URL.</li>
 *      <li><b>-1:</b> enlace a JavaScript.</li>
 *      <li><b>1:</b> igual a la URL actual.</li>
 *      <li><b>2:</b> Misma p&aacute;gina que la actual.</li>
 *      <li><b>3:</b> Mismo servidor que el actual.</li>
 *      <li><b>4:</b> Distinto servidor que el actual.</li>
 *    </ul></li>
 *  </ul></div>
 ** */
function ngstk_wmCheckUrl(url, loc) {
  if( !url || url=="" ) return(-2);
  if( ngstk_trimL(url).substring(0,11) == "javascript:" || ngstk_trimL(url).substring(0,12) == "javascript :" ) return(-1);                       // Caso -1, JavaScript
  // Si no se pasa loc se coge por defecto
  if( !loc ) loc = location.href;
  if( url == loc ) return(1);
  // Quitamos los 'anchor'
  var pos = loc.indexOf("#");
  if( pos != -1 ) loc = loc.substr(0,pos);
  pos = url.indexOf("#");
  if( pos != -1 ) url = url.substr(0,pos);
  if( url == loc ) return(2);
  // Miramos los servers
  var loc = loc.substr(0, loc.substr(8).indexOf("/")+8 );
  var url = url.substr(0, url.substr(8).indexOf("/")+8 );
  if( loc == url ) return(3);
  return(4);
  }


/* **
 *  <div class="ngstk_funcion">ngstk_wmCheckLinks(o, d)</div>
 *  <div class="ngstk_descripcion">Cambia los enlaces de todos los los subobjetos de un objeto dado para que usen el gestor de ventanas.<ul>
 *    <li><b>o:</o> Objeto del dom a procesar.</li>
 *    <li><b>d:</o> <i>[opcional]</i> ID del objeto donde se cargaran los enlaces. Si no se especifica se usar? el principal, "ngstk_wmmain".</li>
 *  </ul></div>
 ** */
function ngstk_wmCheckLinks(o, d, l) {
  if( !l ) l = location.href;
  if( !d ) d = "ngstk_wmmain";
  if( o ) {
    obj = o.getElementsByTagName("a");
    var e;
    for( e in obj )
     if( obj[e].href && (!obj[e].target || obj[e].target == "_self" ) ){
      var url = obj[e].href;
      if( ngstk_wmCheckUrl(url,l) >= 3 || ngstk_wmCheckUrl(url,l) >= 4 ) {
        // Guardamos el contenido del enlace
        contenido = obj[e].innerHTML;
        // Creamos el icono de ventana nueva
        obj[e].target = "_blank";
        obj[e].innerHTML = "<img src=\""+config["IMAGE_URL"]+"newwin.gif\" alt=\"(pop)\" title=\"Abrir en ventana nueva\" style=\"border:0; height:11px; width:17px;\">";
        // Volvemos a crear el enlace, pero con la funcion del toolkit
        attr=new Array();
        attr["href"] = "javascript:ngstk_wmloadurl('" + url.split("'").join("&#39;") + "', '" + d + "')";
        y = ngstk_createObject("a", attr, contenido);
        obj[e].parentNode.insertBefore(y,obj[e]);
        }
      }
    }
  }


/* **
 *  <div class="ngstk_funcion">ngstk_wmInit(f, e)</div>
 *  <div class="ngstk_descripcion">Inicia el gestor de ventanas.<ul>
 *    <li><b>e:</b> Variable para capturar el evento, de ser llamada por un evento.</li>
 *  </ul></div>
 ** */
function ngstk_wmInit(e) {
  if( !ngstk_getElementById("ngstk_wmmain") && ngstk_wm_test == top ) {
    // Cargamos el CSS de ventanas...
    var attr = new Array();
    attr["rel"] = "stylesheet";
    attr["type"] = "text/css";
    attr["href"] = "http://www.naguissa.com/ngstk.new.php?wmcss";
    var css = ngstk_createObject("link", attr, contenido);
    document.getElementsByTagName("head")[0].appendChild(css);
    document.getElementsByTagName("html")[0].style.height="100%";
    var obj = document.getElementsByTagName("body")[0];
    obj.style.height="100%";
    var contenido = obj.innerHTML;
    obj.innerHTML = "";
    attr = new Array();

    attr["id"] = "ngstk_wmmain";
//    var y = ngstk_createObject("div", attr, contenido);
//    y = ngstk_createWindow("ngstk_wmmain", 12, "xmlrpc=1;", "top:0;bottom:0;left:0;right:0;", false);
    y = ngstk_createWindow("ngstk_wmmain", 12, "xmlrpc=1;", "width:100%;", false);
    ngstk_getElementById("ngstk_wmmain_cnt").innerHTML = contenido;
//    y.style.paddingLeft = obj.style.left;
//    y.style.paddingRight = obj.style.right;
//    y.style.paddingTop = obj.style.top;
//    y.style.paddingBottom = obj.style.bottom;
//    y.style.marginLeft = obj.style.marginLeft;
//    y.style.marginRight = obj.style.marginRight;
//    y.style.marginTop = obj.style.marginTop;
//    y.style.marginBottom = obj.style.marginBottom;
//    y.style.background = obj.style.background;
y.style.height="100%";
y.style.width="100%";
y.style.border="1px solid #000";
    obj.appendChild(y);
    ngstk_wmCheckLinks(y);
    }
  }


/* **
 *  <div class="ngstk_funcion">ngstk_createWindow(id, tipo, opciones, css, url)</div>
 *  <div class="ngstk_descripcion">Crea una ventana nueva (div) con la ID dada y le aplica el css dado al div. Por ?ltimo, lo rellena con su contenido.<ul>
 *    <li><b>id:</b> ID de la nueva ventana (div)</li>
 *    <li><b>tipo:</b> tipo de ventana.<ul>
 *      <li><b>10:</b> <i>(Por defecto)</i> Ventana normal, con t&iacute;tulo, etc.</li>
 *      <li><b>11:</b> Ventana sin t&iacute;tulo, ideal para ventanas flotantes.</li>
 *      <li><b>12:</b> Ventana sin ninguna marca, ideal para el contenido principal.</li>
 *    </ul></li>
 *    <li><b>opciones:</b> Opciones de la ventana, separadas por punto y coma (;):<ul>
 *      <li><b>xmlrpc=0/1; :</b> La ventana se carga mediante XML-RPC (solo p&aacute;ginas locales al servidor) (1=si, <u>0=no</u>).</li>
 *      <li><b>dragg=0/1; :</b> La ventana se puede arrastrar (1=si, <u>0=no</u>).</li>
 *      <li><b>float=0/1; :</b> La ventana flota verticalmente (1=si, <u>0=no</u>).</li>
 *      <li><b>titulo=xxxxxxx; :</b> T&iacute;tulo de la ventana. Se mostrar&aacute; si es del tipo 10.</li>
 *    </ul></li>
 *    <li><b>css:</b> La ventana flota verticalmente.</li>
 *    <li><b>url:</b> <i>(opcional)</i> URL a cargar..</li>
 *  </ul></div>
 ** */
function ngstk_createWindow(id, tipo, opciones, css, url) {
  if( id && !ngstk_getElementById(id) && !ngstk_getElementById(id+"_if") && !ngstk_getElementById(id+"_cnt") ) {
    var attr = new Array();
    var titulo = "Sin t&iacute;tulo"; // Si no pasamos un t&iacute;tulo ponemos uno por defecto
    var dragg = false;
    var float = false;
    var xmlrpc = false;
    var estilo="";
    var html="";
    switch( ""+tipo ) {
      case "12":  // Sin marca
        estilo = "ngstk_wm_invisible";
        html = "<div id=\""+ id +"_cnt\" style=\"height:100%;width:100%;\"></div>\n";
        break;
      case "11":  // Borde, pero no titulo.
        estilo = "ngstk_wm_notitle";
        html = "<div id=\""+ id +"_cnt\" style=\"height:100%;width:100%;\"></div>\n";
        break;
      default:  // Ventana normal.
        estilo = "ngstk_wm_normal";
        html = "  <div class=\"ngstk_wm_windowtr\">&nbsp;</div>\n  <div class=\"ngstk_wm_windowt\"";
        if(dragg) html += " onmousedown=\"ngstk_dragStart('ventana',event)\"";
        html += ">" + titulo + "</div>\n  <div id=\""+ id +"_cnt\" class=\"ngstk_wm_windowin\">";
        html += "</div>\n\n";
        break;
      }
    attr["id"] = id;
    attr["class"] = estilo;
    if( css ) attr["style"] = css;
    var y = ngstk_createObject("div", attr, html);
    document.getElementsByTagName("body")[0].appendChild(y);
    if( float ) ngstk_wmFloatBottomAdd(id);
    if( url ) ngstk_loadInWindow(id, url, xmlrpc);
    return y;
    }
  return false;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_loadInWindow(id, url, xmlrpc)</div>
 *  <div class="ngstk_descripcion">Dada una ventana (id) carga una URL en ella.<ul>
 *    <li><b>id:</b> ID de la nueva ventana (div)</li>
 *    <li><b>url:</b> URL a cargar.</li>
 *    <li><b>xmlrpc:</b> <i>(opcional)</i> Usar XML-RPC para cargar los contenidos (si se puede)</li>
 *  </ul></div>
 ** */
function ngstk_loadInWindow(id, url, xmlrpc) {
  var obj = ngstk_getElementById(id+"_cnt");
  if( id && ngstk_getElementById(id) && obj ) {
    var cond = ngstk_wmCheckUrl(url);
    // Comprobamos si se puede cargar por xml-rpc
    if( xmlrpc && ( cond < 1 || cond > 3 ) ) xmlrpc = false;
    if(!xmlrpc) obj.innerHTML += "<iframe id=\"" + id + "_if\" src=\"" + url + "\" style=\"width:100%; height:100px; border:0;\"></iframe>\n";
     else ngstk_xmlvar.recibir(url, ngstk_loadInWindowAux, false, id);
    return y;
    }
  return false;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_loadInWindowAux(xmlreq, id)</div>
 *  <div class="ngstk_descripcion">Dada una ventana (id) carga una URL en ella.<ul>
 *    <li><b>url:</b> Objeto XML con la informacion cargada.</li>
 *    <li><b>id:</b> ID de la nueva ventana (div)</li>
 *  </ul></div>
 ** */
function ngstk_loadInWindowAux(xmlreq, id) {
  if( id && xmlreq ) {
    var cnt="";
    if( xmlreq.responseXML ) cnt = xmlreq.responseXML.documentElement.getElementsByTagName('body')[0].innerHTML;
     else cnt = xmlreq.responseText;
    ngstk_getElementById(id+"_cnt").innerHTML = cnt;
    }
  return false;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_wmFloatBottomList</div>
 *  <div class="ngstk_descripcion">Variable tipo Array con los y su posici&oacute;n elementos que 'flotan'.</div>
 ** */
var ngstk_wmFloatBottomList = new Array();


/* **
 *  <div class="ngstk_funcion">ngstk_wmFloatBottomAdd(id)</div>
 *  <div class="ngstk_descripcion">A&ntilde;ade un elemento a la lista de elementos que 'flotan'.<ul>
 *    <li><b>id:</b> ID de la nueva ventana (div)</li>
 *  </ul></div>
 ** */
function ngstk_wmFloatBottomAdd(id) {
  var obj = ngstk_getElementById(id);
  if( obj ) {
    ngstk_wmFloatBottomList[id] = true;
    ngstk_wmFloatBottomEvent();
    }
  }


/* **
 *  <div class="ngstk_funcion">ngstk_wmFloatBottomRemove(id)</div>
 *  <div class="ngstk_descripcion">A&ntilde;ade un elemento a la lista de elementos que 'flotan'.<ul>
 *    <li><b>id:</b> ID de la nueva ventana (div)</li>
 *  </ul></div>
 ** */
function ngstk_wmFloatBottomRemove(id) {
  ngstk_wmFloatBottomList[id] = false;
  }


/* **
 *  <div class="ngstk_funcion">ngstk_wmFloatBottomEvent()</div>
 *  <div class="ngstk_descripcion">Recoloca los objetos que flotan.</div>
 ** */
function ngstk_wmFloatBottomEvent() {
  var sz = ngstk_windowInnerSize();
  for( var i in ngstk_wmFloatBottomList ) {
    var obj = ngstk_getElementById(i);
    if( ngstk_wmFloatBottomList[i] && obj ) {
      var bt = (-sz[5]) + "px";
      obj.style.bottom = bt;
      }
    }
  }



// Cargamos los eventos
// Revisar por algo mas optimo.
ngstk_addEvent(document, "scroll", ngstk_wmFloatBottomEvent);



// Precargamos la imagen de ventana nueva
tmp = new Array(config["IMAGE_URL"]+"newwin.gif");
ngstk_preloadimg(tmp);

// Iniciamos el WM:
var ngstk_wm_test = self;
// ngstk_addEvent(window,"load",top.ngstk_wmInit);



























/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Funciones de dibujo.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion">ngstk_sketches</div>
 *  <div class="ngstk_descripcion">Variable con los datos de todos los dibujos.</div>
 ** */
var ngstk_sketches = new Array();

/* **
 *  <div class="ngstk_funcion">ngstk_sketchClick</div>
 *  <div class="ngstk_descripcion">Variable con la id del sketch donde estamos dibujando.</div>
 ** */
var ngstk_sketchClick = false;



/* **
 *  <div class="ngstk_funcion">ngstk_createSketch(id, ancho, alto, css)</div>
 *  <div class="ngstk_descripcion">Crea un dibujo.<ul>
 *    <li><b>id:</b> Id del dibujo.</li>
 *    <li><b>ancho:</b> Anchura en p&iacute;xeles del dibujo.</li>
 *    <li><b>alto:</b> Altura en p&iacute;xeles del dibujo.</li>
 *    <li><b>css:</b> css de la capa, para posicionarla.</li>
 *  </ul></div>
 ** */
function ngstk_createSketch(id, ancho, alto, css) {
  // Creamos el div contenedor...
  var attr = new Array();
  attr["id"] = id;
  attr["style"] = "width:" + ancho + "px; height:" + alto + "px;";
  if( css ) attr["style"] += css;
  var html = "<table style=\"border:0;\">";
  var x;
  for(var y = 0; y< alto; y++) {
    html += "<tr style=\"height:1px;width:" + ancho + "px;border-spacing:0;border-collapse:collapse;padding:0;\">";
    for(x = 0; x < ancho; x++) {
      html += "<td style=\"height:1px;width:1px;padding:0;\" onmouseover=\"ngstk_SketchOverDot('"+id+"', "+x+", "+y+");\" onmousedown=\"ngstk_sketchClick = '" + id + "'; ngstk_SketchOverDot('"+id+"', "+x+", "+y+"); return false;\" onselectstart=\"return false;\"><img src=\""+config["IMAGE_URL"]+"pixel.gif\" style=\"border:0; width:1px; height:1px;\" alt=\" \" /></td>";
      }
    html += "</tr>";
    }
  html += "</table>";
  y = ngstk_createObject("div", attr, html);
  ngstk_sketches[id] = new Array();
  ngstk_sketches[id]["alto"] = alto;
  ngstk_sketches[id]["ancho"] = ancho;
  ngstk_sketches[id]["pixeles"] = new Array( alto * ancho);
  ngstk_sketches[id]["color"] = "#000";
  return y;
  }

/* **
 *  <div class="ngstk_funcion">ngstk_createSketchAdd(id, ancho, alto, css)</div>
 *  <div class="ngstk_descripcion">Crea un dibujo y lo a&ntilde;ade al body.<ul>
 *    <li><b>id:</b> Id del dibujo.</li>
 *    <li><b>ancho:</b> Anchura en p&iacute;xeles del dibujo.</li>
 *    <li><b>alto:</b> Altura en p&iacute;xeles del dibujo.</li>
 *    <li><b>css:</b> css de la capa, para posicionarla.</li>
 *  </ul></div>
 ** */
function ngstk_createSketchAdd(id, ancho, alto, css) {
  var y=ngstk_createSketch(id, ancho, alto, css);
  document.getElementsByTagName("body")[0].appendChild(y);
  return y;
  }

/* **
 *  <div class="ngstk_funcion">ngstk_SketchOverDot(id, x, y)</div>
 *  <div class="ngstk_descripcion">Crea un dibujo.<ul>
 *    <li><b>id:</b> Id del dibujo.</li>
 *    <li><b>x:</b> Posici&oacute;n X del dibujo.</li>
 *    <li><b>y:</b> Posici&oacute;n Y del dibujo.</li>
 *  </ul></div>
 ** */
function ngstk_SketchOverDot(id, x, y) {
  if( ngstk_sketchClick && id == ngstk_sketchClick ) {
    var pos=x + ngstk_sketches[id]["ancho"] * y;
    ngstk_sketches[id]["pixeles"][pos] = ngstk_sketches[id]["color"];
    ngstk_getElementById(id).getElementsByTagName("td")[pos].style.background = ngstk_sketches[id]["color"];
    }
  }



/* **
 *  <div class="ngstk_funcion">ngstk_sketchUp()</div>
 *  <div class="ngstk_descripcion">Se deja de pintar.</div>
 ** */
function ngstk_sketchUp() {
  ngstk_sketchClick = false;
  }

// Lo anyadimos para controlar el fin del dibujado:
ngstk_addEvent(document,"mouseup",ngstk_sketchUp);
























/* **
 * <div class="ngstk_anuncio"><b>Autor:</b> Daniel Mart&iacute;n Fern&aacute;ndez<br />
 * <b>Web:</b> <a href="http://www.naguissa.com">http://www.naguissa.com</a><br />
 * <b>Nombre:</b> Naguissa Toolkit (ngstk)<br />
 * <b>Descripci&oacute;n:</b> Toolkit JavaScript y PHP para creaci&oacute;n, manipulaci&oacute;n y transformaci&oacute;n de documentos web.<br />
 * <b>Secci&oacute;n:</b> Rich Text Editor, editor RTF para webs.<br />
 * <b>Licencia: GPL</b></div>
 ** */


/* **
 *  <div class="ngstk_funcion"></div>
 *  <div class="ngstk_descripcion"></div>
 ** */

function ngstk_rte(id, objectId) {
  if (!id || !objectId) alert("Naguissa Toolkit Error:\n\nEl constructor del editor RTE requiere dos par&aacute;metros: id, objectId");
  var self = this;
  this.id = id;
  this.objectId = objectId;
  this.frame;
  this.viewSource = false;
  this.editorHtml = "";
  this.frameHtml = "";
  this.textareaValue = "";

  // Configuracion. Puede predefinirse o hacerse externamente antes del init().
  this.height= "450px";    // Altura del editor. Obligatoria.
  this.cssFile = config["BASE_URL"]+"/css/estilo.css"; // URL del CSS del editor (iframe) (opcional)
  this.buttonPath = config["IMAGE_URL"];    // URL de la carpeta con los botones (con la '/' al final)

  // URL del navegador de imagenes (vacio para no usar):
  this.imageBrowse = config["BROWSER_URL"] + ( (config["BROWSER_URL"].indexOf( "?" ) == -1) ? "?" : "&" ) + "fn=" + this.objectId + ".addImage";


  // URL del navegador de flashes (vacio para no usar):
  this.flashBrowse = config["BROWSER_URL"] + ( (config["BROWSER_URL"].indexOf( "?" ) == -1) ? "?" : "&" ) + "fn=" + this.objectId + ".addFlash";

  // URL del navegador de archivos (vacio para no usar):
  this.linkBrowse = config["BROWSER_URL"] + ( (config["BROWSER_URL"].indexOf( "?" ) == -1) ? "?" : "&" ) + "fn=" + this.objectId + ".addLink";

  this.charset = "utf-8";  // Charset del editor
  this.headMax = 1;        // Cabecera maxima que se puede usar (para que no usen h1, h2, etc).


  this.browser = {
    "ie": Boolean(document.body.currentStyle),
    "gecko" : (navigator.userAgent.toLowerCase().indexOf("gecko") != -1)
    };



  this.addImage = function(url) {
    ngstk_getElementById(this.id + '-i-url').value=url;
    }

  this.addFlash = function(url) {
    ngstk_getElementById(this.id + '-f-url').value=url;
    }

  this.addLink = function(url) {
    ngstk_getElementById(this.id + '-l-url').value=url;
    }

  this.submit = function() {
    if (self.isOn()) {
      if (self.viewSource) self.toggleSource();
      var code = ngstk_get_xhtml(self.frame.document.body);
      code = unlockUrls(code);
      if( config["SYNTAX"] ) {
        var extra = "";
        if( code.indexOf('class="cpp"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushCpp.js"></sc'+'ript>';
        if( code.indexOf('class="csharp"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushCSharp.js"></sc'+'ript>';
        if( code.indexOf('class="css"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushCss.js"></sc'+'ript>';
        if( code.indexOf('class="delphi"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushDelphi.js"></sc'+'ript>';
        if( code.indexOf('class="xml"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushXml.js"></sc'+'ript>';
        if( code.indexOf('class="java"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushJava.js"></sc'+'ript>';
        if( code.indexOf('class="javascript"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushJScript.js"></sc'+'ript>';
        if( code.indexOf('class="php"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushPhp.js"></sc'+'ript>';
        if( code.indexOf('class="python"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushPython.js"></sc'+'ript>';
        if( code.indexOf('class="ruby"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushRuby.js"></sc'+'ript>';
        if( code.indexOf('class="sql"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushSql.js"></sc'+'ript>';
        if( code.indexOf('class="vb"') != -1 ) extra += '<scri'+'pt type="text/javascript" src="'+config["SYNTAX_URL"]+'shBrushVb.js"></sc'+'ript>';
        if( extra != "" ) {
          code += extra;
          code += "<link href=\"" + config["SYNTAX_URL"] + "SyntaxHighlighter.css\" rel=\"stylesheet\" type=\"text/css\" /><scri" + "pt type=\"text/j" + "avascript\" src=\"" + config["SYNTAX_URL"] + "shCore.js\"></sc" + "ript>";
          code += "<sc"+"ript type=\"text/javascript\">\n<!--\ndp.SyntaxHighlighter.ClipboardSwf = '"+config["SYNTAX_URL"]+"clipboard.swf'; dp.SyntaxHighlighter.HighlightAll('code'); /"+"/ -->\n</sc"+"ript>";
          }
        }

      var URLservidor = location.href;

      // Sacamos la posicion de la ultima '/'
      var nw = -1;
      var pos;
      do {
        pos = nw;
        nw = URLservidor.indexOf("/", nw+1);
        } while( nw != -1);

      if( pos > 7 ) URLservidor = URLservidor.substring(0,pos+1);

      // Preparamos las cadenas como patrones de busqueda (escapamos):
      URLservidor = URLservidor.replace(/\//g,"\\/");
      URLbase = config["BASE_URL"].replace(/\//g,"\\/");

      // Cambiamos las urls absolutas a nuestra carpeta...
      code = eval("code.replace(/(href|data|value|src)=[\"']" + URLservidor + "([^\"']*)[\"']/gi,  '$1=\"$2\"')");

      // Cambiamos las urls absolutas a nuestro servidor...
      code = eval("code.replace(/(href|data|value|src)=[\"']" + URLbase + "([^\"']*)[\"']/gi,  '$1=\"$2\"')");
      code = code.replace(/(href|data|value|src)=["'](^(javascript ?:|#|http:\/\/)][^"']*)["']/g,  '$1="/$2"');
      code = code.replace(/<strong ?\/>/gi,"");
      ngstk_getElementById(self.id).value = code;


      }
    };


  this.init = function() {
    if (document.getElementById && document.createElement && document.designMode && (this.browser.ie || this.browser.gecko)) {
      // EDITOR
      if (!ngstk_getElementById(this.id)) {
        alert("Naguissa Toolkit Error\n-----------------------\n\nError en el editor RTE. El objeto "+this.objectId+" no existe.");
        return;
        }
      this.textareaValue = ngstk_getElementById(this.id).value;
      var ste = document.createElement("div");
      ngstk_getElementById(this.id).parentNode.replaceChild(ste, ngstk_getElementById(this.id));
      ste.id = this.id+"-ste";
      ste.innerHTML = this.editorHtml ? this.editorHtml : this.getEditorHtml();
      if (this.browser.ie) this.frame = frames[this.id+"-frame"];
       else if (this.browser.gecko) this.frame = ngstk_getElementById(this.id+"-frame").contentWindow;
      this.frame.document.designMode = "on";
      this.frame.document.open();
      this.frame.document.write(this.frameHtml ? this.frameHtml : this.getFrameHtml());
      this.frame.document.close();
      insertHtmlFromTextarea();
      for( var obj = ngstk_getElementById(this.id); obj && obj.nodeName.toLowerCase() != "html"; obj=obj.parentNode)
       if( obj.nodeName.toLowerCase() == "form" ) {
        ngstk_addEvent(obj,"submit",this.submit );
        break;
        }
      }
    };

  function lockUrls(s) {
    if (self.browser.gecko) { return s; }
    return s.replace(/(href|data|value|src)=["']([^"']*)["']/gi,  '$1="simpletexteditor://simpletexteditor/$2"');
    }

  function unlockUrls(s) {
    if (self.browser.gecko) { return s; }
    return s.replace(/(href|data|value|src)=["']simpletexteditor:\/\/simpletexteditor\/([^"']*)["']/gi,  '$1="$2"');
    }

  function insertHtmlFromTextarea() {
    try { self.frame.document.body.innerHTML = lockUrls(self.textareaValue); } catch (e) { setTimeout(insertHtmlFromTextarea, 10); }
    }

  this.codeBlock = function(obj, tipo) {
    self.insHTML('<pre name="code" class="'+tipo+'">', '</pre>');
    }

  this.getEditorHtml = function() {
    var html = "";
    html += '<input type="hidden" id="'+this.id+'" name="'+this.id+'" value="" />';

    // BOTONES
    html += '<div style="float:right; padding:5px;z-index:1;"><input id="'+this.id+'-viewSource" type="checkbox" onclick="'+this.objectId+'.toggleSource()" /><span onclick="'+this.objectId+'.toggleSource()">Fuente</span></div>';
    html += '<div id="'+this.id+'-botones" unselectable="on" onselectstart="return(false)" style="background-color:#d4d0c8;padding:0;border:1px solid #333;user-select:none;-moz-user-select:none;-khtml-user-select:none;">';
    html += '<select style="vertical-align:middle;margin:1px;" onchange="'+this.objectId+'.execCommand(\'formatblock\', this.value);this.selectedIndex=0;">';
    html += '<option value=""></option>';
    for( var i=this.headMax; i<=7; i++) html += '<option value="<h'+i+'>">Cabecera '+i+'</option>';
    html += '<option value="<p>">P&aacute;rrafo</option><option value="<pre>">Preformateado</option></select>';
    html += '&nbsp;';

    if( config["SYNTAX"] ) {
      html += '<select style="vertical-align:middle;margin:1px;" onchange="'+this.objectId+'.codeBlock('+this.objectId+',this.value);this.selectedIndex=0;">';
      html += ' <option value=""></option>';
      html += ' <option value="cpp">C++</option>';
      html += ' <option value="csharp">C#</option>';
      html += ' <option value="css">CSS</option>';
      html += ' <option value="delphi">Delphi</option>';
      html += ' <option value="xml">HTML/XML/XHTML</option>';
      html += ' <option value="java">Java</option>';
      html += ' <option value="javascript">JavaScript</option>';
      html += ' <option value="php">PHP</option>';
      html += ' <option value="python">Python</option>';
      html += ' <option value="ruby">Ruby</option>';
      html += ' <option value="sql">SQL</option>';
      html += ' <option value="vb">VB</option>';
      html += '</select>';
      html += '&nbsp;';
      }

    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Negrita" type="button" onclick="'+this.objectId+'.execCommand(\'bold\')"><img src="'+this.buttonPath+'bold.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Negrita" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Cursiva" type="button" onclick="'+this.objectId+'.execCommand(\'italic\')"><img src="'+this.buttonPath+'italic.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Cursiva" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Subrayado" type="button" onclick="'+this.objectId+'.execCommand(\'underline\')"><img src="'+this.buttonPath+'underline.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Subrayado" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Tachado" type="button" onclick="'+this.objectId+'.execCommand(\'StrikeThrough\')"><img src="'+this.buttonPath+'strikethrough.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Tachado" /></button>';
    html += '&nbsp;';

    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Izquierda" type="button" onclick="'+this.objectId+'.execCommand(\'justifyleft\')"><img src="'+this.buttonPath+'left.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Izquierda" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Centrar" type="button" onclick="'+this.objectId+'.execCommand(\'justifycenter\')"><img src="'+this.buttonPath+'center.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Centrar" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Derecha" type="button" onclick="'+this.objectId+'.execCommand(\'justifyright\')"><img src="'+this.buttonPath+'right.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Derecha" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Justificar" type="button" onclick="'+this.objectId+'.execCommand(\'justifyfull\')"><img src="'+this.buttonPath+'justify.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Justificar" /></button>';
    html += '&nbsp;';

    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Superscript" type="button" onclick="'+this.objectId+'.execCommand(\'Superscript\')"><img src="'+this.buttonPath+'superscript.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Superscript" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Subscript" type="button" onclick="'+this.objectId+'.execCommand(\'Subscript\')"><img src="'+this.buttonPath+'subscript.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Subscript" /></button>';
    html += '&nbsp;';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Lista numerada" type="button" onclick="'+this.objectId+'.execCommand(\'insertorderedlist\')"><img src="'+this.buttonPath+'number.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Lista numerada" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Lista no numerada" type="button" onclick="'+this.objectId+'.execCommand(\'insertunorderedlist\')"><img src="'+this.buttonPath+'bullet.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Lista no numerada" /></button>';
    html += '&nbsp;';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Sangrar" type="button" onclick="'+this.objectId+'.execCommand(\'indent\')"><img src="'+this.buttonPath+'indent.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Sangrar" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Quitar sangrado" type="button" onclick="'+this.objectId+'.execCommand(\'outdent\')"><img src="'+this.buttonPath+'outdent.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Quitar sangrado" /></button>';
    html += '&nbsp;';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Insertar enlace" type="button" onclick="'+this.objectId+'.hideDialogs(); document.getElementById(\''+this.id+'-link\').style.display=\'block\'"><img src="'+this.buttonPath+'link.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Insertar enlace" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Insertar im&aacute;gen" type="button" onclick="'+this.objectId+'.hideDialogs(); document.getElementById(\''+this.id+'-imagen\').style.display=\'block\'"><img src="'+this.buttonPath+'image.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Insertar im&aacute;gen" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Insertar v&iacute;deo" type="button" onclick="'+this.objectId+'.hideDialogs(); document.getElementById(\''+this.id+'-video\').style.display=\'block\'"><img src="'+this.buttonPath+'video.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Insertar v&iacute;deo" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Insertar flash" type="button" onclick="'+this.objectId+'.hideDialogs(); document.getElementById(\''+this.id+'-flash\').style.display=\'block\'"><img src="'+this.buttonPath+'flash.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Insertar flash" /></button>';
    html += '<button style="vertical-align:middle;padding:0;margin:1px;" title="Insertar tabla" type="button" onclick="'+this.objectId+'.hideDialogs(); document.getElementById(\''+this.id+'-tabla\').style.display=\'block\'"><img src="'+this.buttonPath+'table.gif" style="vertical-align:middle;margin:-1px;" onerror="this.parentNode.innerHTML=this.alt" alt="Insertar tabla" /></button>';
    html += '</div>';

    // CONTROLES: ENLACE
    html += '<div id="'+this.id+'-link" style="background-color:#d4d0c8;padding:0;border:1px solid #333;display:none;" onkeypress="if(event.keyCode==13) return false;" onselectstart="return(false)">';
    html += 'URL a enlazar: <input type="text" id="'+this.id+'-l-url" size="50" /> ';
    if (this.linkBrowse) html += '<input style="vertical-align:middle;padding:0;margin:1px;"type="button" onclick="'+this.objectId+'.openWindow(\''+this.linkBrowse+'&ID='+this.id+'-i-url\',750,500)" value="En servidor" /> ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" value="http://" onclick="document.getElementById(\''+this.id+'-l-url\').value=\'http://\'+document.getElementById(\''+this.id+'-l-url\').value"> ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" value="mailto:" onclick="document.getElementById(\''+this.id+'-l-url\').value=\'mailto:\'+document.getElementById(\''+this.id+'-l-url\').value"> ';
    html += '<input type="checkbox" id="'+this.id+'-l-new" /> Abrir en ventana nueva. ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.insertLink();" value="Insertar enlace" /><input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.hideDialogs();" value="Cancelar" />';
    html += '</div>';

    // CONTROLES: IMAGEN
    html += '<div id="'+this.id+'-imagen" style="background-color:#d4d0c8;padding:0;border:1px solid #333;display:none;" onkeypress="if(event.keyCode==13) return false;" onselectstart="return(false)">';
    html += 'URL de la im&aacute;gen: <input type="text" id="'+this.id+'-i-url" size="50" /> ';
    if (this.imageBrowse) html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.openWindow(\''+this.imageBrowse+'&ID='+this.id+'-i-url\',750,500)" value="En servidor" /> ';
    html += '<label title="Texto a mostrar si la im&aacute;gen no est&aacute; disponible"><br>Texto alternativo: <input id="'+this.id+'-i-alt" type="text" size="50" /></label><br>';
    html += 'Alineaci&oacute;n: <select style="vertical-align:middle;margin:1px;" id="'+this.id+'-i-side"><option value="none">_&hearts;_  Con el texto</option><option value="left">&hearts;== A la izaquierda</option><option value="right">==&hearts; A la derecha</option></select> ';
    html += 'Borde: <input type="text" id="'+this.id+'-i-border" size="20" value="none" title="N&uacute;mero o css (ej: 3px maroon outset)" /> ';
    html += 'M&aacute;rgen: <input type="text" id="'+this.id+'-i-margin" size="20" value="0" title="N&uacute;mero o CSS (ej: 5px 1em)" /> ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.insertImage();" value="Insertar im&aacute;gen" /><input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.hideDialogs();" value="Cancelar" />';
    html += '</div>';

    // CONTROLES: FLASH
    html += '<div id="'+this.id+'-flash" style="background-color:#d4d0c8;padding:0;border:1px solid #333;display:none;" onkeypress="if(event.keyCode==13) return false;" onselectstart="return(false)">';
    html += 'URL del flash: <input type="text" id="'+this.id+'-f-url" size="50" /> ';
    if (this.flashBrowse) html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.openWindow(\''+this.flashBrowse+'&ID='+this.id+'-f-url\',750,500)" value="En servidor" /> ';
    html += 'Ancho: <input type="text" id="'+this.id+'-f-width" size="5" /> ';
    html += 'Alto: <input type="text" id="'+this.id+'-f-height" size="5" /> ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.insertFlash();" value="Insertar flash" /><input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.hideDialogs();" value="Cancelar" />';
    html += '</div>';

    // CONTROLES: VIDEO
    html += '<div id="'+this.id+'-video" style="background-color:#d4d0c8;padding:0;border:1px solid #333;display:none;" onkeypress="if(event.keyCode==13) return false;" onselectstart="return(false)">';
    html += 'Pega el c&oacute;digo de youtube, etc...: <input type="text" id="'+this.id+'-v-cod" size="60" /> ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.insertVideo();" value="Insertar video" /><input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.hideDialogs();" value="Cancelar" />';
    html += '</div>';

    // CONTROLES: TABLE
    html += '<div id="'+this.id+'-tabla" style="background-color:#d4d0c8;padding:0;border:1px solid #333;display:none;" onkeypress="if(event.keyCode==13) return false;" onselectstart="return(false)">';
    html += 'Filas: <input type="text" id="'+this.id+'-t-rows" size="3" value="2"/> ';
    html += '<input type="checkbox" id="'+this.id+'-t-head" />1a es cabecera. ';
    html += 'Columnas: <input type="text" id="'+this.id+'-t-cols" size="3" value="3"/> ';
    html += '<label title="Ancho en p&iacute;xeles o CSS">Borde : <input type="text" id="'+this.id+'-t-border" size="10" value="1px solid #000;"/> ';
    html += '<input type="checkbox" id="'+this.id+'-t-collapse" checked="checked" />Unir bordes. ';
    html += '<input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.insertTable();" value="Insertar tabla" /><input style="vertical-align:middle;padding:0;margin:1px;" type="button" onclick="'+this.objectId+'.hideDialogs();" value="Cancelar" />';
    html += '</div>';


    // EDITOR
    html += '<div style="border:1px solid #000; padding:0.5em;"><iframe id="'+this.id+'-frame" frameborder="0" style="width:100%; height:'+this.height+';"></iframe></div>';

    // Variable que indica que el editor esta activo.
    html += '<input type="hidden" name="'+this.objectId+'_RTEOK" value="1" />';

    return html;
    };


  this.getFrameHtml = function() {
    var html = "";
    html += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
    html += '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es"><head>';
    html += '<meta http-equiv="Content-Type" content="text/html; charset='+this.charset+'">';
    html += '<title>ngstk Rich Text Editor frame</title>';
    html += '<style type="text/css">html,body { cursor: text; }</style>';
    if (this.cssFile) { html += '<link rel="stylesheet" type="text/css" href="'+this.cssFile+'">'; }
    html += '</head><body></body></html>';
    return html;
    };

  this.hideDialogs = function() {
    document.getElementById(this.id+"-imagen").style.display="none";
    document.getElementById(this.id+"-video").style.display="none";
    document.getElementById(this.id+"-flash").style.display="none";
    document.getElementById(this.id+"-link").style.display="none";
    document.getElementById(this.id+"-tabla").style.display="none";
    };

  this.openWindow = function(url, width, height) {
    var x = (screen.width/2-width/2);
    var y = (screen.height/2-height/2);
    window.open(url, "", "scrollbars=yes,width="+width+",height="+height+",screenX="+(x)+",screenY="+y+",left="+x+",top="+y);
    };

  this.toggleSource = function() {
    var html, text;
    if (this.browser.ie) {
      if (!this.viewSource) {
        html = this.frame.document.body.innerHTML;
        this.frame.document.body.innerText = unlockUrls(html);
        ngstk_display(this.id+"-botones","none")
        this.viewSource = true;
        }
       else {
        text = this.frame.document.body.innerText;
        this.frame.document.body.innerHTML = lockUrls(text);
        ngstk_display(this.id+"-botones","block")
        this.viewSource = false;
        }
      }
     else if (this.browser.gecko) {
      if (!this.viewSource) {
        html = document.createTextNode(this.frame.document.body.innerHTML);
        this.frame.document.body.innerHTML = "";
        this.frame.document.body.appendChild(html);
        ngstk_display(this.id+"-botones","none")
        this.viewSource = true;
        }
       else {
        html = this.frame.document.body.ownerDocument.createRange();
        html.selectNodeContents(this.frame.document.body);
        this.frame.document.body.innerHTML = html.toString();
        ngstk_display(this.id+"-botones","block")
        this.viewSource = false;
        }
      }
    this.hideDialogs();
    ngstk_getElementById(this.id+"-viewSource").checked = this.viewSource ? "checked" : "";
    ngstk_getElementById(this.id+"-viewSource").blur();
    };

  this.execCommand = function(cmd, value) {
    if (cmd == "createlink" && !value) {
      var url = prompt("Enter URL:", "");
      if (url) {
        this.frame.focus();
        this.frame.document.execCommand("unlink", false, null);
        if (this.browser.ie) this.frame.document.execCommand(cmd, false, "simpletexteditor://simpletexteditor/"+url);
         else if (this.browser.gecko) this.frame.document.execCommand(cmd, false, url);
        this.frame.focus();
        }
      }
     else if (cmd == "insertimage" && !value) {
      this.insHTML
      var imageUrl = prompt("Enter Image URL:", "");
      if (imageUrl) {
        this.frame.focus();
        this.frame.document.execCommand(cmd, false, imageUrl);
        this.frame.focus();
        }
      }
     else {
      this.frame.focus();
      this.frame.document.execCommand(cmd, false, value);
      this.frame.focus();
      }
    };


  this.insertLink = function() {
    this.hideDialogs();
    var URL = document.getElementById(this.id+"-l-url").value;
    var tgt = document.getElementById(this.id+"-l-new").checked ? ' target="_blank"' : "";
    if (URL) this.insHTML('<a href="'+URL+'"'+tgt+'>');
     else this.frame.document.execCommand('unlink', false);
    };

  this.insertImage = function() {
    this.hideDialogs();
    var URL = document.getElementById(this.id+"-i-url").value;
    if (URL) {
      var alt = document.getElementById(this.id+"-i-alt").value ? document.getElementById(this.id+"-i-alt").value: URL.replace(/.*\/(.+)\..*/,"$1");
      var side = document.getElementById(this.id+"-i-side").value;
      var border = document.getElementById(this.id+"-i-border").value;
      if(border.match(/^\d+$/)) border+='px solid';
      var margin = document.getElementById(this.id+"-i-margin").value;
      if(margin.match(/^\d+$/)) margin+='px solid';

      var img = '<img alt="' + alt + '" src="' + URL +'"';
      if ((side == "left") || (side == "right") || border || margin ) {
        img += ' style="';
        if (side) img += 'float:' + side + ';';
        if (border) img += 'border:' + border + ';';
        if (margin) img += 'margin:' + margin + ';';
        img += '"';
        }
      img += ' />';
      this.insHTML(img);
      }
    };

  this.insertFlash = function() { // insert flash as specified
    this.hideDialogs();
      var dir = document.getElementById(this.id+"-i-url").value;
      var wd = document.getElementById(this.id+"-i-width").value;
      var hd = document.getElementById(this.id+"-i-height").value;
      if (dir && wd && hd) {
      if(config["SATAY_URL"]) dir = config["SATAY_URL"] + "?path=" + dir;
      cod = '<object type="application/x-shockwave-flash" data="' + dir + '" width="'+wd+'" height="'+hd+'"><param name="movie" value="' + dir + '" /><param name="quality" value="high" /><div style="border: 1px dashed rgb(0, 0, 0); width: '+wd+'px; height: '+wd+'px; text-align: center;">Objeto Flash</div></object>';
      this.insHTML(lockUrls(cod));
      }
    }

  this.insertVideo = function() { // insert video as specified
    this.hideDialogs();
    var cod = document.getElementById(this.id+"-v-cod").value;
    if (cod) {
      var pos = cod.indexOf("<object");
      var hd=false;
      var wd=false;
      var dir=false;
      var codb;
      if( pos > 0 ) cod=cod.substr(pos);
      pos = cod.indexOf("</object");
      if( pos > 0 ) cod=cod.substr(0,pos);
      pos = cod.indexOf("width");
      if( pos != -1 ) {
        codb=cod.substr(pos);
        codb=codb.substr(codb.indexOf('"')+1);
        wd=codb.substr(0,codb.indexOf('"'));
        }
      pos = cod.indexOf("width:");
      if( pos != -1 ) {
        codb=cod.substr(pos+6);
        wd=codb.substr(0,codb.indexOf('px'));
        }
      pos = cod.indexOf("height");
      if( pos != -1 ) {
      codb=cod.substr(pos);
      codb=codb.substr(codb.indexOf('"')+1);
      hd=codb.substr(0,codb.indexOf('"'));
      }
    pos = cod.indexOf("height:");
    if( pos != -1 ) {
      codb=cod.substr(pos+7);
      hd=codb.substr(0,codb.indexOf('px'));
      }
    pos = cod.indexOf("src");
    if( pos != -1 ) {
      codb=cod.substr(pos);
      codb=codb.substr(codb.indexOf('"')+1);
      dir=codb.substr(0,codb.indexOf('"'));
      }
    if( wd && hd && dir ) {
      if(config["SATAY_URL"]) dir = config["SATAY_URL"] + "?path=" + dir;
      cod = '<object type="application/x-shockwave-flash" data="' + dir + '" width="'+wd+'" height="'+hd+'"><param name="movie" value="' + dir + '" /><param name="quality" value="high" /><div style="border: 1px dashed rgb(0, 0, 0); width: '+wd+'px; height: '+wd+'px; text-align: center;">Objeto Flash</div></object>';
      this.insHTML(lockUrls(cod));
      }
    }
  };


  this.insertTable = function() {
    this.hideDialogs();
    var rows = document.getElementById(this.id+"-t-rows").value;
    var cols = document.getElementById(this.id+"-t-cols").value;
    var border = document.getElementById(this.id+"-t-border").value;
    if(border.match(/^\d+$/)) border+='px solid';
    var collapse = document.getElementById(this.id+"-t-collapse").checked;
    var head = document.getElementById(this.id+"-t-head").checked;
    var estilo="";
    if ( border || collapse ) {
      var estilo = ' style="';
      if (border) estilo += 'border:' + border + ';';
      if (collapse) estilo += 'border-collapse:collapse;';
      estilo += '"';
      }

    if ((rows > 0) && (cols > 0)) {
      var table = '<table' + estilo + '>';
      for (var i=1; i <= rows; i++) {
        table = table + '<tr' + estilo + '>';
        for (var j=1; j <= cols; j++)
         if (i==1 && head) table += '<th' + estilo + '>T&iacute;tulo' + j + '</th>';
          else table += '<td' + estilo + '>(' + i + ', ' + j + ')</td>';
        table += '</tr>';
        }
      table += '</table>';
      this.insHTML(table);
      }
    };


  this.isOn = function() {
    return Boolean(this.frame);
    };

  this.getContent = function() {
    try { return unlockUrls(this.frame.document.body.innerHTML); } catch(e) { alert("Naguissa Toolkit Error:\n\nHa fallado el comando "+this.objectId+".getContent()"); }
    };

  this.insHTML = function(html,post) {
    if( !ngstk_isDef(post) ) post = "";
    if( this.isOn() ) {
      // Seleccion y rango:
      this.frame.focus();
      if (this.frame.getSelection) { //Moz
        var sel = this.frame.getSelection();
        if (sel) var rng = sel.getRangeAt(sel.rangeCount - 1).cloneRange();
        if( sel ) sel = (sel+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
        }
       else { //IE
        var sel = this.frame.document.selection;
        var rng = sel.createRange();
        }
      // Anyadimos
      if (html.indexOf('js:') == 0) {
        try{ eval(html.replace(/^js:/,'')); } catch(e){ };
        return;
        }
      try { this.frame.document.execCommand("inserthtml", false, html + sel + post); } catch (e) {
        if (this.frame.document.selection) {
          rng.select(); //else IE gets lost
          html = html + rng.htmlText + post;
          try { this.frame.document.selection.createRange().pasteHTML(html); } catch (e) { }
          }
        }
      }
    };
  }
