/********************************************************************************/
/*                                                                              */
/* Plataforma e-ducativa.  Version 7.02.03-28 - Argentina                       */
/*                                                                              */
/* Copyright (c) 1998-2008 de e-ducativa Educación Virtual S.A.                 */
/*                                                                              */
/********************************************************************************/
/*
 * www.e-ducativa.com
 */


// esta funcion ejecuta el codigo en el onload si la pagina aun no se cargo, si la pagina
// esta cargada, la ejecuta direactamente
(function(){
    window.$ready = function( fn ){
        Event.observe(window, 'load', fn);
    }

    Event.observe(window, 'load', function(){
        window.$ready = function(fn){
            fn();
        }
    });
})();


/**
* @class Element::Select
*
* @brief Se agregar metodos para el manejo de opciones
*
*/
Element.addMethods('select', {
    /** @method add_options( element  )
    *  Elimina todas las opciones de un select
    */
    clear : function(element){
            while (element.length> 0) {
                element.remove(0);
            }
        },
    /** @method add_options( element, list )
    *  Agrega opciones a un elemento select
    *  \param element SELECT
    *  \param list Array de objetos con las propiedades label y value
    */
    add_options : function(element, list){
        list.each(function(i){
            element.appendChild(new Element('option', {value : i.value}).update(i.label) );
        });
    },

    /* mueve los elementos seleccionados a otra lista */
    moveSelectedItemsTo : function(element,hasta) {
        element.select('option')
            .findAll(function(o){return ! o.disabled && o.selected})
            .invoke('remove')
            .each(function(e){ $(hasta).appendChild( e ) });
        element.sortItems();
    },
    /* ordena los elementos del select de forma ascendente */
    sortItems : function(element){
        element.select('option')
            .invoke('remove').sort(function(a,b){
                return a.innerHTML < b.innerHTML
                    ? -1 : a.innerHTML == b.innerHTML ? 0 : 1;
            })
            .each(function(e){ element.appendChild( e ) });
    },
    /* selecciona todos los elementos del select */
    selectAllItems : function(element) {
        if(! (element.multiple && element.multiple) ) return ;
        element.select('option').each(function(o){o.selected = true});
    }
});

/**
* @class Educativa
*
* @brief Framework e-ducativa
*/

var Educativa = new Object;

Educativa.Iterator = {
    isTrue  : function(e){ return   e },
    isFalse : function(e){ return ! e }
};


Educativa.Browser = new (function(){
    var t = this, d = document, w = window, na = navigator, ua = na.userAgent;

    // Browser checks
    t.isOpera = w.opera && opera.buildNumber;
    t.isWebKit = /WebKit/.test(ua);
    t.isOldWebKit = t.isWebKit && !w.getSelection().getRangeAt;
    t.isIE = !t.isWebKit && !t.isOpera && (/MSIE/gi).test(ua) && (/Explorer/gi).test(na.appName);
    t.isIE6 = t.isIE && /MSIE [56]/.test(ua) && ! /MSIE [78]/.test(ua);
    t.isGecko = !t.isWebKit && /Gecko/.test(ua);
    t.isMac = ua.indexOf('Mac') != -1;
    t.isAir = /adobeair/i.test(ua);
});


Educativa.Observable = Class.create({
    observe : function(event, action){
        if ( Object.isUndefined( this._listeners ) )
            this._listeners = {};
        (this._listeners[event] = this._listeners[event] || []).push( action );
        return this;
    },
    fire : function( event, memo)
    {
        if ( Object.isUndefined( this._listeners )
          || Object.isUndefined(this._listeners[event]) ) return;

        var listeners = this._listeners[event];

        for( var i=0; i < listeners.length; i++ )
            listeners[i]( this, memo );

        return this;
    }
});
/**
* @class Educativa::Control
*
*/
Educativa.Control = Class.create(Educativa.Observable, {
    initialize : function(id){
       this.element = this.element || $(id);

       // indexo los controles para la funcion E() del prototype
       if (this.element) Educativa.Control.Objects[ id || this.element.identify() ] = this;
    }
});

Educativa.Control.Objects = {};

Element.addMethods( {
    E : function(element) {
        return Educativa.Control.Objects[element.id]
    },
    control : function(element){
        return Educativa.Control.Objects[element.id]
    }
} );

/* @class Educativa.Control.OverlayedDialog
 *
 */
(function(){
Educativa.Control.OverlayedDialog = Class.create({
    options : {
        title : '',
        content: '',
        width : false,
        height: false,
        min : 0,
        max : 100
    },

    initialize : function(options)
    {
        Object.extend( this.options, options );

        var dg = this.element = new Element('div', { className : 'overlayed-dialog' });

        $('marco_principal').insert({before: dg});

        dg.hide();

        dg.update(
            '<div class="overlayed-dialog-title"></div>' +
            '<div class="overlayed-dialog-content"></div>'
        );

        this._title   = this.element.down();
        this._content = this.element.down().next();

        this.refresh();

    },
    refresh : function(){
        this.setContent(this.options.content);
        this.setTitle(this.options.title);
        this.element.setStyle({width:'', height : ''});

        this.setWidth(this.options.width ? this.options.width : this.element.getWidth() );
        this.setHeight(this.options.height ? this.options.height : this.element.getHeight() );
    },
    show : function()
    {
        this.lb = new lightbox( this.element.identify() );
        this.lb.activate()
        // $('contenedor').scrollTo();
    },
    hide : function()
    {
        this.lb.deactivate()
        this.element.hide();
    },
    setTitle : function(title)
    {
        this._title.update(this.options.title = title);
    },
    setContent: function(content)
    {
        this._content.update(this.options.content = content);
    },
    setWidth : function(w)
    {
        this.element.setStyle({width:w+'px',
            left:((document.viewport.getDimensions().width-w)/2)+'px'});
    },
    setHeight : function(h)
    {
        this.element.setStyle({height:h+'px',
            top:((document.viewport.getDimensions().height-h)/2)+'px'});
    }
});
})();


/**
* @class Educativa::Utils
*
*/
Educativa.Utils = {
  disable_input_file_keypress : function(){
    $$('input[type="file"]').invoke('observe','keydown',function(e){
        if ( e.keyCode != 9 ) Event.stop(e)
    });
  },
  quitar_html_tags : function(str){
    var letters = str.split('');
    var estado = ''; //posibles estados: ''|tag|string
    var quote = '';
    var new_str = '';
    for ( var j=0; j < letters.length; ++j){
        var c = letters[j];
        switch( estado ){
            case '':
                if( c == '<') estado = 'tag';
                else new_str += c;
                break;
            case 'tag':
                if( c.match(/[\'\"]/) ){ /* ' // para que no me rompa el ue */
                    estado = 'string';
                    quote = c;
                }
                if( c == '>' ) estado = '';
                break;
            case 'string':
                if( c == quote) estado = 'tag';
                break;
            default:
                alert("epa epa!");
                break;
        }

    }
    return new_str;
  },

  // Funcion especifica (optima) para validar tiny vacio
  check_empty_html_content: function (str){

    str = str.replace(/&nbsp;/g,'')

    var letters = str.split('');
    var estado = ''; //posibles estados: ''|tag|string
    var quote = '';

    // se permite que str sea solo un iframe, un flash, o una imagen
    var allowedTags = 'iframe|object|img|embed';
    var pattern = new RegExp ('<'+ allowedTags + '\.*' + '>');
    if( pattern.test(str) ) return false;

    for ( var j=0; j < letters.length; ++j){
        var c = letters[j];
        switch( estado ){
            case '':
                if( c == '<') estado = 'tag';
                else if( ! c.match(/\s/) ){
                    return false;
                };
                break;
            case 'tag':
                if( c.match(/['"]/) ){
                    estado = 'string';
                    quote = c;
                }
                if( c == '>' ) estado = '';
                break;
            case 'string':
                if( c == quote) estado = 'tag';
                break;
            default:
                alert("epa epa!");
                break;
        }
    }
    return true;
  },

  helpWin : null,
  closeWinHelp : function(){
    if (Educativa.Utils.helpWin != null && !Educativa.Utils.helpWin.closed)
        Educativa.Utils.helpWin.close();
  },

  popUpHelp : function(strURL) {
    Educativa.Utils.closeWinHelp();
    var strOptions = '';
    var strHeight  = screen.height - 100;
    var strWidth   = screen.width  - 100;
    var strOptions = 'scrollbars,resizable,status,height=' + strHeight + ',width=' + strWidth +
     ',left=50,top=50';
    try {
        Educativa.Utils.helpWin = window.open(strURL, 'helpWin', strOptions);
        Educativa.Utils.helpWin.focus();
    } catch(e){}
  },

  disable_links : function(element){
    $(element).select("a").each(function(item){
        item.observe('click', function(e){
            e.stop();
            alert( Educativa.Dict.LINKS_DESACTIVADOS_EN_LA_PREVISUALIZACION.capitalize());
            return true;
        });
        item.writeAttribute({title: item.readAttribute('href')});
        item.removeAttribute("href");
        item.setStyle({ textDecoration: 'underline' });
    });
  },
  uri_split : function(uri){
    var a = uri.match( /(?:([^:/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/ );
    return { scheme : a[1], authority : a[2], path : a[3], query : a[4], fragment : a[5] };
  },

  is_uri : function(value){
    if( ! value ) return false;
    //if( value.match(/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i ) ) return false; //ver bug 5727
    if( value.match(/%[^0-9a-f]/i ) ) return false;
    if( value.match(/%[0-9a-f](:?[^0-9a-f]|$)/i ) ) return false;

    // from RFC 3986
    var uri = Educativa.Utils.uri_split( value );

    if( ! uri.authority ) return false;
    if( uri.authority.match(/\s/) ) return false;

    // scheme and path are required, though the path can be empty
    if ( !(uri.scheme != null && uri.scheme.length && uri.path != null) ) return false;

    // if authority is present, the path must be empty or begin with a /
    var slash_re = new RegExp( "^/" );
    if(uri.authority != null  && uri.authority.length )
    {
        if( !( uri.path.length == 0 || uri.path.match(slash_re ) ) ) return false;
    }
    else
    {   // if authority is not present, the path must not start with //
        if ( uri.path.match(slash_re) ) return false;
    }

    // scheme must begin with a letter, then consist of letters, digits, +, ., or -
    if (! uri.scheme.toLowerCase().match('^[a-z][a-z0-9\+\-\.]*$') ) return false;

    return true;
  },
  cleanCommentOnPasteFromWord : function (str)
  {
    var results = '';
    str = str.replace(/endif\]--> &lt;!--/ig, '[endif]--> <!--')
             .replace(/--&gt; <!--\[if/ig, '--> <!--[if' )
             .replace(/(accept-charset)\s*=\s*[\"\'].*?[\"\']/gi, "");

   try {
        HTMLParser( str , {
          start: function( tag, attrs, unary )
          {
            results += "<" + tag;
            for ( var i = 0; i < attrs.length; i++ )
              results += " " + attrs[i].name + '="' + attrs[i].escaped + '"';
            results += (unary ? "/" : "") + ">";
          },
          end: function( tag )
          {
            results += "</" + tag + ">";
          },
          chars: function( text )
          {
            results += text;
          },
          comment: function( text ) {}
        });
    }catch(e){
        alert(Educativa.Dict.translate('CONTENIDO_INVALIDO_PREVISUALIZACION'));
    }

    return results;
  },
  addWmodeToFlashObjects: function( html_content, ed ){
      return html_content;

      var obj = new Element('div').update( html_content );
      var objects = obj.select('object');
      objects.each( function(e){
          if( e.readAttribute('classid') != 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000'){
              return;
          }
          e.writeAttribute('wmode','transparent')
          var wmode_present = false;
          e.childElements().each(function(c){

              if(     c.nodeName.toUpperCase() == 'PARAM'
                  && (c.readAttribute('name').toUpperCase() == 'wmode'.toUpperCase())
              ){
                  if(c.readAttribute('value') != 'transparent'){
                      c.writeAttribute('value','transparent')
                  }
                  wmode_present = true;
              }else if( c.nodeName.toUpperCase() == 'EMBED' ){
                  c.writeAttribute('wmode','transparent')
              }
          });

          if( !wmode_present){
              e.insert( new Element('param',{ name : 'wmode',value:'transparent'}) );
          }
      });
      return ed.serializer.serialize(obj);
  },

  dateFormat: function( fecha ) {
      return Educativa.Utils.dateFormatDate(fecha)+' '+Educativa.Utils.dateFormatTime(fecha);
  },

  dateFormatDate: function( fecha ) {
      var mes = (fecha.getMonth()+1);
      var dia = fecha.getDate();
      return (dia<10?'0'+dia:dia)+'/'+(mes<10?'0'+mes:mes)+'/'+fecha.getFullYear();
  },

  dateFormatTime: function( fecha ) {
      var hora = fecha.getHours();
      var minuto = fecha.getMinutes();
      return (hora<10?'0'+hora:hora)+':'+(minuto<10?'0'+minuto:minuto);
  },

  /* Retorna el nombre del dia de la semana de una fecha */
  /* El invocador es responsable de cargar las traducciones de los terminos al javascript */
  dateFormatDayName: function( fecha ) {
      var dias = {
        0 : 'DOMINGO',
        1 : 'LUNES',
        2 : 'MARTES',
        3 : 'MIERCOLES',
        4 : 'JUEVES',
        5 : 'VIERNES',
        6 : 'SABADO'
      };

      return dias[fecha.getDay()].term();
  },

  /* Retorna el nombre del mes de una fecha, si se pasa el string 'short' en modo, usa nombres cortos para los meses */
  /* El invocador es responsable de cargar las traducciones de los terminos al javascript */
  dateFormatMonthName: function( fecha, modo ) {
      var meses = {
        0 : 'ENERO',
        1 : 'FEBRERO',
        2 : 'MARZO',
        3 : 'ABRIL',
        4 : 'MAYO',
        5 : 'JUNIO',
        6 : 'JULIO',
        7 : 'AGOSTO',
        8 : 'SEPTIEMBRE',
        9 : 'OCTUBRE',
        10 : 'NOVIEMBRE',
        11 : 'DICIEMBRE'
      };

      var mes = meses[fecha.getMonth()];

      if ( modo == 'short' ) mes += '_SHORT';

      return mes.termcap();
  },

  parseDate: function(date){ //Toma una fecha en formato '2010 10 31 14 05' (esto seria 2010/10/31 14:05)
    var arr = date.split(/ /);
    return new Date( arr[0], arr[1]-1, arr[2], arr[3], arr[4]);
  }

};

/**
* @class Educativa::Debug
*
*/
Educativa.Debug = {
  clear : function(o){
        if ($('DivDebug')) $('DivDebug').innerHTML='';
    },
  show : function(o){
    var d;
    if (!$('DivDebug')){
        d = document.createElement('pre');
        d.id = 'DivDebug';
        d.style.position = 'fixed'
        d.style.left     = '10px';
        d.style.bottom   = '0';
        d.style.width    = '92%';
        d.style.height   = '200px';
        d.style.overflow = 'auto';

        d.style.fontSize = '11px';

        d.style.color    ='#FFFFFF';
        d.style.zIndex   ='1000';
        d.style.backgroundColor='pink';
        d.style.borderWidth='2px';
        d.style.borderColor ='black';
        d.style.borderStyle ='solid';
        d.ondblclick = function(){
            Element.hide(this);
        }
        document.body.style.paddingBottom = '200px';
        document.body.appendChild(d);
    } else {
        d = $('DivDebug');
    }
    d.show();
    var str="";

    if ( typeof o == 'string')
        str = o;
    else for(i in o)
            str += "\t" + i + " => " + o[i] + "\n";

    d.innerHTML +=  "\n" + str;
  }
};


/**
* @class Educativa::Session
*
*/
Educativa.Session = {} ;

Educativa.utf8 = 0;


// diccionarios


Educativa.Dict     = new (function(){
    function _translate( t )  {
        return Educativa.Dict[t] ? Educativa.Dict[t] : '*' + t + '*';
    }

    Object.extend( String.prototype, {
        term : function() {return _translate(this);},
        termcap:  function() { return this.term().capitalize() ;}
    } );

    return {
        translate : _translate,
        add : function(term, traduccion) {
            if( Object.isString(term) )
                Educativa.Dict[term] = traduccion;
            else
                Object.extend( Educativa.Dict, term );
        }
    }
});

Educativa.Glosario = {};



if ( $('AyudaContextual')) Event.observe(window, 'load', function(){
    Event.observe(window, 'keypress', function(event) {
        if (event.charCode == 104) {
            Educativa.Utils.popUpHelp( $('AyudaContextual').href );
        }
    });

    $('AyudaContextual').onclick = function(){
        Educativa.Utils.popUpHelp( $('AyudaContextual').href );
        return false;
    }

});

/* Educativa.Alert */
(function(){
    var alertas = [];
    Educativa.Alert = Class.create({
        options :
        {
            type : 'info',
            text : ''
        },
        initialize : function(options)
        {
            myself = this;
            myself.detallesVisibles = false;
            // si options es un string
            if ( typeof( options ) != 'object' ) options = { text : options };

            Object.extend( this.options, options );

            var content = new Element('div',{className: 'content'}).update( this.options.text );
            this.element = new Element('div', { className: 'alert '+ this.options.type , style: "display:none" })
                               .insert( content );

            if( this.options.log ) {

                var showHideButton = new Element('div', {className: 'AlertShowHideButton'} ).update('[Mostrar Detalles]');

                var log_mssg = new Element('ul');
                this.options.log.each(function(e){
                    if( e.type == 'detail' ){
                        log_mssg.insert( new Element('li',{className: 'AlertLogDetail'}).update(e.text)) ;
                    }else{
                        log_mssg.insert( new Element('li',{className: 'AlertLogLi'}).update(e.text)) ;
                    }
                });
                log_mssg.hide();

                var contentLog = new Element('div',{className:'AlertLogContent'})
                                     .insert( showHideButton )
                                     .insert( log_mssg );

                this.element.insert( contentLog );
                showHideButton.observe('click',function(){
                    if( myself.detallesVisibles ){
                        log_mssg.hide();
                        showHideButton.update('[Mostrar Detalles]');
                        myself.detallesVisibles = false;
                    }else{
                        log_mssg.show();
                        showHideButton.update('[Ocultar Detalles]');
                        myself.detallesVisibles = true;
                    }
                });
            }

            $('ajax_indicator').insert({ after : this.element });

            if (Effect) Effect.Pulsate(this.element.identify(),
                { pulses: 3, duration: .6 });

            this.element.show();
            alertas.push( this );
        },
        hide : function()
        {
            this.element.hide();
        }

    });

    Object.extend( Educativa.Alert, {
        hideAll : function()
        {
            alertas.invoke('hide');
        }
    });
})();



/* Educativa.Popup
 */
Educativa.Popup = Class.create({
    closed: function(){
        return this.window.closed;
    },
    initialize : function(options) {
        this.options = {
          url       : 'about:blank',
          width     : 600,
          height    : 500,
          name      : '_blank',
          location  : false,
          menubar   : false,
          toolbar   : false,
          status    : true,
          scrollbars: true,
          resizable : true,
          left      : 0,
          top       : 0,
          depend    : false,
          normal    : false,
          center    : true
        };

        Object.extend(this.options, options || {});

        if ( Educativa.id_grupo ) this.options.name += Educativa.id_grupo;

        if ( this.options.depend )
            Event.observe( window, 'unload', this.close.bind(this) )


        if (this.options.normal){
            this.options.menubar  = true;
            this.options.status   = true;
            this.options.toolbar  = true;
            this.options.location = true;
        }

        this.options.width
            = this.options.width < screen.availWidth
            ? this.options.width
            : screen.availWidth;

        this.options.height
            = this.options.height < screen.availHeight
            ? this.options.height
            : screen.availHeight;

        if ( this.options.center ){
            this.options.top  = (screen.availHeight - this.options.height + 1) / 2;
            this.options.left = (screen.availWidth  - this.options.width  + 1) / 2;
        }


        var openoptions =
            'width='       + this.options.width
          + ',height='     + this.options.height
          + ',location='   + (this.options.location   ? 'yes' : 'no')
          + ',menubar='    + (this.options.menubar    ? 'yes' : 'no')
          + ',toolbar='    + (this.options.toolbar    ? 'yes' : 'no')
          + ',scrollbars=' + (this.options.scrollbars ? 'yes' : 'no')
          + ',resizable='  + (this.options.resizable  ? 'yes' : 'no')
          + ',status='     + this.options.status ;

        if ( this.options.top != "" ) openoptions += ",top=" + this.options.top;
        if ( this.options.left!= "" ) openoptions += ",left="+ this.options.left;


        Educativa.Popup.Objects[this.options.name] = this;

        this.window = window.open(this.options.url, this.options.name,openoptions );

        return this.window;

    },
    reload : function( n ){
        ele = Educativa.Popup.get( n );
        setTimeout( function(){
            if ( this.window.closed && this.options.onClose )
                this.options.onClose();
            else if ( this.options.onReload )
                this.options.onReload();
        }.bind(ele), 1)
    },
    close : function(){

        if ( ! this.closed() )
            this.window.close();
    },
    focus : function(){
        this.window.focus();
        return this;
    },
    write : function (content) {
        var doc = this.window.document;
        doc.write(content);
        doc.close();
    }
});
Educativa.Popup.Objects = {};
Educativa.Popup.get = function(name){
    var r ;
    try {
        if ( ! Educativa.Popup.Objects[name].closed() )
            r = Educativa.Popup.Objects[name];
    } catch(e){}
    return r;
}
Educativa.Popup.open = function(opt){
    var name = opt.name;
    if ( Educativa.id_grupo ) name += Educativa.id_grupo;
    var w = Educativa.Popup.Objects[ name ];
    return  w && !w.closed()
        ? w.focus()
        : new Educativa.Popup( opt );
}

/* Educativa.Tooltip
 */
Educativa.Tooltips = [];
Educativa.Tooltip = Class.create({
    initialize : function(options){
        this.options = {
            trigger   : null,
            html      : '',
            canFixed  : false
        };

        Object.extend( this.options, options );

        this.trigger = $(this.options.trigger);
        this.html    = this.options.html;

        var tt = this.element = new Element('div');
        tt.className = 'tooltip';
        tt.update(this.options.html);

        $(document.body).appendChild( tt );

        this.trigger.observe('mouseover', this.show.bindAsEventListener(this) );
        this.trigger.observe('mouseout', this.hide.bindAsEventListener(this) );
        this.trigger.observe('click', this.click.bindAsEventListener(this) );

        Educativa.Tooltips.push( this );

    },

    show : function(e){
        var tt = this.element, bt = this.trigger;
        tt.makePositioned();
        Position.clone( bt, tt, {
            setWidth:0,
            setHeight: 0,
            offsetLeft: 3,
            offsetTop: - 1 - tt.getHeight()
        });
        tt.setStyle({zIndex : 500});
        bt.addClassName('tooltip-button-over');
        if ( this.trigger.hasClassName('tooltip-fixed') ) return;
        tt.show();
    },
    hide : function(e){
        if ( this.trigger.hasClassName('tooltip-fixed') ) return ;
        this.trigger.removeClassName('tooltip-button-over');
        this.element.hide();
    },
    click : function(e){
        return;
        if ( ! this.options.canFixed ) return;
        this.trigger.toggleClassName('tooltip-fixed');
        this.fixed = this.trigger.hasClassName('tooltip-fixed');
        Element.toggleClassName(this.element, 'tooltip-fixed-tt');

        var l = this.trigger.ancestors().find(function(e){ return e.hasClassName('line') });

        if ( ! this.trigger.hasAttribute('line_height') )
            this.trigger.setAttribute('line_height', l.getHeight() );
        if ( this.trigger.hasClassName('tooltip-fixed') ){
            if ( l.getHeight() < this.element.getHeight() )
                l.setStyle({ height : this.element.getHeight() + 'px' });
        } else {
            l.setStyle({ height : this.trigger.getAttribute( 'line_height' ) + 'px' });
        }

        Educativa.Tooltips
            .findAll(function(e){ return e.fixed } )
            .invoke('show');
    }

});

Educativa.Tooltip.Menu = Class.create({
    initialize : function(options){
        this.options = {
            trigger   : null,
            html      : '',
            over      : null,
            offsetLeft: 0,
            offsetTop : 0 ,
            className : 'tooltip',
            title     : '',
            is_tooltip: false,
            center    : false
        };

        Object.extend( this.options, options );
        //
        var options = this.options;
        var menu = this;
        if( ! this.options.over ) this.options.over = this.options.trigger;
        this.trigger = $(this.options.trigger);

        //dialog
        var tt = this.element = new Element('div');
        tt.className = options.className;
        tt.hide();
        $(document.body).insert( tt );

        //container
        this.container = new Element('div',{ className: options.className + '_container'  });
        this.container.update(this.options.html);
        this.element.insert(this.container);

        // boton para cerrar la ventana
        this.title_bar = new Element('div', {className: options.className + '_title_bar'});
        this.b_close = new Element('a', {className: options.className + '_close_button'});

        this.title_bar.update(options.title).insert(this.b_close);
        tt.insert( this.title_bar );

        var trigger_event = options.is_tooltip ? 'mouseover' : 'click';

        if( this.trigger ){
            this.trigger.observe( trigger_event, this.raise_dialog.bindAsEventListener(this) );

            if( options.is_tooltip ){
                this.trigger.observe('mouseout', this.hide.bindAsEventListener(this) );
                tt.observe('mouseover', this.show.bindAsEventListener(this) );
            }
        }

        this.b_close.observe('click', this.hide.bindAsEventListener(this) );

        if (options.draggable) {
            this.title_bar.setStyle( {'cursor': 'move'} );
            new Draggable(tt, { handle: this.title_bar,revert: false });
        }

        //esta linea hace que cuando se salga de la caja la oculte
        //tt.observe('mouseout', this.hide.bindAsEventListener(this) );
    },
    raise_dialog: function(){

        if (this.options.center) {
            var left = (document.viewport.getWidth() - this.element.getWidth())/2;
            var top = (document.viewport.getHeight() - this.element.getHeight())/2;
            if (top < 0) top = 0;
            this.element.setStyle({left: left+'px', top: top+'px'});
        } else {
            Position.clone( this.options.over, this.element, {
                setWidth:0,
                setHeight: 0,
                offsetLeft: this.options.offsetLeft,
                offsetTop: this.options.offsetTop
            });
        }

        var t = this;
        Effect.Appear( this.element, {
            duration :0.4,
            afterFinish: function(){
                t.container.fire('TooltipMenu:render');
            }
        });
    },
    show : function(e){
        this.element.show();
    },
    hide : function(e){
        this.element.hide();
    },
    update: function(content){
        this.container.update(content);
        //this.element.appendChild( this.b_close );
    },
    setOver: function(over){
        this.options.over = over;
    },
    setOffSetLeft: function(offset){
        this.options.offsetLeft= offset;
    }

});

/* Deshabilito los clicks derechos
 */
Educativa.disableRightClick = function (){
    $$('.noRightClick').each(function(e){ e.oncontextmenu=function(){return false} });
}
Educativa.agregar_glosario = function() {
    if (! $('marco_principal') ) return;
    var div = $('DivTerminoGlosarizado');
    if (!div){
        new Insertion.Before($('marco_principal'), '<div id="DivTerminoGlosarizado" style="display:none" ></div>');
        div = $('DivTerminoGlosarizado');
        div.makePositioned();
    }
    var tmpl = new Template(
           '<h6>#{id}</h6><p>#{desc}</p><em>'
        +  Educativa.Dict['CLICK_SOBRE_EL_TERMINO_PARA_VISUALIZAR_EL_GLOSARIO_COMPLETO']
        + '</em>'
    );

    $$('.TerminoGlosarizado').each(function(o){

        o.observe('mouseover', function(e){
            o.makePositioned();
            var offset = Position.realOffset(o);
            Position.clone( o, div, {
                setWidth  : 0,
                setHeight : 0,
                offsetLeft: 20,
                offsetTop : 20
            } );

            div.innerHTML = Educativa.Glosario[o.name]
                ? tmpl.evaluate(Educativa.Glosario[o.name])
                : '';
            div.show();
        });
        o.onmouseout = function(){ div.hide(); }

        o.onclick    = function(){
            window.open('glosario.cgi?id_curso=' + Educativa.id_grupo,
                        'glosario',
                        'width=350,height=450,scrollbars=yes');
            return false;
        }


    })
}
Event.observe(window, 'load', Educativa.disableRightClick );
Ajax.Responders.register({  onComplete: Educativa.disableRightClick });

Event.observe(window, 'load', Educativa.agregar_glosario );
Ajax.Responders.register({  onComplete: Educativa.agregar_glosario });

//Esta varriable debe existir, ya que se usa (Ajax.Responders.unregister(uke_ajax_indicator_callbacks);)
//para desregistrar estos indicadores por defecto.
var uke_ajax_indicator_callbacks = {
    onCreate  : function(){ if($('ajax_indicator')) $('ajax_indicator').show() },
    onComplete: function(){ if($('ajax_indicator')) $('ajax_indicator').hide() }
};
Ajax.Responders.register(uke_ajax_indicator_callbacks);


/*
Este codigo se comenta debido a que en la version 3.3.9.3 del tinymce se produce
un error de visualizacion en internet explorer al abrir una ventana modal.
El error en cuestion se puede visualizar en el titulo de la ventana ya que esta aparece 'cortada'

if ( ! window.getSelection ){
    window.getSelection = function (){
        if (document.getSelection) {
            window.getSelection = document.getSelection;
        } else if (document.selection) {
            window.getSelection = function(){
                return document.selection.createRange().text;
            }
        } else {
            window.getSelection = function(){}
        }
        return window.getSelection();
    }
}
*/

try{
if ( window.opener && window.name && window.opener.Educativa ){
    Event.observe( window, 'unload', function(){
        try{
            window.opener.Educativa.Popup.get( window.name ).reload(window.name);
        } catch(e){}
    });

}
} catch(e){}







if( Object.isUndefined( window.console ) ){
    window.console = {
        log : function(){},
        info : function(){}
    };
}

popupWins = new Array();

if(! window.windowOpener) windowOpener = function ( url, name, args)
{
    if ( typeof( popupWins[name] ) != "object" ){
        popupWins[name] = window.open(url,name,args);
    } else {
        if (!popupWins[name].closed){
            popupWins[name].focus();
        } else {
            popupWins[name] = window.open(url, name,args);
        }
    }
    popupWins[name].focus();
};

if (! window.OpenWin ) OpenWin = function () {
    switch ( id_usuario ){
        case "":
            alert(Educativa.Dict.translate('PARA_UTILIZAR_EL_CHAT_PRIMERO_DEBES_INGRESAR_A_LA_INTRANET'));
            break;
        case "_anonimo":
            alert(Educativa.Dict.translate('ESTA_FUNCION_NO_ESTA_DISPONIBLE_PARA_USUARIOS_ANONIMOS'));
            break;
        default:
            var windowX = (screen.width/2)-390;
            var windowY = (screen.availHeight/2)-285;
            void windowOpener('location.cgi?wseccion=21'+'&id_curso='+id_grupo,
                              'Chat'+id_usuario+id_grupo,
                              'toolbar=0,location=0,directories=0,status=0,'+
                              'menubar=0,scrollbars=0,resizable=0,width=780,'+
                              'height=570,top='+windowY+',screenY='+windowY+
                            ',left='+windowX+',screenX='+windowX);
    }//end switch

}; //end OpenWin()

if(!window.MensajeInstantaneo) MensajeInstantaneo= function ( titulo, destino, asunto) {
    InstantaneaScript=url_dir+"nph-instantanea.cgi?wIdDestino="+destino+"&wAsunto="+asunto;
    if( confirm(titulo) ){ location.href = InstantaneaScript; }
};

//es pisada en evaluaciones, pero no cousa problemas...
if (! window.small_window ) small_window = function ( myurl, ventana_x, ventana_y) {
    var winl = (screen.width - ventana_x) / 2;
    var wint = (screen.height - ventana_y) / 2;
    var props = 'scrollBars=yes,resizable=yes,toolbar=no,menubar=no,location=no,'+
                'directories=no,width='+ventana_x+',height='+ventana_y+
                ',top='+wint+',left='+winl;

    var uri = myurl.split(/[?#]/);
    if( uri[1] ){
        var query = uri[1].toQueryParams();
        query['id_curso'] = id_grupo;
        uri[1] = $H(query).toQueryString();
    }
    myurl = uri[0] +'?'+uri[1]+ (uri[2] ? '#'+uri[2] : '' );

    var newWindow = window.open(myurl, "microsite", props);
    newWindow.focus();
};

// Agrega el color #CCC a los option desactivados, bug del IE
if ( Prototype.Browser.IE )
    Event.observe(window, 'load', function(){
        $$('select option').each(function(e){
            if(e.disabled) e.setStyle({color : "#CCC"});
        });
    });

/* se utiliza para los popups de ayuda donde la ventana es mas grande q en aula */
Event.observe(window, 'load', function(){
    var a = $$('#boton-ayuda a').first();
    if (a) a.observe('click',function(event){
        var aula_front_end = a.href.toQueryParams().section;
        event.stop();
        Educativa.Popup.open({
            url       : a.href,
            width     : aula_front_end ? 740 : screen.width-100,
            height    : aula_front_end ? 600 : screen.height-100,
            name      : '_blank',
            status    : false,
            resizable : true,
            left      : (screen.width/2)-370,
            top       : (screen.availHeight/2) - 300,
            depend    : false,
            center    : ! aula_front_end
        });
    })
})

/* se utiliza para abrir los popups de ayuda en aula */
Educativa.popupAyuda = function (args){

    var url = Educativa.url_ayuda;

    if( args.url )
        url = args.url;

    new Educativa.Popup({
        url : url,
        width : 740,
        height : 600,
        resizable: false,
        status : false
    });

    return;
}

/** @fn $string  generar_id($lenght)
 *  genera un id correspondiente al mail que se esta enviando
 *  \param lenght  la longitud del id
 *  \return string con el id de lenght caracteres , undef en caso de error
 */
Educativa.Utils.generar_id = function(cant){
    var list = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    return $R(1,cant).map(function(){
        return list.charAt( Math.floor(Math.random() * (list.length + 1)) );
    }).join('');

}

/** @fn $string  isInScrollView($element, $scrollParent)
 *  Determina si un elemento esta visible en un contenedor scrolleable
 *  \param element el elemento a verificar. Debe ser hijo de scrollParent
 *  \param scrollParent debe ser un contenedor scroleable (overflow auto).
 *  \return true | false si se encuentra o no visible
 */
Educativa.Utils.isInScrollView = function(element, scrollParent) {
    return (element.offsetTop + element.getHeight() > scrollParent.scrollTop+ scrollParent.getHeight())
           || (element.offsetTop < scrollParent.scrollTop);
}


// clase abstracta, debe ser heredara para funcionar
// Parametros obligatorios:
//    trigger    : 'el1', //id del elemento que dispara la ventana
//    container  : 'donde_se_muestra',          // id del elemento en donde se insertan
//    ajax_url   : '?wAccion=ajax_list&id_item=5' //url de donde se toman los elementos
// Parametros opcionales:
//    page_limit : 10,
//    className  : 'list_select_dialog',
//    void_list_message : "No existen items dispobibles"
//    draggable  : permite arrastrar la ventana
//    offsetTop   : 0,
//    offsetLeft  : 0
//    title       : '',
Educativa.ListSelectDialog = Class.create({

    initialize : function(args) {
        //parametros que recive
        var options = {
            trigger     : null,
            ajax_url    : null,
            page_limit  : 10,
            page_index  : 0,
            className   : 'list_select_dialog',
            void_list_message : "No existen items disponibles",
            draggable   : 0,
            offsetTop   : 0,
            offsetLeft  : 0,
            title       : '',
            lista       : null //array con los items disponibles
        };

        Object.extend(options,args); // para pisar los default
        Object.extend(this,options);


        this.menu = new Educativa.Tooltip.Menu({
            trigger   : $(this.trigger),
            html      : new Element('div',{ className: this.className+"_spinner" }),
            className : this.className,
            over      : $(this.trigger),
            offsetLeft: this.offsetLeft,
            offsetTop : this.offsetTop,
            draggable : this.draggable,
            title     : this.title
        });

        this.menu.container.observe(
            'TooltipMenu:render',
            this.render.bindAsEventListener(this )
        );

        var obj = this;
        if( this.lista == null ){
            new Ajax.Request(this.ajax_url, {
                method: 'get',
                onSuccess: function(transport) {
                    obj.lista = transport.responseText.evalJSON();
                    obj.load_items();
                }
            });
        }else{
            this.load_items();
        }

    },
    load_items: function() {
        var obj = this;
        var i = 0;
        $A(this.lista).findAll(function(c){ return c.asociado == 1 }).each(function(c){
            obj.asociar_item({ item :c, index: i++ });
        });
    },

    render: function(ev,argd_container) {
        var obj = this;

        if( obj.lista == null ){

            new Ajax.Request(this.ajax_url, {
                method: 'get',
                onSuccess: function(transport) {
                    obj.lista = transport.responseText.evalJSON();
                    obj.draw_items_list();
                }
            });

        }else{
            this.draw_items_list();
        }
    },

    draw_items_list: function( ){
        var obj = this;
        var cant_c = $A(this.lista).findAll(function(e){ return e.asociado == 0 }).size();
        if( cant_c == 0 ){
            this.menu.update( new Element('div').update( this.void_list_message ));
            return;
        }
        if( this['empty_body_message'] && cant_c == this.lista.length ) this.empty_body_message();
        //chequeaos basicos
        if( this.page_index >= cant_c ){ this.page_index -= this.page_limit ; }
        if( this.page_index < 0       ){ this.page_index = 0; }

        var div = new Element('div');
        var list = new Element('ul');

        var items = $A(this.lista).
            findAll(function(e){ return e.asociado == 0 }).
            sort( function(a,b){ return a.nombre.localeCompare(b.nombre); } );

        for( var i = this.page_index; items[i] &&  i < (this.page_index+this.page_limit) ; ++i){
            var e = items[i];
            var li = new Element('li',
                    { id: "curso_"+e.id , className: e.estado ? this.className+'_item_'+(i%2?'impar':'par'): 'grupo_inactivos_control' }
            );

            list.insert(
                li.insert( new Element('span').update(e.nombre+ ' ') )
            );

            li.observe('click', obj.asociar_item.bind(obj, { item: e} ) );

            if( this['item_decorator'] ) this.item_decorator( li, e);
        }

        div.insert(list);

        // paginador
        var pie = new Element('div',{ className: this.className + '_footer' });

        if( this.page_index > 0 ){
            var atras    = new Element('span',{ className: this.className + '_back'  }).update(' << ');
            atras.observe('click', this.retroceder_pagina.bindAsEventListener(this) );
            pie.insert(atras);
        }

        pie.insert(new Element('span').update(
            Educativa.Dict.PAGINA_DE.interpolate({
                nro:'<span style="font-weight: bold" >'+
                     ((this.page_index/this.page_limit)+1).floor()
                    +'</span>' ,
                total: (cant_c/this.page_limit).ceil()
                }).capitalize()
        ));

        if( cant_c > (this.page_index+this.page_limit) ){
            var adelante = new Element('span',{ className: this.className + '_next'  }).update(' >> ');
            adelante.observe('click', this.avanzar_pagina.bindAsEventListener(this) );
            pie.insert(adelante);
        }
        div.insert(pie);

        this.menu.update( div);

    },

    avanzar_pagina: function( ){
        this.page_index += this.page_limit;
        this.draw_items_list();
    },

    retroceder_pagina: function( ){
        this.page_index -= this.page_limit;
        this.draw_items_list();
    },

    toFormInput: function(formId, inputName){ // puede reescribirse
        var frm = $(formId);
        $$('.'+inputName+'_class').each(function(e){
            e.remove();
        });
        $A(this.lista).findAll(function(c){ return c.asociado == 1 }).each( function (c) {
            frm.insert(new Element('input',{
                className: inputName+'_class',
                name  : inputName,
                value : Object.toJSON({ id: c.id, activo: (c.activa_chk.checked ?1 :0) }),
                type  : 'hidden'
            }));
        });
        return true;

    },

    hide: function(){
        this.menu.hide();
    },

    asociar_item: function(arg){}, //pure virtual

    desasociar_item: function(arg){}, //pure virtual

    empty_body_message: function(){} //pure virual (puede no ser implementada)
});


/*
    [
        {
            label : 'parent 1',
            value : 1
            childs : [
                { label : 'child 1', value : 1 },
                { label : 'child 2', value : 2 },
                ...
            ]
        },
        ...
    ]
*/
Educativa.LinkedCombos = Class.create({
    initialize : function (args) {
        this.name = args.name;
        this.options = args.options;
        this.target = args.target;
        Object.extend(this, args);

        this.render();
        this.onChangeParent();
    },
    render : function () {
        $(this.target).update('');

        this.parentCombo = new Element('select', {id : this.name + '_parent'});

        var pcombo = this.parentCombo;
        var options = this.options;

        var i = 0;
        $A(options).each(function(opt) {
            pcombo.insert( new Element('option', {value : opt.value}).update(opt.label) );
        });

        Event.observe(pcombo,'change',this.onChangeParent.bindAsEventListener(this));

        $(this.target).insert(new Element('p').update(
            new Element('label', {'for' : this.name + '_parent'}).update(this.label_parent)
            ).insert(pcombo)
        );
        $(this.target).insert(new Element('p', {id : this.name + '_child_cont'}).update(
            new Element('label', {'for' : this.name + '_child'}).update(this.label_child)
            )
        );
        $(this.target).insert(new Element('input', {type: 'hidden', name: this.name, id: this.name}));

        this.onChangeParent();
    },
    onChangeParent : function() {
        if (this.childCombo) {
            Element.remove(this.childCombo);
        }
        this.childCombo = new Element('select', {id : this.name + '_child'});
        var ccombo = this.childCombo;
        var pcombo = this.parentCombo;

        var options = this.options;

        $A(options).each(function(opt) {
            if (opt.value == pcombo.getValue()) {
                $A(opt.childs).each(function(chld) {
                    ccombo.insert( new Element('option', {value : chld.value}).update(chld.label) );
                });

            }
        });

        this.setValue(pcombo.getValue(),ccombo.getValue());

        Event.observe(ccombo,'change',this.onChangeChild.bindAsEventListener(this));
        $(this.name + '_child_cont').insert(ccombo);
    },
    onChangeChild : function() {
        var ccombo = this.childCombo;
        var pcombo = this.parentCombo;

        this.setValue(pcombo.getValue(),ccombo.getValue());
    },
    setValue : function (p, c) {
        $(this.name).setValue(p + ',' + c);
    },
    getSelected : function () {
        var ccombo = this.childCombo;
        var pcombo = this.parentCombo;
        return [pcombo.getValue(),ccombo.getValue()];
    }
});

// ie bug... no toma los checked si no estan agregados al form en el DOM. se utiliza en encuestas
function ie_bug_element(e,h){
    var parameters = '';
    $H(h).each(function(pair) {
        if( pair.value == null ) return;
        if( pair.key == 'disabled'){
            if(pair.value) {
                parameters += ' disabled="disabled" ';
            }
            return;
        }
        parameters += ' '+pair.key +'="'+ pair.value+'" ';

    });
    return '<'+e+parameters+' />';
}


/* Permite eliminar el contenido de un input file.
*   Modo de uso, ejemplo:
*
*     <INPUT id="wImagenPost" class=CajaABM TYPE=FILE NAME="wImagenPost" SIZE=35
*            onchange="Educativa.InputClear.agregarInput('wImagenPost')" style="width: auto;"
*     >
*
*/
(function(){

var inputs_creados = [];

Educativa.InputClear = Class.create({
    initialize : function(input_id) {
        var input_file = $(input_id);

        this.elementId = input_id;

        this.element = input_file;

        this.element.addClassName('inputFile');

        this.padre = input_file.parentNode || input_file.parentElement;
        this.existeEliminar = 0;
    },

    crear: function(){

        if( this.existeEliminar == 0 ){
            this.wrapper = this.element.wrap( 'div', {className : 'inputClearWrapper'});

            this.wrapper.appendChild( (new Element('a', {
                href : 'javascript:;',
                className : 'inputClearButton',
                title : Educativa.Dict.translate('QUITAR_ARCHIVO')
            })).observe('click', function(){ this.eliminar(); }.bind(this)) );

            this.wrapper.appendChild( new Element('div', { style : 'clear:both' } ) );

            this.existeEliminar = 1;
        }

    },

    eliminar: function(){
        var c = this.element.E();

        this.element = new Element('input', {
            type: 'file',
            className: this.element.className,
            name: this.element.name,
            size: this.element.size,
            id: this.elementId
        });

        if ( c ) {
            c.element = this.element;
        }

        this.element.observe( 'change', this.crear.bind(this) );


        this.wrapper.replace( this.element );

        Educativa.Utils.disable_input_file_keypress();

        this.existeEliminar = 0;
    }

});

Educativa.InputClear.agregarInput = function(input_id) {
    if( ! inputs_creados[input_id] ){
        inputs_creados[input_id] = new Educativa.InputClear(input_id);
    }
    inputs_creados[input_id].crear();
};

Educativa.InputClear.clear = function( input_id ) {
    if( inputs_creados[input_id] ){
        inputs_creados[input_id].eliminar();
    }
};

})();


// Debe llamarse en el onLoad, o cuando esten creados los objetos
Educativa.Desplegable = Class.create({
    desplegado: false,

    initialize : function( header_id, body_id, options ) {

        Object.extend( this, options );
        this.header = $(header_id);
        this.body   = $(body_id);

        if( this.desplegado ){
            this.header.addClassName('formSection-desplegado');
            this.header.removeClassName('formSection-replegado');
            this.body.show();
        }else{
            this.header.removeClassName('formSection-desplegado');
            this.header.addClassName('formSection-replegado');
            this.body.hide();
        }

        this.header.observe('click',this.onClick.bindAsEventListener(this));
    },

    onClick: function(){
        if( this.desplegado ){
            this.desplegado = false;
            this.header.removeClassName('formSection-desplegado');
            this.header.addClassName('formSection-replegado');
            this.body.hide();
        }else{
            this.desplegado = true;
            this.header.addClassName('formSection-desplegado');
            this.header.removeClassName('formSection-replegado');
            this.body.show();
        }
    }
});


Educativa.OverlayedSpinner = Class.create({
    over: null, //param
    spinner: null,
    className: 'OverlayedSpinner',
    transparent: true,
    opacity: 0.6,
    over_opacity: 0.8,

    initialize: function(args){
        Object.extend( this, args);

        var d = this.over.getDimensions();
        this.spinner = new Element('div',{ className: this.className +'-spinner' } );
        this.spinner.setStyle({
            position: 'absolute', width: d.width, height: d.height, zIndex: 1000
        });
        this.spinner.clonePosition(this.over);
        this.spinner.setOpacity(this.opacity);
        if( this.transparent ) this.over.setOpacity(this.over_opacity);
        $(document.body).insert( this.spinner );

    },
    remove: function(){
        this.spinner.remove();
        if( this.transparent ) this.over.setOpacity(1);
    }

});


/* muestra / oculta select para el acceso a la Administracion General
   y a la administracion del producto */
Event.observe(window,'load',function(){

    if( $('select_administracion') != null ) {

        var position_top = - ($('select_administracion_opciones').getHeight() + 4) + 'px';

        var toggle = function(event){
            if ( event.isRightClick() ) return;

            $('select_administracion_opciones').setStyle({top: position_top});
            $('select_administracion_opciones').toggle();
        };

        $('select_administracion')
            .observe('mouseup',toggle);

        Event.observe(document.body, 'click', function(event) {


            var element = Event.element(event);

            if(     element.id != 'select_administracion'
                &&  element.id != 'titulo_opciones_administracion')
            {
                $('select_administracion_opciones').hide();
            }
        });

    }
});

/*Esto falla en ciertos entornos */
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
    return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
    return this.replace(/\s+$/,"");
}

Educativa.Utils.ln2br = function( s ) {
    while (s.indexOf("\n") > -1)
        s = s.replace("\n","<br />");
    return s;
}


/****************************************************************************************************
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
*!!!! Las ultimas funciones pueden fallar en ciertos navegadores (es un comportamiento esperado) !!!*
*!!!! AGREGAR LAS NUEVAS CLASES ANTES DEL ULTIMO Event.observe                                   !!!*
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*
*****************************************************************************************************/


