
//=================================================
//  INICIO
//  ajax-minimo.js
//=================================================

/** Indica se a engine esta ocupada processando um request. **/
var _ajaxBusy = false;

/** Fila de requisicoes que nao puderam ser processadas ainda **/
var _queue = new Array();

/**
 * Funcao "minima" para atualizar um div com o conteudo de uma URL.
 *
 * @param {Div} div cujo conteudo (innerHTML) sera atualizado.
 * @param {String} url URL (completa, com parametros) que sera requisitada. A esta url
 * sera adicionado um parametro numerico com o timestamp atual (para ignorar possiveis
 * caches do browser)
 * @param {String} errorMessage Texto a ser utilizado caso ocorra algum erro
 * durante a atualizacao. Este texto tambem sera colocado dentro do div.
 * @param {Boolean} execScripts Indica se tags "script" dentro do texto recebido
 * devem ser processadas ou nao. Default == false.
 */
function ajaxUpdate( div, url, errorMessage, execScripts  ) {

	// Enfileira esta requisicao, se ja estamos processando uma.
	if ( _ajaxBusy ) {
		_queue.push( { div: div, url: url, errorMessage: errorMessage, execScripts: execScripts } );
		return;
	}

	// Indica que estamos ocupados.
	_ajaxBusy = true;

  // Cria o objeto xmlhttp
  try {
		xmlhttp = new XMLHttpRequest();
  } catch( e1 ) {
		try{
    	xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch( e2 ) {
			try {
      	xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch( e3 ) {
      	xmlhttp = false;
     	}
   	}
  }

  // Pluga a funcao que vai atualizar o div.
  xmlhttp.onreadystatechange = function() {
	    try {
			if ( xmlhttp.readyState == 4 ) {
				var ok = ( xmlhttp.status == undefined || xmlhttp.status == 0 ||
						   (xmlhttp.status >= 200 && xmlhttp.status < 300) );

				if ( ok ) {
				loadPage( div, xmlhttp.responseText, execScripts );
				} else {
					loadPage( div, errorMessage, execScripts );
				}

				// Terminamos de processar esta requisicao; indica que estamos livres e
				// tenta dar vazao a fila.
				_ajaxBusy = false;
				consumeQueue();
			}
		} catch (e) {
			loadPage( div, errorMessage, execScripts );
		}

	}

	// Dispara a requisicao. Adiciona um parametro (? ou &) com o timestamp.
	var c = url.indexOf( "?" ) == -1 ? "?" : "&";
  xmlhttp.open( "get", url + c + new Date().getTime(), true );
  xmlhttp.send( null );
}

function loadPage( container, text, execScripts ) {
	container.innerHTML = text;
	if ( execScripts ) evalScripts( text );
}

function consumeQueue() {
	if ( _queue.length < 1 ) {
		return;
	}

	var request = _queue.shift();
	ajaxUpdate( request.div, request.url, request.errorMessage, request.execScripts );
}

function evalScripts( htmlFragment ) {
	var SCRIPT_REGEX = '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)';
	var MATCH_ALL = new RegExp( SCRIPT_REGEX, "img" );
	var MATCH_ONE = new RegExp( SCRIPT_REGEX, "im" );

	// Recupera todos os fragmentos <script> dentro da string em um array.
	var scriptTags = htmlFragment.match( MATCH_ALL ) || [];
	for ( var i = 0; i < scriptTags.length; i++ ) {
		// Para cada fragmento, recupera o texto dentro das tags.
		var script = scriptTags[i].match( MATCH_ONE )[1];
		eval(script);
	}
}

//=================================================
//  FIM
//  ajax-minimo.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  drag-portlet.js
//=================================================
// Configuracoes
var _largura = 210;
var _maxModulesPerColumn = null;
var _errorMessage = "";
var _exchangeWhenFull = false;

// Funcoes de callback do mecanismo de drag-and-drop.
var _onDragStart = null;
var _onDragEnd = null;
var _onAddModule = null;
var _onRemoveModule = null;

//var _createModulePlaceholder = null;

/** Guarda o estado atual dos modulos na tela. Eh uma lista de objetos ModuleColumn. **/
var _moduleColumns;

// Variaveis privadas.
var _ocupa;
var _subocupa;

// guarda os applets enquanto o m?dulo est? sendo arrastado
var _appletHolder = null;

/**
 * Se usando o modo de "troca" de modulos quando a coluna esta cheia, guarda
 * o ultimo modulo "trocado" de lugar (util para "destrocar" quando a sombra
 * muda de lugar).
 */
var _lastExchangedModule = null;

/** Cache de colunas ajustadas durante o drag. Vide findNextModule(). **/
var _adjustedColumnsCache = new Array();

/**
 * ModuleColumn: objeto que agrupa uma lista de ModuleInfos e metodos utilitarios.
 *
 * @param {Div} div Div que representa a coluna.
 * @param {Integer} index Indice desta coluna dentro do seu pai.
 */
function ModuleColumn( div, index ) {
  this.box = findRelativeBox( div, $("modulesArea") );
  this.modules = new Array();
  this.index = index;
  this.div = div;

  this.add = function( moduleInfo ) {
    this.modules.push( moduleInfo );
    moduleInfo.column = this;
    moduleInfo.index = this.modules.length - 1;
  }

  this.moduleAt = function( index ) {
    if ( index < 0 ) return null;
    if ( index >= this.modules.length ) return null;
    return this.modules[ index ];
  }
}

/**
 * ModuleInfo: objeto com informacoes sobre um modulo, incluindo
 * suas coordenadas (propriedade "box"), a coluna no qual se encontra,
 * o indice dele dentro da coluna, e o div com seu conteudo.
 *
 * @param {Div} div Div que representa o modulo em si.
 */
function ModuleInfo( div ) {
	
  this.box = findRelativeBox( div, $("modulesArea") );
  
  this.div = div;
  this.column = null;
  this.index = 0;
  this.moduleId = div.id.replace( /mod/, "" );
  
}


/**
 * Monta a estrutura de dados que descreve a situacao atual
 * dos modulos na tela. Esta funcao atualiza a variavel global
 * _moduleColumns, que eh um array de ModuleColumns.
 */
function buildModuleInfos() {

  _moduleColumns = new Array();

  // Varre todas as colunas
  var cols = $children( $("modulesArea"), "div" );
  for ( var i = 0; i < cols.length; i++ ) {

    // So considera tags que tenham class="coluna"
    if ( cols[i].className != "coluna" ) continue;

    var moduleColumn = new ModuleColumn( cols[i], i );

    _moduleColumns.push( moduleColumn );

    // Varre todos os modules desta coluna
    var modules = $children( cols[i], "div" );
    for ( var j = 0; j < modules.length; j++ ) {

      if ( modules[j].className.indexOf("modulo") == -1 ) continue;

      var info = new ModuleInfo( modules[j] );
      moduleColumn.add( info );

     //$tagWithClass( modules[j], "help" ).innerHTML = info.box.toString();

      // Adiciona o info ao div do modulo, tambem, para facilitar obtencao de infos depois
      modules[j].moduleInfo = info;
    }
  }
}


/**
 * Dispara a inicializacao de todas as funcoes necessarias pelo
 * drag-n-drop de modulos.
 */
function initModuleDrags() {
	
	// Cria o div que representa o espaco vago para inserir um modulo
  _ocupa = $new( "div" );
  _ocupa.id = 'ocupa';
	// Cria o div usado para segurar o modulo enquanto ele eh arrastado
  _subocupa = $( "subocupa" );
  if (_subocupa == null) {
      _subocupa = $new( "div" );
      _subocupa.id = "subocupa";
  } 

	// Adiciona o subocupa diretamente sob a area de modulos
  $("modulesArea").appendChild( _subocupa );
	
	// Varre todos os divs com classe "modulo"
  var divs = $tags( 'div' )
  for( var i = 0; i < divs.length; i++ ) {
    var div = divs[i];
    if( div.className.indexOf("modulo") > -1 ) {
	
			// Cria um drag sobre este div, usando como handle o
			// primeiro elemento com css "handle"
			
      Drag.init( $tagWithClass( div, "handle" ), div );

			// Pluga os handlers de DND
      div.onDragStart = dragStart;
      div.onDrag = dragOn;
      div.onDragEnd = dragEnd;
    }
  }

	// Obtem informacoes sobre os modulos existentes
	buildModuleInfos();
}

function hasApplets () {
	if ((document.applets) && (document.applets.length > 0)) {
		hasApplet = true;
	}
}


// acha as tags applet debaixo de this
// guarda as tags em variaveis globais e faz o remove do this
// coloca uma tag <div> no lugar com um id especifico
function replaceAppletWithDummyDiv(element) {
	var temDiv = $new('DIV');
	temDiv.id = 'appletReplacer';
	temDiv.innerHTML = 'movendo...';

    //alert(element.innerHTML);
	var c = $('mod_moedas');
	if (!c) {
		alert('falhou!');
	} else {
		$('modules_island').appendChild(c);
		//_appletHolder = temDiv;
		//$replace(temDiv, c);
	}
}

// varrer o this em busca de tag <div > com id especificado
// recolocar as tags applet removidas
function replaceDummyDivWithApplet(element) {
	var c = $('modules_island').childNodes[0];
	if (!c) {
		//alert('falhou!');
	} else {
		$replace( _appletHolder, c );
		//_appletHolder = null;
	}
}


// acha as tags applet debaixo de this
// guarda as tags em variaveis globais e faz o remove do this
// coloca uma tag <div> no lugar com um id especifico
function showApplet(element) {
	var temDiv = document.createElement('DIV');
	temDiv.id = 'appletReplacer';
	var this_children = element.childNodes;
	for	(var i=0; i < this_children.length; i++) {
		var child = this_children[i];
		if (child.nodeName == 'applet'){
			_appletHolder = child;
			$replace(child, tempDiv);
		}
	}
}

function handleAppletsBack(element) {
	var this_children = element.childNodes;
	for	(var i=0; i < this_children.length; i++) {
		var child = this_children[i];
		if (child.id == 'appletReplacer'){
			$replace(child, _appletHolder);
			return;
		}
	}
}


/**
 * Funcao que deve ser executada quando o drag se iniciar. Esta funcao
 * monta o objeto com o estado atual dos modulos, e altera a estrutura
 * dos divs (ocupa, subocupa, e o div sendo arrastado) para fazer o efeito
 * de drag-and-drop.
 *
 * @param {Integer} x DeltaX do movimento
 * @param {Integer} y DeltaY do movimento
 */
function dragStart( x, y ) {

    // Atualiza as informacoes sobre os modulos existentes
    buildModuleInfos();
    var modulesArea = $( "modulesArea" );
    var areaLeft    = modulesArea.offsetLeft;
    var areaTop     = modulesArea.offsetTop;
    var areaRight   = areaLeft + modulesArea.offsetWidth;
    var areaBottom  = areaTop + modulesArea.offsetHeight;
    this.moduloOriginClassName = this.className;
    
    if ( (x + areaLeft) < areaLeft
            || (y + areaTop) < areaTop
            || (x + areaRight) > areaRight
            || (y + areaBottom) > areaBottom ) {
            
        // Remove este div do temporario e troca de lugar com o placeholder
        $del( this );
        $replace( this, _ocupa );
        // varrer o this em busca de tag <div > com id especificado
        // recolocar as tags applet removidas
        //handleAppletsBack(this);

        // Zera o auxiliar (so eh usado se _exchangeWhenFull esta true)
        //_lastExchangedModule = null;

        // Limpa o CSS
        this.style.top  = "0px";
        this.style.left = "0px";

        // Volta o CSS original deste div.
        this.className = this.moduloOriginClassName;
        showApplets();

    } else {

        hiddenApplets();

        // Calcula a posicao do modulo sendo movido (this)
        var areaPos = findPos( $("modulesArea") );
        var thisPos = findPos( this );

        // Altera a classe CSS deste div.
        this.className = "moduloMoving";

        // Reposiciona o subocupa para que o canto fique no mesmo canto que o div original.
        _subocupa.style.left = thisPos.left - areaPos.left + "px";
        _subocupa.style.top = thisPos.top - areaPos.top + "px";

        /*
        $("log").innerHTML = "mouse: " + x + ":" + y + " subocupa " + findPos( _subocupa ).toString() +
                " this " + this.style.left + ":" + this.style.top;
        */

        //handleApplets(this);

        // Coloca o placeholder no lugar deste div
        $replace( _ocupa, this );
        

        // Coloca este div dentro do temporario
        _subocupa.appendChild( this );

        // Dispara callbacks
        if ( _onDragStart ) {
            _onDragStart( x, y, this );
        }

        /** [ventura] Para evitar a criacao de arrays temporarios no dragOn,
         * iremos manter um "cache" com a posicao "alterada" das 3 colunas, populado aqui.
         */
        _adjustedColumnsCache = new Array();

        for ( var i = 0; i < _moduleColumns.length; i++ ) {
            _adjustedColumnsCache.push( fixColumnModulesList( _moduleColumns[i], this.moduleInfo ) );
        }
    }

}

/**
 * Funcao que deve ser executada quando o drag estiver em andamento. Esta
 * funcao descobre qual o local onde o div de "sombra" deve aparecer e o
 * coloca la.
 *
 * @param {Integer} x
 * @param {Integer} y
 */
function dragOn( x, y ) {
  // Descobre a coluna-alvo corrente.
  var colIdx = findColumnIndex( this.moduleInfo, x );
  colIdx = $fixRange( colIdx, 0, _moduleColumns.length - 1 );
  
  // Recupera a coluna indicada.
  var columnInfo = _moduleColumns[ colIdx ];

	// Conta quantos modulos esta coluna tera, depois do drop.
	var count = columnInfo.modules.length;
	if ( this.moduleInfo.column != columnInfo ) count++;

	// Se temos um limite de modulos por coluna, e nao estamos com o
	// modo "exchange" ligado, verifica se o limite pode ser honrado.
	// Se nao puder, retorna, deixando o ocupa na posicao anterior.
	if ( ( _maxModulesPerColumn != null ) && ( ! _exchangeWhenFull ) &&
	     ( count > _maxModulesPerColumn ) ) {
			return;
	}

    	// Estima a posicao Y, somando o deltaY ao centro do modulo que foi arrastado.
    	var posY = y + this.moduleInfo.box.centerTop;

    	// Descobre o div que esta sob o mouse.
    	var nextModule = findNextModule( columnInfo, this.moduleInfo, posY );


	// Primeiro, verifica se eh necessario "destrocar" a sombra com
	// outro div. Descobre isto comparando o lastExchangedModule com
	// este. Se for o mesmo, nao precisa fazer nada; se nao for, desfaz
	// o exchange. NOTA: _lastExchangedModule sempre esta null se
	// _exchangeWhenFull esta false.
	if ( _lastExchangedModule != null && _lastExchangedModule != nextModule ) {
	    if (_ocupa != null && _lastExchangedModule.div != null) {
		   $exchange( _lastExchangedModule.div, _ocupa );
		   _lastExchangedModule = null;
	    }
	}

       /*
	$("log").innerHTML =
   	"mouse: " + posY +
		" lastExchanged: " + ( _lastExchangedModule == null ? "null" : _lastExchangedModule.moduleId ) +
		" next: " + ( nextModule == null ? "null" : nextModule.moduleId );
       */

	// Se o limite nao foi atingido (ou nao existe), insere o div de sombra no meio
	// dos divs existentes.
	if ( ( _maxModulesPerColumn == null ) || ( count <= _maxModulesPerColumn ) ) {
	
          // Faz um exchange ou um append, dependendo se o modulo sob o mouse existe ou nao.
	  if ( nextModule == null ) {
	  	if (_ocupa != null) {
	  	     columnInfo.div.appendChild( _ocupa );
		}
	  } else {	  	
		if (_lastExchangedModule != nextModule) {
		     if ( _ocupa != null) {
			     if ( nextModule != null && nextModule.div != null ) {
				 $exchange( _ocupa, nextModule.div );
				 _lastExchangedModule = nextModule; 
			     }
		     } 
		}
	  }	  
	  
	}

	// Atingiu o limite (e so chega aqui se _exchangeWhenFull esta true);
	// troca o div do ocupa com o div sob o mouse.
	else {
		if ( ( nextModule != null ) && ( _ocupa.parentNode != columnInfo.div ) ) {
			if (_lastExchangedModule != nextModule) {
			     if ( _ocupa != null && nextModule.div != null) {
				 if ( nextModule != null && nextModule.div != null ) {
				      $exchange( _ocupa, nextModule.div );
				      _lastExchangedModule = nextModule;
				 }
			     }
			}
		}
	}
}

/**
 * Funcao que deve ser executada no final da operacao de drag-and-drop.
 * Esta funcao recoloca o div sendo arrastado no lugar do div de "sombra",
 * e dispara as callbacks configuradas (document.onDragEnd()).
 *
 * @param {Integer} x
 * @param {Integer} y
 */
function dragEnd( x, y ) {
  var ocupa = $( 'ocupa' );
  if (ocupa != null) {     
      //Se nÃ£o houve a ultima troca, troque.
      /*if ( _lastExchangedModule != null) {
	    if (_lastExchangedModule.div != null) {
		   $exchange( _lastExchangedModule.div, ocupa );
		   _lastExchangedModule = null;
	    }
      }*/
      
      // Remove este div do temporario e troca de lugar com o placeholder
      $del(this);      
      
      //Troca o ocupa (sombra) pelo modulo
      $replace(this, ocupa);

      // varrer o this em busca de tag <div> com id especificado
      // recolocar as tags applet removidas
      //handleAppletsBack(this);

      // Zera o auxiliar (so eh usado se _exchangeWhenFull esta true)
      _lastExchangedModule = null;

      // Limpa o CSS
      this.style.top = "0px";
      this.style.left = "0px";

      // Volta o CSS original deste div.
	this.className = this.moduloOriginClassName;
      
 
      // Dispara callbacks
      buildModuleInfos();
      if ( _onDragEnd ) {
          _onDragEnd( x, y, this );
      }
      showApplets();

      if ( document.getElementById("iframeMoeda") ) {
          document.getElementById("iframeMoeda").src = document.getElementById("iframeMoeda").src;
      }
  }
}


/**
 * Verifica qual o indice da coluna na qual a "sombra" deve ser posicionada.
 * Descobre isto baseado no quanto o "x" andou desde o comeco do drag.
 *
 * NOTA: Este metodo supoe que todos os modulos tem a mesma LARGURA.
 */
function findColumnIndex( moduleInfo, x ) {

  var amount = Math.floor( ( Math.abs( x ) - ( _largura / 2.0 ) ) / _largura ) + 1;
  if ( x < 0 ) {
    amount = -amount;
  }

  // Adiciona no indice da coluna da qual partimos.
  var result = moduleInfo.column.index + amount;
  return result;
}


/**
 * Descobre qual o proximo modulo durante um drag -- isto eh, o modulo antes
 * do qual deve ser inserido o div de "sombra". Este metodo retorna null se nao
 * existe proximo modulo (por exemplo, se estamos movendo para a ultima posicao
 * da coluna). Se ele retornar um modulo, eh antes dele que o div de sombra deve
 * ser inserido.
 *
 * @param {ModuleColumn} columnInfo
 * @param {ModuleInfo} moduleBeingDragged
 * @param {Integer} y
 * @return ModuleInfo correspondente ao modulo que vira em seguida se o DND
 * acabar agora, ou null se nao existir modulo nessa situacao.
 */
function findNextModule( columnInfo, moduleBeingDragged, y ) {

	// Recupera a lista de modulos "ajustada" (isto eh, sem o modulo
	// corrente, e com as posicoes acertadas neste caso). Isto provem
	// de um cache criado no dragStart, para que nao seja necessario
	// instanciar arrays durante o dragOn.
 	var modules = _adjustedColumnsCache[ columnInfo.index ];

  // Se nao existem modulos, retorna null
  if ( modules.length < 1 ) return null;

  var next = null;
  var prev = null;
  for ( var i = 0; i < modules.length; i++ ) {
    if ( modules[i].y > y ) {
      next = i;
      prev = i - 1;
      if ( prev < 0 ) prev = null;
      break;
    }
  }

 /*
 	$("log2").innerHTML = "y: " + y + ", next: " + next + ", prev: " + prev;
  */

  // Se next esta null, eh porque eh o ultimo
  if ( next == null ) return null;

  // Se prev esta null, eh porque eh o primeiro
  if ( prev == null ) return modules[0].moduleInfo;

  // Descobre qual dois dois esta mais perto.
  if ( ( modules[ next ].y - y ) < ( y - modules[ prev ].y ) ) {
    return modules[ next ].moduleInfo;
  } else {
    return modules[ prev ].moduleInfo;
  }
}


/**
 * "Corrige" a lista de modulos da coluna-alvo atual; esta correcao retira
 * o modulo sendo arrastado da coluna (se estiver nela) e, neste caso,
 * atualiza as posicoes dos modulos que vem em seguida, subtraindo a altura
 * do modulo removido (para simular o efeito dele ser retirado da coluna).
 *
 * @param {Object} columnInfo
 * @param {Object} moduleBeingDragged
 * @return Lista de objetos que correspondem aos modulos da coluna, sem o
 * modulo sendo arrastado (caso esteja nesta) e, neste caso, com as posicoes
 * Y acertadas. Nota: o objeto de retorno possui duas propriedades, "y" (com
 * o valor da coordenada Y do centro do modulo) e "moduleInfo" (com o moduleInfo
 * propriamente dito).
 */
function fixColumnModulesList( columnInfo, moduleBeingDragged ) {
	var result = new Array();
	var foundModule = false;

	for ( var i = 0; i < columnInfo.modules.length; i++ ) {
  	var oneModule = columnInfo.modules[i];

  	if ( oneModule == moduleBeingDragged ) {
   		foundModule = true;
   		continue;
  	}

  	if ( ! foundModule ) {
   		result.push( { y: oneModule.box.centerTop, moduleInfo: oneModule } );
  	} else {
			// ToDo : falta levar em conta a margem entre modulos
   		result.push( { y: oneModule.box.centerTop - moduleBeingDragged.box.height, moduleInfo: oneModule } );
  	}
 	}

 	return result;
}


/**
 * Adiciona um novo modulo ao grid de modulos.
 *
 * @param {Integer} colIdx Indice da coluna na qual o modulo deve ser inserido.
 * @param {Integer} modIdx Indice dentro da coluna no qual o modulo deve ser inserido
 * @param {ModuleDefinition} moduleDef Definicao do modulo sendo adicionado.
 */
function addModule( colIdx, modIdx, moduleDef ) {
	
	// Define a categoria para cada modulo para definir um "class" 
	// Isso Ã© utilizando para mudar o fundo de cada modulo
	var category = '';
	if(moduleDef.categoryLabel == "\xDAltimas not\xEDcias"){
		category = 'ultimasnoticias';
	} else if(moduleDef.categoryLabel == "Ferramentas"){
		category = 'ferramentas';
	} else if(moduleDef.categoryLabel == "Mais Populares"){
		category = 'maispopulares';
	} else if(moduleDef.categoryLabel == "Empresas"){
		category = 'empresas';
	} else if(moduleDef.categoryLabel == "Indicadores"){
		category = 'indicadores';
	}

  // Cria o div para conter o modulo.
  var newDiv = $new( 'div' );
  newDiv.id = "mod" + moduleDef.id;
  newDiv.className = "modulo " + category;
  newDiv.innerHTML = _createModulePlaceholder( moduleDef );

	// Dispara o init do Drag neste modulo tambem
  Drag.init( $tagWithClass( newDiv, "handle" ), newDiv );
  newDiv.onDragStart = dragStart;
  newDiv.onDrag = dragOn;
  newDiv.onDragEnd = dragEnd;

  // Recupera a coluna indicada.
  var column = _moduleColumns[ colIdx ];

  // Se o indice eh maior que o ultimo elemento, faz um append.
	// Caso contrario, faz um insertBefore.
  if ( modIdx >= column.modules.length ) {
    column.div.appendChild( newDiv );
  } else {
    var existingMod = column.modules[ modIdx ];
    $before( newDiv, existingMod.div );
  }

  // Dispara o load desse modulo. Quando o resultado chegar,
  // coloca dentro do div "contents" desse modulo.
	var contentsDiv = $tagWithClass( newDiv, "contents" );
	ajaxUpdate( contentsDiv, moduleDef.fullUrl, _errorMessage, true );

	buildModuleInfos();
	if (_onAddModule) {
		_onAddModule();
	}

}

/**
 * Remove um modulo da pagina.
 *
 * @param {Integer} id ID do modulo a ser removido.
 */
function removeModule( id ) {

	// Recupera o div que contem o modulo e o remove da pagina
	var div = $( "mod" + id );
	if ( div != null ) {
	     $del( div );
	}

	buildModuleInfos();
	if (_onRemoveModule) {
		_onRemoveModule();
	}
}


function hiddenApplets() {
	var elements = $("modulesArea").getElementsByTagName("applet");
	if (elements != null) {
		for (i = 0; i < elements.length; i++) {
			elements[i].style.display="none";
		}
	}
}

function showApplets() {
	var elements = $("modulesArea").getElementsByTagName("applet");
	if (elements != null) {
		for (i = 0; i < elements.length; i++) {
			elements[i].style.display = "inline";
		}
	}
}


//=================================================
//  FIM
//  drag-portlet.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  dom-drag.js
//=================================================
/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************/

var Drag = {

       
	obj : null,

	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
	{
		o.onmousedown	= Drag.start;

		o.hmode			= bSwapHorzRef ? false : true ;
		o.vmode			= bSwapVertRef ? false : true ;

		o.root = oRoot && oRoot != null ? oRoot : o ;

		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

		o.minX	= typeof minX != 'undefined' ? minX : null;
		o.minY	= typeof minY != 'undefined' ? minY : null;
		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
		o.maxY	= typeof maxY != 'undefined' ? maxY : null;

		o.xMapper = fXMapper ? fXMapper : null;
		o.yMapper = fYMapper ? fYMapper : null;

		o.root.onDragStart	= new Function();
		o.root.onDragEnd	= new Function();
		o.root.onDrag		= new Function();
	},

	start : function(e)
	{
		var o = Drag.obj = this;		
		e = Drag.fixE(e);

		if (e.which && e.which != 1) return false;
		if (e.button && e.button != 1) return false;

		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.hmode) {
			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
		} else {
			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
		}

		if (o.vmode) {
			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
		} else {
			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
		}
		o.onmousedown	= null;
		document.onmousemove = Drag.drag;
		document.onmouseup = Drag.end;		

		return false;
	},

	drag : function(e)
	{
		e = Drag.fixE(e);
		var o = Drag.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;

		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		var nx, ny;

		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

		if (o.xMapper)		nx = o.xMapper(y)
		else if (o.yMapper)	ny = o.yMapper(x)

		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
		Drag.obj.lastMouseX	= ex;
		Drag.obj.lastMouseY	= ey;

		Drag.obj.root.onDrag(nx, ny);
		return false;
	},

	end : function()
	{
		document.onmousemove = null;
		document.onmouseup   = null;
		Drag.obj.root.onDragEnd(parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]),
					   parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
		Drag.obj.onmousedown = Drag.start;					   
		Drag.obj = null;
	},

	fixE : function(e)
	{
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};


//=================================================
//  FIM
//  dom-drag.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  personalizacao.js
//=================================================
/**
 * PersonalizacaoUtil
 *
 * Esta classe contem metodos utilitarios para gerir o controle de drag-and-drop de modulos
 * juntamente com as funcionalidades de personalizacao, isto eh, armazenamento das
 * preferencias do usuario em banco de dados.
 *
 * Para utilizar, basta executar o metodo <code>PersonalizacaoUtil.init()</code> durante
 * o onLoad da pagina.
 */

	// usado para debug do DWR
	function handler( msg ) {
		//throw msg;
	}

	var PersonalizacaoUtil = new Object();

	var handle = null;

	PersonalizacaoUtil.config = {
		updateIntervalMillis : 1000 * 10, // 10s
		flushOnUnload : true,
		cookiePrefix : "userPreferences" ,
		loadAvailableModulesCallback : null,
		siteId : null
	};

	PersonalizacaoUtil.modules = new Array();

	PersonalizacaoUtil.getModules = function() {
		return this.modules;
	}

	PersonalizacaoUtil.getModuleById = function( id ) {
		for ( var i = 0; i < this.modules.length; i++ ) {
			if ( this.modules[i].id == id ) return this.modules[i];
		}
		return null;
	}

	/**
	 * Dispara a inicializacao de todos os mecanismos javascript da personalizacao.
	 * Especificamente, este metodo dispara o init do drag-and-drop em cada modulo,
	 * adiciona os handlers para o flush das preferencias (no timer, e no onUnload),
	 * e carrega as preferencias do usuario a partir do banco de dados.
	 */
	PersonalizacaoUtil.init = function() {
	
		//Debug de erros do DWR
		DWREngine.setErrorHandler( handler );
		DWREngine.setWarningHandler( handler );
		DWREngine.setTimeout( 1000 * 11 );

	     // Dispara o init do drag-n-drop
	    initModuleDrags();

		// Pluga a callback que grava as preferencias quando o drop acontece, remo??o e adi??o de m?dulos
		_onDragEnd = _onAddModule = _onRemoveModule = function ( x, y, moduleInfo ) {
			PersonalizacaoUtil.saveState( _moduleColumns );
		}

	  	// Pluga o flush no onUnload da p?gina, se desejado
		if ( this.config.flushOnUnload ) {
	  		addUnload( function() { PersonalizacaoUtil.flushState() } );
		}

	  	// Dispara o flush em intervalos periodicos, se desejado
		if ( this.config.updateIntervalMillis != null ) {
			handle = setInterval( function() { PersonalizacaoUtil.flushState() }, this.config.updateIntervalMillis );
		}

		// Carrega a lista de modulos possiveis do servidor e guarda em cache
		PersonalizacaoController.getAvailableModules( function( modules ) {
			PersonalizacaoUtil.modules = modules;

			if ( PersonalizacaoUtil.config.loadAvailableModulesCallback ) {
				PersonalizacaoUtil.config.loadAvailableModulesCallback( modules );
			}
		});
		// Carrega o estado do servidor
		PersonalizacaoUtil.loadState();
		// Carrega menu de personalizacao
		PersonalizacaoUtil.loadMenu();
	}

	/**
	 * Descobre os m?dulos do usu?rio logado (ou os m?dulos do usu?rio
	 * an?nimo) e os coloca nas posi??es apropriadas.
	 */
	PersonalizacaoUtil.loadState = function() {
        var prefix = this.config.cookiePrefix;
        

		PersonalizacaoController.loadModulePositions( function( prefs ) {

			var lastUpdate = readCookie( prefix + "LastUpdate" );
			var lastFlush = readCookie( prefix + "LastFlush" );

			var useCookie = false;
			if ( ( lastUpdate != null ) &&
				 ( lastFlush == null ) || ( parseInt( lastUpdate ) > parseInt( lastFlush ) ) ) {
			 	useCookie = true;
			}

			if ( useCookie && logado()) {
				var currentModulePositions = readCookie( prefix + "ModuleState" );
				if ((lastFlush != null) &&
				    (currentModulePositions != null) &&
				    (currentModulePositions != "")) {
	    			var currentArray = PersonalizacaoUtil.buildStateFromString( currentModulePositions );
		    		for ( var i = 0; i < currentArray.length; i++ ) {
			    		for ( var j = 0; j < currentArray[i].length; j++ ) {
				    		// Chamada para a API do dnd
				    		if (currentArray[i][j]!=null && currentArray[i][j]!="") {
						    	var moduleDef = PersonalizacaoUtil.getModuleById( currentArray[i][j] );
						    	if (moduleDef != null) {
	    							addModule( i, j, moduleDef );
	    						}
    						}
	    				}
		    		}
				} else {
				    for ( var i = 0; i < prefs.length; i++ ) {
					    for ( var j = 0; j < prefs[i].length; j++ ) {
						    // Chamada para a API do dnd
						    addModule( i, j, prefs[i][j] );
					    }
				    }

				}
				PersonalizacaoUtil.saveState( _moduleColumns );

			} else {

				for ( var i = 0; i < prefs.length; i++ ) {
					for ( var j = 0; j < prefs[i].length; j++ ) {

						// Chamada para a API do dnd
						addModule( i, j, prefs[i][j] );
					}
				}
			}
		});
	}

	/**
	 * Grava o estado dos m?dulos que o usu?rio escolheu. Esta fun??o
	 * grava as prefer?ncias em um cookie; para enviar as prefer?ncias
	 * para o servidor, veja a fun??o flushState().
	 *
	 * @param moduleColumns Array de objetos ModuleColumn representando
	 * o estado a ser persistido.
	 */
	PersonalizacaoUtil.saveState = function( moduleColumns ) {
	  // Serializa o estado em uma string, e coloca essa string em um cookie.
	  var serialized = PersonalizacaoUtil.serializeState( moduleColumns );
	  createCookie( this.config.cookiePrefix + "ModuleState", serialized );

		//$("log2").innerHTML = "state: " + serialized;

	  // Guarda a data atual em um cookie, para saber quando foi feita a ?ltima
	  // atualiza??o pelo usu?rio.
	  var lastUpdateTime = new Date().getTime();
	  createCookie( this.config.cookiePrefix + "LastUpdate", lastUpdateTime );
	}

	/**
	 * Carrega os modulos default
	 */
	PersonalizacaoUtil.loadDefaultModules = function() {
		PersonalizacaoController.loadDefaultModulesPosition( function( prefs ) {
			for ( var i = 0; i < prefs.length; i++ ) {
				for ( var j = 0; j < prefs[i].length; j++ ) {
					// Chamada para a API do dnd
					addModule( i, j, prefs[i][j] );
				}
			}
		});
	}

	/**
	 * Serializa um estado para grava??o em cookie. O estado ? uma
	 * lista de listas de IDs de m?dulos. As listas externas s?o
	 * separadas com ";" e as internas com "," . Exemplo:
	 *
	 * <pre>
	 *  1, 2, 3 ; 4 ; 5, 6
	 *  corresponde a:
	 *  [
	 *   [ 1, 2, 3 ] ,
	 *   [ 4 ] ,
	 *   [ 5, 6 ]
	 *  ]
	 * </pre>
	 *
	 * @param moduleColumns array de ModuleColumn representando o estado.
	 */
	PersonalizacaoUtil.serializeState = function( moduleColumns ) {
	  var result = "";
	  for ( var i = 0; i < moduleColumns.length; i++ ) {
	    var oneColumn = moduleColumns[i];
	    for ( var j = 0; j < oneColumn.modules.length; j++ ) {
	      var oneModule = oneColumn.modules[j];

	      result += oneModule.moduleId;

	      if ( j < oneColumn.modules.length - 1 ) {
	        result += ", ";
	      }
	    }

	    if ( i < moduleColumns.length - 1 ) {
	      result += "| ";
	    }
	  }

	  return result;
	}



	/**
	 * Deserializa um estado guardado em uma string. Veja o formato
	 * em <code>serializeState()</code>.
	 *
	 * @param strState String com o estado serializado.
	 * @return Array de arrays com os IDs dos m?dulos em cada coluna.
	 */
	PersonalizacaoUtil.buildStateFromString = function( strState ) {
	  var result = new Array();

	  // Divide a string nos "|" para obter as partes de cada coluna
	  var strCols = strState.split( "|" );

	  // Adiciona uma coluna para cada string.
	  for ( var i = 0; i < strCols.length; i++ ) {

	    // Quebra a string de cada coluna nos ","
	    var oneColumn = strCols[i].split( "," );
	    result.push( oneColumn );

	    // Faz um trim em cada string
	    for ( var j = 0; j < oneColumn.length; j++ ) oneColumn[j] = oneColumn[j].trim();

	  }

	  return result;
	}



	/**
	 * Dispara a grava??o do estado no servidor. Esta fun??o determina
	 * se isso ? necess?rio ou n?o dependendo das datas de ?ltima
	 * atualiza??o de estado / ?ltimo flush de estado. Essas informa??es,
	 * bem como o estado a ser enviado, s?o recuperadas de cookies.
	 *
	 * Esta fun??o foi projetada para ser chamada em um timeout ou interval.
	 */
	PersonalizacaoUtil.flushState = function( force, erase ) {
	  // Descobre quando foi o ?ltimo flush e compara com a ?ltima atualiza??o do usu?rio.
	  var lastUpdate = readCookie( this.config.cookiePrefix + "LastUpdate" );
	  var lastFlush = readCookie( this.config.cookiePrefix + "LastFlush" );

	  //alert( "update/flush " + lastUpdate + "/" + lastFlush );

		// Ignora a "inteligencia" se o force esta true.
		if ( ! force ) {
		  // Se n?o existe um lastUpdate, n?o faz nada
		  if ( lastUpdate == null ) return;

		  // Existe, mas tamb?m existe um lastFlush feito depois; tamb?m n?o faz nada
		  if ( ( lastFlush != null ) &&
		  	   ( parseInt( lastFlush ) >= parseInt( lastUpdate ) ) ) return;
		}

	  // Chega aqui se existe um update, e n?o existe um flush adequado; executa o flush
	  // e guarda essa informa??o no cookie.
	  var serializedState = readCookie( this.config.cookiePrefix + "ModuleState" );
	  var now = new Date().getTime();

	  // NOTA: S? cria o cookie se o retorno da fun??o for OK e n?o uma exce??o. (desta
	  // forma, se ocorrer um erro, o cookie n?o ser? setado e o pr?ximo timeout vai
	  // tentar novamente). Al?m disso, mesmo se executado mais tarde, a data gravada no
	  // cookie ? a data de submiss?o de dados (ent?o, se acontece uma altera??o durante
	  // a chamada, ela ter? uma data posterior ? data no cookie, e ser? necess?rio mais
	  // um flush para grav?-la).
		var prefix = this.config.cookiePrefix;
	  PersonalizacaoController.saveModulePositions( serializedState, function() {
	    createCookie( prefix + "LastFlush", now );
	    if (erase) {
            eraseCookie(prefix + "LastFlush");
	    }
	  });

	}

   /**
    * Logout da personalizacao
    */
	PersonalizacaoUtil.logout = function() {
		if (handle != null) {
			clearInterval(handle);
		}
	    PersonalizacaoUtil.flushState(true, true);
		var modulos = PersonalizacaoUtil.getModules();
	    for (i =0; i < modulos.length; i++) {
	    	removeModule(modulos[i].id);
	    }
	    PersonalizacaoUtil.loadDefaultModules();
	}

	/**
	 * Carrega o menu da pagina
	 */
	PersonalizacaoUtil.loadMenu = function() {
		// callback que monta a tab para adi??o de novos modulos
		PersonalizacaoUtil.config.loadAvailableModulesCallback = function( modules ) {
			//Obtem o lugar onde os links do modulos ser??o escrito
			var ulModules = $("availableModules");
			//Variaveis auxiliares
			var previous = null;
			var iSubMenu = 0;
			var ulCategory = null;
			var liCategory = null;
			var separatorCount = 0;
			// Itera por cada modulo, criando links para adicionar cada um
			for (var i = 0; i < modules.length; i++ ) {
				//Verifica se existe uma categoria
				if (modules[i].categoryLabel != null) {
					//Se ?? um nova categoria...
					if (previous == null || previous.categoryLabel != modules[i].categoryLabel) {
						//Salva a categoria anterior
						if (ulCategory!=null && liCategory != null) {
							liCategory.appendChild(ulCategory);
							//Atualiza na raiz
							ulModules.appendChild( liCategory );
						}
						liCategory = $new( "li" );
						//Link de subMenu
						if(iSubMenu == 0){
							liCategory.innerHTML = "<a id=\"link" + iSubMenu + "\" href=\"javascript:subMenuOnClick(\'" + (iSubMenu) + "\');\" style=\"font-weight:bolder\" >" +
								modules[i].categoryLabel + "</a>";
						} else {
							liCategory.innerHTML = "<a id=\"link" + iSubMenu + "\" href=\"javascript:subMenuOnClick(\'" + (iSubMenu) + "\');\">" +
								modules[i].categoryLabel + "</a>";

						}
						//Cria uma nova categoria
						ulCategory = $new ( "ul" );
						ulCategory.setAttribute("id", "submenu" + iSubMenu);
						ulCategory.setAttribute("class", "submenu");
						ulCategory.className = "submenu";
						if(iSubMenu == 0){
							ulCategory.style.display = "block";
						} else {
							ulCategory.style.display = "none";
						}
						iSubMenu++;
						separatorCount = 0;
					}
					//Adiciona os sub-itens
					if (ulCategory != null) {
						var liModule = $new( "li" );
						liModule.innerHTML = ((separatorCount>0)?"&nbsp;&nbsp;|&nbsp;&nbsp;":"")+ ( (logado())?"<a href=\"javascript:exameAddModule(" + modules[i].id + ");\">":"<a href=\"javascript:exameAddModuleNaoLogado();\">" ) + modules[i].label + "</a>";
						ulCategory.appendChild( liModule );
						separatorCount++;
					}
				//Se n??o for...
				} else {
					//Salva a categoria anterior
					var liModule = $new( "li" );
					if (ulCategory != null) {
						liCategory.appendChild(ulCategory);
						//Atualiza na raiz
						ulModules.appendChild( liCategory );
					}
					//Inclui um item sem categoria
					ulCategory = null;
					liModule.innerHTML = "<a href=\"javascript:exameAddModule(" + modules[i].id + ");\">" + modules[i].label + "</a>";
					ulModules.appendChild( liModule );
				}
				previous = modules[i];
			}
			//Ultima categoria
			if (ulCategory != null) {
				liCategory.appendChild(ulCategory);
				//Atualiza na raiz
				ulModules.appendChild( liCategory );
			}
		}
	}



//=================================================
//  FIM
//  personalizacao.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  PersonalizacaoController.js
//=================================================

function PersonalizacaoController() { }
PersonalizacaoController._path = '/personalizacao/dwr';

PersonalizacaoController.ping = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'ping', callback);
}

PersonalizacaoController.getAvailableModules = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'getAvailableModules', callback);
}

PersonalizacaoController.setUseCache = function(p0, callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'setUseCache', p0, callback);
}

PersonalizacaoController.saveModulePositions = function(p0, callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'saveModulePositions', p0, callback);
}

PersonalizacaoController.loadModulePositions = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'loadModulePositions', false, callback);
}

PersonalizacaoController.loadDefaultModulesPosition = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'loadDefaultModulesPosition', callback);
}

PersonalizacaoController.saveUserPreferences = function(p0, callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'saveUserPreferences', p0, callback);
}

PersonalizacaoController.loadUserPreferences = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'loadUserPreferences', false, callback);
}

PersonalizacaoController.getItemPreferencia = function(p0, callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'getItemPreferencia', p0, false, callback);
}

PersonalizacaoController.saveItemPreferencia = function(p0, callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'saveItemPreferencia', p0, false, callback);
}

PersonalizacaoController.getUseCache = function(callback) {
    DWREngine._execute(PersonalizacaoController._path, 'PersonalizacaoController', 'getUseCache', callback);
}


//=================================================
//  FIM
//  PersonalizacaoController.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  engine.js
//=================================================



















if (DWREngine == null) var DWREngine = {};





DWREngine.setErrorHandler = function(handler) {
DWREngine._errorHandler = handler;
};





DWREngine.setWarningHandler = function(handler) {
DWREngine._warningHandler = handler;
};





DWREngine.setTimeout = function(timeout) {
DWREngine._timeout = timeout;
};





DWREngine.setPreHook = function(handler) {
DWREngine._preHook = handler;
};





DWREngine.setPostHook = function(handler) {
DWREngine._postHook = handler;
};


DWREngine.XMLHttpRequest = 1;


DWREngine.IFrame = 2;






DWREngine.setMethod = function(newMethod) {
if (newMethod != DWREngine.XMLHttpRequest && newMethod != DWREngine.IFrame) {
DWREngine._handleError("Remoting method must be one of DWREngine.XMLHttpRequest or DWREngine.IFrame");
return;
}
DWREngine._method = newMethod;
};





DWREngine.setVerb = function(verb) {
if (verb != "GET" && verb != "POST") {
DWREngine._handleError("Remoting verb must be one of GET or POST");
return;
}
DWREngine._verb = verb;
};





DWREngine.setOrdered = function(ordered) {
DWREngine._ordered = ordered;
};





DWREngine.setAsync = function(async) {
DWREngine._async = async;
};





DWREngine.setTextHtmlHandler = function(handler) {
DWREngine._textHtmlHandler = handler;
}





DWREngine.defaultMessageHandler = function(message) {
if (typeof message == "object" && message.name == "Error" && message.description) {
//alert("Error: " + message.description);
}
else {

if (message.toString().indexOf("0x80040111") == -1) {
//alert(message);
}
}
};





DWREngine.beginBatch = function() {
if (DWREngine._batch) {
DWREngine._handleError("Batch already started.");
return;
}

DWREngine._batch = {
map:{ callCount:0 },
paramCount:0,
ids:[],
preHooks:[],
postHooks:[]
};
};





DWREngine.endBatch = function(options) {
var batch = DWREngine._batch;
if (batch == null) {
DWREngine._handleError("No batch in progress.");
return;
}

if (options && options.preHook) batch.preHooks.unshift(options.preHook);
if (options && options.postHook) batch.postHooks.push(options.postHook);
if (DWREngine._preHook) batch.preHooks.unshift(DWREngine._preHook);
if (DWREngine._postHook) batch.postHooks.push(DWREngine._postHook);

if (batch.method == null) batch.method = DWREngine._method;
if (batch.verb == null) batch.verb = DWREngine._verb;
if (batch.async == null) batch.async = DWREngine._async;
if (batch.timeout == null) batch.timeout = DWREngine._timeout;

batch.completed = false;


DWREngine._batch = null;



if (!DWREngine._ordered) {
DWREngine._sendData(batch);
DWREngine._batches[DWREngine._batches.length] = batch;
}
else {
if (DWREngine._batches.length == 0) {

DWREngine._sendData(batch);
DWREngine._batches[DWREngine._batches.length] = batch;
}
else {

DWREngine._batchQueue[DWREngine._batchQueue.length] = batch;
}
}
};






DWREngine._errorHandler = DWREngine.defaultMessageHandler;


DWREngine._warningHandler = null;


DWREngine._preHook = null;


DWREngine._postHook = null;


DWREngine._batches = [];


DWREngine._batchQueue = [];


DWREngine._handlersMap = {};


DWREngine._method = DWREngine.XMLHttpRequest;


DWREngine._verb = "POST";


DWREngine._ordered = false;


DWREngine._async = true;


DWREngine._batch = null;


DWREngine._timeout = 0;


DWREngine._DOMDocument = ["Msxml2.DOMDocument.6.0", "Msxml2.DOMDocument.5.0", "Msxml2.DOMDocument.4.0", "Msxml2.DOMDocument.3.0", "MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"];


DWREngine._XMLHTTP = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];


DWREngine._stateChange = function(batch) {
	if (!batch.completed && batch.req.readyState == 4) {
		try {
			var reply = batch.req.responseText;

			if (reply == null || reply == "") {
				DWREngine._handleMetaDataWarning(null, "No data received from server");
			} else {
				var contentType = batch.req.getResponseHeader("Content-Type");
				if (!contentType.match(/^text\/plain/) && !contentType.match(/^text\/javascript/)) {
					if (DWREngine._textHtmlHandler && contentType.match(/^text\/html/)) {
						DWREngine._textHtmlHandler();
					} else {
						DWREngine._handleMetaDataWarning(null, "Invalid content type from server: '" + contentType + "'");
					}
				} else {
					if (reply.search("DWREngine._handle") == -1) {
						DWREngine._handleMetaDataWarning(null, "Invalid reply from server");
					} else {
						eval(reply);
					}
				}
			}


			DWREngine._clearUp(batch);
		} catch (ex) {
			if (ex == null) ex = "Unknown error occured";
				DWREngine._handleMetaDataWarning(null, ex);
		} finally {
			if (DWREngine._batchQueue.length != 0) {
				var sendbatch = DWREngine._batchQueue.shift();
				DWREngine._sendData(sendbatch);
				DWREngine._batches[DWREngine._batches.length] = sendbatch;
			}
		}
	}
};







DWREngine._execute = function(path, scriptName, methodName, vararg_params) {
var singleShot = false;
if (DWREngine._batch == null) {
DWREngine.beginBatch();
singleShot = true;
}

var args = [];
for (var i = 0; i < arguments.length - 3; i++) {
args[i] = arguments[i + 3];
}

if (DWREngine._batch.path == null) {
DWREngine._batch.path = path;
}
else {
if (DWREngine._batch.path != path) {
DWREngine._handleError("Can't batch requests to multiple DWR Servlets.");
return;
}
}


var params;
var callData;
var firstArg = args[0];
var lastArg = args[args.length - 1];

if (typeof firstArg == "function") {
callData = { callback:args.shift() };
params = args;
}
else if (typeof lastArg == "function") {
callData = { callback:args.pop() };
params = args;
}
else if (lastArg != null && typeof lastArg == "object" && lastArg.callback != null && typeof lastArg.callback == "function") {
callData = args.pop();
params = args;
}
else if (firstArg == null) {



if (lastArg == null && args.length > 2) {
DWREngine._handleError("Ambiguous nulls at start and end of parameter list. Which is the callback function?");
}
callData = { callback:args.shift() };
params = args;
}
else if (lastArg == null) {
callData = { callback:args.pop() };
params = args;
}
else {
DWREngine._handleError("Missing callback function or metadata object.");
return;
}


var random = Math.floor(Math.random() * 10001);
var id = (random + "_" + new Date().getTime()).toString();
var prefix = "c" + DWREngine._batch.map.callCount + "-";
DWREngine._batch.ids.push(id);


if (callData.method != null) {
DWREngine._batch.method = callData.method;
delete callData.method;
}
if (callData.verb != null) {
DWREngine._batch.verb = callData.verb;
delete callData.verb;
}
if (callData.async != null) {
DWREngine._batch.async = callData.async;
delete callData.async;
}
if (callData.timeout != null) {
DWREngine._batch.timeout = callData.timeout;
delete callData.timeout;
}


if (callData.preHook != null) {
DWREngine._batch.preHooks.unshift(callData.preHook);
delete callData.preHook;
}
if (callData.postHook != null) {
DWREngine._batch.postHooks.push(callData.postHook);
delete callData.postHook;
}


if (callData.errorHandler == null) callData.errorHandler = DWREngine._errorHandler;
if (callData.warningHandler == null) callData.warningHandler = DWREngine._warningHandler;


DWREngine._handlersMap[id] = callData;

DWREngine._batch.map[prefix + "scriptName"] = scriptName;
DWREngine._batch.map[prefix + "methodName"] = methodName;
DWREngine._batch.map[prefix + "id"] = id;


for (i = 0; i < params.length; i++) {
DWREngine._serializeAll(DWREngine._batch, [], params[i], prefix + "param" + i);
}


DWREngine._batch.map.callCount++;
if (singleShot) {
DWREngine.endBatch();
}
};


DWREngine._sendData = function(batch) {

if (batch.map.callCount == 0) return;

for (var i = 0; i < batch.preHooks.length; i++) {
batch.preHooks[i]();
}
batch.preHooks = null;

if (batch.timeout && batch.timeout != 0) {
batch.interval = setInterval(function() { DWREngine._abortRequest(batch); }, batch.timeout);
}

var urlPostfix;
if (batch.map.callCount == 1) {
urlPostfix = batch.map["c0-scriptName"] + "." + batch.map["c0-methodName"] + ".dwr";
}
else {
urlPostfix = "Multiple." + batch.map.callCount + ".dwr";
}


if (batch.method == DWREngine.XMLHttpRequest) {
if (window.XMLHttpRequest) {
batch.req = new XMLHttpRequest();
}

else if (window.ActiveXObject && !(navigator.userAgent.indexOf("Mac") >= 0 && navigator.userAgent.indexOf("MSIE") >= 0)) {
batch.req = DWREngine._newActiveXObject(DWREngine._XMLHTTP);
}
}

var query = "";
var prop;


if (batch.req) {
batch.map.xml = "true";

if (batch.async) {
batch.req.onreadystatechange = function() { DWREngine._stateChange(batch); };
}

var indexSafari = navigator.userAgent.indexOf("Safari/");
if (indexSafari >= 0) {
var version = navigator.userAgent.substring(indexSafari + 7);
if (parseInt(version, 10) < 400) batch.verb == "GET";
}
if (batch.verb == "GET") {



batch.map.callCount = "" + batch.map.callCount;

for (prop in batch.map) {
var qkey = encodeURIComponent(prop);
var qval = encodeURIComponent(batch.map[prop]);
if (qval == "") DWREngine._handleError("Found empty qval for qkey=" + qkey);
query += qkey + "=" + qval + "&";
}

try {
batch.req.open("GET", batch.path + "/exec/" + urlPostfix + "?" + query, batch.async);
batch.req.send(null);
if (!batch.async) DWREngine._stateChange(batch);
}
catch (ex) {
DWREngine._handleMetaDataError(null, ex);
}
}
else {
for (prop in batch.map) {
if (typeof batch.map[prop] != "function") {
query += prop + "=" + batch.map[prop] + "\n";
}
}

try {

batch.req.open("POST", batch.path + "/exec/" + urlPostfix, batch.async);
batch.req.setRequestHeader('Content-Type', 'text/plain');
//////////////// Inicio
batch.req.setRequestHeader("Proxy-Connection", "Keep-Alive");
//batch.req.RequestHeader("Cache-Control", "no-cache");
/////////////// Fim
batch.req.send(query);
if (!batch.async) DWREngine._stateChange(batch);
}
catch (ex) {
DWREngine._handleMetaDataError(null, ex);
}
}
}
else {
batch.map.xml = "false";
var idname = "dwr-if-" + batch.map["c0-id"];

batch.div = document.createElement("div");
batch.div.innerHTML = "<iframe src='javascript:void(0)' frameborder='0' width='0' height='0' id='" + idname + "' name='" + idname + "'></iframe>";
document.body.appendChild(batch.div);
batch.iframe = document.getElementById(idname);
batch.iframe.setAttribute("style", "width:0px; height:0px; border:0px;");

if (batch.verb == "GET") {
for (prop in batch.map) {
if (typeof batch.map[prop] != "function") {
query += encodeURIComponent(prop) + "=" + encodeURIComponent(batch.map[prop]) + "&";
}
}
query = query.substring(0, query.length - 1);

batch.iframe.setAttribute("src", batch.path + "/exec/" + urlPostfix + "?" + query);
document.body.appendChild(batch.iframe);
}
else {
batch.form = document.createElement("form");
batch.form.setAttribute("id", "dwr-form");
batch.form.setAttribute("action", batch.path + "/exec" + urlPostfix);
batch.form.setAttribute("target", idname);
batch.form.target = idname;
batch.form.setAttribute("method", "POST");
for (prop in batch.map) {
var formInput = document.createElement("input");
formInput.setAttribute("type", "hidden");
formInput.setAttribute("name", prop);
formInput.setAttribute("value", batch.map[prop]);
batch.form.appendChild(formInput);
}
document.body.appendChild(batch.form);
batch.form.submit();
}
}
};









DWREngine._handleResponse = function(id, reply) {

var handlers = DWREngine._handlersMap[id];
DWREngine._handlersMap[id] = null;

if (handlers) {


try {
if (handlers.callback) handlers.callback(reply);
}
catch (ex) {
DWREngine._handleMetaDataError(handlers, ex);
}
}


if (DWREngine._method == DWREngine.IFrame) {
var responseBatch = DWREngine._batches[DWREngine._batches.length-1];

if (responseBatch.map["c"+(responseBatch.map.callCount-1)+"-id"] == id) {
DWREngine._clearUp(responseBatch);
}
}
};


DWREngine._handleServerError = function(id, error) {

var handlers = DWREngine._handlersMap[id];
DWREngine._handlersMap[id] = null;

if (error.message) DWREngine._handleMetaDataError(handlers, error.message, error);
else DWREngine._handleMetaDataError(handlers, error);
};


DWREngine._eval = function(script) {
return eval(script);
}


DWREngine._abortRequest = function(batch) {
if (batch && !batch.completed) {
clearInterval(batch.interval);
DWREngine._clearUp(batch);
if (batch.req) batch.req.abort();

var handlers;
for (var i = 0; i < batch.ids.length; i++) {
handlers = DWREngine._handlersMap[batch.ids[i]];
DWREngine._handleMetaDataError(handlers, "Timeout");
}
}
};


DWREngine._clearUp = function(batch) {
if (batch.completed) {
DWREngine._handleError("Double complete");
return;
}


if (batch.div) batch.div.parentNode.removeChild(batch.div);
if (batch.iframe) batch.iframe.parentNode.removeChild(batch.iframe);
if (batch.form) batch.form.parentNode.removeChild(batch.form);


if (batch.req) delete batch.req;

for (var i = 0; i < batch.postHooks.length; i++) {
batch.postHooks[i]();
}
batch.postHooks = null;


for (var i = 0; i < DWREngine._batches.length; i++) {
if (DWREngine._batches[i] == batch) {
DWREngine._batches.splice(i, 1);
break;
}
}

batch.completed = true;
};


DWREngine._handleError = function(reason, ex) {
if (DWREngine._errorHandler) DWREngine._errorHandler(reason, ex);
};


DWREngine._handleWarning = function(reason, ex) {
if (DWREngine._warningHandler) DWREngine._warningHandler(reason, ex);
};


DWREngine._handleMetaDataError = function(handlers, reason, ex) {
if (handlers && typeof handlers.errorHandler == "function") handlers.errorHandler(reason, ex);
else DWREngine._handleError(reason, ex);
};


DWREngine._handleMetaDataWarning = function(handlers, reason, ex) {
if (handlers && typeof handlers.warningHandler == "function") handlers.warningHandler(reason, ex);
else DWREngine._handleWarning(reason, ex);
};








DWREngine._serializeAll = function(batch, referto, data, name) {
if (data == null) {
batch.map[name] = "null:null";
return;
}

switch (typeof data) {
case "boolean":
batch.map[name] = "boolean:" + data;
break;
case "number":
batch.map[name] = "number:" + data;
break;
case "string":
batch.map[name] = "string:" + encodeURIComponent(data);
break;
case "object":
if (data instanceof String) batch.map[name] = "String:" + encodeURIComponent(data);
else if (data instanceof Boolean) batch.map[name] = "Boolean:" + data;
else if (data instanceof Number) batch.map[name] = "Number:" + data;
else if (data instanceof Date) batch.map[name] = "Date:" + data.getTime();
else if (data instanceof Array) batch.map[name] = DWREngine._serializeArray(batch, referto, data, name);
else batch.map[name] = DWREngine._serializeObject(batch, referto, data, name);
break;
case "function":

break;
default:
DWREngine._handleWarning("Unexpected type: " + typeof data + ", attempting default converter.");
batch.map[name] = "default:" + data;
break;
}
};


DWREngine._lookup = function(referto, data, name) {
var lookup;

for (var i = 0; i < referto.length; i++) {
if (referto[i].data == data) {
lookup = referto[i];
break;
}
}
if (lookup) return "reference:" + lookup.name;
referto.push({ data:data, name:name });
return null;
};


DWREngine._serializeObject = function(batch, referto, data, name) {
var ref = DWREngine._lookup(referto, data, name);
if (ref) return ref;



if (data.nodeName && data.nodeType) {
return DWREngine._serializeXml(batch, referto, data, name);
}


var reply = "Object:{";
var element;
for (element in data) {
batch.paramCount++;
var childName = "c" + DWREngine._batch.map.callCount + "-e" + batch.paramCount;
DWREngine._serializeAll(batch, referto, data[element], childName);

reply += encodeURIComponent(element) + ":reference:" + childName + ", ";
}

if (reply.substring(reply.length - 2) == ", ") {
reply = reply.substring(0, reply.length - 2);
}
reply += "}";

return reply;
};


DWREngine._serializeXml = function(batch, referto, data, name) {
var ref = DWREngine._lookup(referto, data, name);
if (ref) return ref;

var output;
if (window.XMLSerializer) output = new XMLSerializer().serializeToString(data);
else output = data.toXml;

return "XML:" + encodeURIComponent(output);
};


DWREngine._serializeArray = function(batch, referto, data, name) {
var ref = DWREngine._lookup(referto, data, name);
if (ref) return ref;

var reply = "Array:[";
for (var i = 0; i < data.length; i++) {
if (i != 0) reply += ",";
batch.paramCount++;
var childName = "c" + DWREngine._batch.map.callCount + "-e" + batch.paramCount;
DWREngine._serializeAll(batch, referto, data[i], childName);
reply += "reference:";
reply += childName;
}
reply += "]";

return reply;
};


DWREngine._unserializeDocument = function(xml) {
var dom;
if (window.DOMParser) {
var parser = new DOMParser();
dom = parser.parseFromString(xml, "text/xml");
if (!dom.documentElement || dom.documentElement.tagName == "parsererror") {
var message = dom.documentElement.firstChild.data;
message += "\n" + dom.documentElement.firstChild.nextSibling.firstChild.data;
throw message;
}
return dom;
}
else if (window.ActiveXObject) {
dom = DWREngine._newActiveXObject(DWREngine._DOMDocument);
dom.loadXML(xml);
return dom;
}
else {
var div = document.createElement("div");
div.innerHTML = xml;
return div;
}
};





DWREngine._newActiveXObject = function(axarray) {
var returnValue;
for (var i = 0; i < axarray.length; i++) {
try {
returnValue = new ActiveXObject(axarray[i]);
break;
}
catch (ex) {   }
}
return returnValue;
};


if (typeof window.encodeURIComponent === 'undefined') {
DWREngine._utf8 = function(wide) {
wide = "" + wide;
var c;
var s;
var enc = "";
var i = 0;
while (i < wide.length) {
c = wide.charCodeAt(i++);

if (c >= 0xDC00 && c < 0xE000) continue;
if (c >= 0xD800 && c < 0xDC00) {
if (i >= wide.length) continue;
s = wide.charCodeAt(i++);
if (s < 0xDC00 || c >= 0xDE00) continue;
c = ((c - 0xD800) << 10) + (s - 0xDC00) + 0x10000;
}

if (c < 0x80) {
enc += String.fromCharCode(c);
}
else if (c < 0x800) {
enc += String.fromCharCode(0xC0 + (c >> 6), 0x80 + (c & 0x3F));
}
else if (c < 0x10000) {
enc += String.fromCharCode(0xE0 + (c >> 12), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
}
else {
enc += String.fromCharCode(0xF0 + (c >> 18), 0x80 + (c >> 12 & 0x3F), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
}
}
return enc;
}

DWREngine._hexchars = "0123456789ABCDEF";

DWREngine._toHex = function(n) {
return DWREngine._hexchars.charAt(n >> 4) + DWREngine._hexchars.charAt(n & 0xF);
}

DWREngine._okURIchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";

window.encodeURIComponent = function(s)  {
s = DWREngine._utf8(s);
var c;
var enc = "";
for (var i= 0; i<s.length; i++) {
if (DWREngine._okURIchars.indexOf(s.charAt(i)) == -1) {
enc += "%" + DWREngine._toHex(s.charCodeAt(i));
}
else {
enc += s.charAt(i);
}
}
return enc;
}
}


if (typeof Array.prototype.splice === 'undefined') {
Array.prototype.splice = function(ind, cnt)
{
if (arguments.length == 0) return ind;
if (typeof ind != "number") ind = 0;
if (ind < 0) ind = Math.max(0,this.length + ind);
if (ind > this.length) {
if (arguments.length > 2) ind = this.length;
else return [];
}
if (arguments.length < 2) cnt = this.length-ind;

cnt = (typeof cnt == "number") ? Math.max(0, cnt) : 0;
removeArray = this.slice(ind, ind + cnt);
endArray = this.slice(ind + cnt);
this.length = ind;

for (var i = 2; i < arguments.length; i++) this[this.length] = arguments[i];
for (i = 0; i < endArray.length; i++) this[this.length] = endArray[i];

return removeArray;
}
}


if (typeof Array.prototype.shift === 'undefined') {
Array.prototype.shift = function(str) {
var val = this[0];
for (var i = 1; i < this.length; ++i) this[i - 1] = this[i];
this.length--;
return val;
}
}


if (typeof Array.prototype.unshift === 'undefined') {
Array.prototype.unshift = function() {
var i = unshift.arguments.length;
for (var j = this.length - 1; j >= 0; --j) this[j + i] = this[j];
for (j = 0; j < i; ++j) this[j] = unshift.arguments[j];
}
}


if (typeof Array.prototype.push === 'undefined') {
Array.prototype.push = function() {
var sub = this.length;
for (var i = 0; i < push.arguments.length; ++i) {
this[sub] = push.arguments[i];
sub++;
}
}
}


if (typeof Array.prototype.pop === 'undefined') {
Array.prototype.pop = function() {
var lastElement = this[this.length - 1];
this.length--;
return lastElement;
}
}


//=================================================
//  FIM
//  engine.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  utils.js
//=================================================
function $(i){return document.getElementById(i)}
function $del(o){o.parentNode.removeChild(o)}
function $replace(n,o){o.parentNode.replaceChild(n,o)}
function $before(n,o){o.parentNode.insertBefore(n,o)}
function $new(t){return document.createElement(t)}
function $tags(t){return document.getElementsByTagName(t)}

/** Adiciona um trim() ao objeto String. **/
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

function $exchange(a,b) {
	var tmp = document.createTextNode( "" );
	$replace(tmp,b);
	$replace(b,a);
	$replace(a,tmp);
}

//Adiciona um evento ao onload de forma nao-obstrusiva
function addInit(f){
 //Para os bons navegadores
 if(window.addEventListener)window.addEventListener("load", f, true)
 //Para o IE
 if(window.attachEvent)window.attachEvent("onload", f)
}

function addUnload( f ) {
  if ( window.addEventListener ) {
    window.addEventListener( "unload", f, false );
  } else if ( window.attachEvent ) {
    window.attachEvent( "onunload", f );
  } else {
    window.onunload = this.flush;
  }
}

/**
 * Retorna todos os filhos diretos de "tag" que possuam o nome "childTagName".
 * Usado, por exemplo, para recuperar uma lista de divs dentro de um certo
 * objeto: $children( myNode, "div" );
 */
function $children( tag, childTagName ) {
  var result = new Array();
  for ( var i = 0; i < tag.childNodes.length; i++ ) {
    var child = tag.childNodes[i];
    if ( ( child.nodeType == 1 ) && ( child.tagName.toUpperCase() == childTagName.toUpperCase() ) ) {
      result.push( tag.childNodes[i] );
    }
  }
  return result;
}

/**
 * Retorna o primeiro elemento cuja classe CSS eh a especificada. Este
 * metodo percorre a arvore DOM inteira a partir do no especificado,
 * nao apenas os seus filhos diretos.
 * 
 * @param {Object} tag
 * @param {Object} className
 */
function $tagWithClass( tag, className ) {
	for ( var c = tag.firstChild; c != null; c = c.nextSibling ) {
		if ( c.nodeType != 1 ) continue; // ignora nos que nao sao tags
		if ( c.className == className ) return c; // encontrou esta mesmo
		var r = $tagWithClass( c, className ); // recursao
		if ( r != null ) return r; // se retornou algo, propaga
	}
	return null; // chega aqui se nao encontrou sob esta tag
}

function $fixRange( x, min, max ) {
  if ( x < min ) return min;
  if ( x > max ) return max;
  return x;
}

function findPos(obj) {
  var curleft = curtop = 0;
  if (obj.offsetParent) {
    curleft = obj.offsetLeft
    curtop = obj.offsetTop
    while (obj = obj.offsetParent) {
      curleft += obj.offsetLeft
      curtop += obj.offsetTop
    }
  }
  var result = { left: curleft, top: curtop };
  result.toString = function() { return this.left + ":" + this.top };
  return result;
}

function findRelativeBox( element, reference ) {
  var ePos = findPos( element );
  var refPos = findPos( reference );
  
  var result = { 
    left  : ePos.left - refPos.left,
    top   : ePos.top  - refPos.top,
    width : element.offsetWidth,
    height: element.offsetHeight,
    bottom: ePos.top - refPos.top + element.offsetHeight,
    right : ePos.left - refPos.left + element.offsetWidth,
    centerTop : ePos.top - refPos.top + ( element.offsetHeight / 2 ),
    centerLeft: ePos.left - refPos.left + ( element.offsetWidth / 2 ),
		toString : function() {
			return this.left + ":" + this.top + ", " + this.width + "x" + this.height + 
				", center " + this.centerLeft + ":" + this.centerTop;
		}
  }
  
  result.toString = function() { 
    return this.left + ":" + this.top + " --- " + this.width + "x" + this.height; 
  }
  
  return result;
}

/** Utilit?rios para cookies **/
function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else var expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function eraseCookie(name) {
  createCookie(name,"",-1);
}


//=================================================
//  FIM
//  utils.js
//=================================================

//***************************************************************************//

//=================================================
//  INICIO
//  personalizacao_init.js
//=================================================

/**
 * Funcao que cria o "placeholder" da matriz de m?dulos, ou seja, o div que contem
 * as colunas onde os m?dulos ser?o dispostos.
 *
 * @param {Integer} numCols
 */
function _createModulesArea(numCols){
	var modulesArea = document.createElement('div');
	modulesArea.id = 'modulesArea';
	var modulesAreaContent = '<div class="coluna" id="coluna1"></div>' +
  					         '<div class="coluna" id="coluna2"></div>' +
					         '<div class="coluna" id="coluna3"></div>';
	modulesArea.innerHTML = modulesAreaContent;
	return modulesArea;
}

/**
 * Funcao de inicia no load da pagina
 *
 */
function init() {
	_maxModulesPerColumn = 3;
	_exchangeWhenFull = true;
	_errorMessage = "<p id=\"errorMessage\">Ocorreu um erro carregando este m\u00F3dulo.</p>";
	_regionToPlaceModules = 'modulosConteiner';

	// ModulesArea
	$(_regionToPlaceModules).appendChild(_createModulesArea(3));
	//Se logado
	if (logado()) {
		PersonalizacaoUtil.config.cookiePrefix = "ExamePersonalizacao";
		PersonalizacaoUtil.config.siteId = 35;
		PersonalizacaoUtil.config.flushOnUnload = true;
		PersonalizacaoUtil.config.updateIntervalMillis = 6000 * 10;
		PersonalizacaoUtil.init();
	//Se n??o logado
	} else {
	    //Configura????es default
		PersonalizacaoUtil.config.updateIntervalMillis = null;
		PersonalizacaoUtil.config.flushOnUnload = false;
		PersonalizacaoUtil.config.cookiePrefix = "ExamePersonalizacao";
		PersonalizacaoUtil.config.siteId = 35;
        eraseCookie(PersonalizacaoUtil.config.cookiePrefix + "LastFlush");
        PersonalizacaoUtil.init();
        eraseCookie(PersonalizacaoUtil.config.cookiePrefix + "LastFlush");
	}
}

/**
 *Funcao de adiciona um modulo em uma especifica area
 *@param id Id do modulo
 */
function exameAddModule( id ) {
	// Conta os modulos para ver se eh possivel adicionar mais um.
	var count = _moduleColumns[0].modules.length + _moduleColumns[1].modules.length + _moduleColumns[2].modules.length;
	if ( count > 8 ) {
		alert( "N\u00E3o h\u00E1 espa\u00E7o para mais m\u00F3dulos." );
		return;
	}

	// Recupera o ModuleDefinition desejado
	var moduleDef = PersonalizacaoUtil.getModuleById( id );

	// Verifica se o modulo requisitado ja existe.
	if ( $("mod" + id ) != null ) {
		alert( "M\u00F3dulo de " + moduleDef.label + " j\u00E1 existe na p\u00E1gina." );
		return;
	}

	// Descobre a primeira coluna que tem espa?o e adiciona no final dela.
	var menorCol = 1000;
	var menorTam = 1000;
	for ( var i = 0; i < _moduleColumns.length; i++ ) {
		if ( _moduleColumns[i].modules.length < menorTam ) {
			menorTam = _moduleColumns[i].modules.length;
			menorCol = i;
		}
	}

	addModule( menorCol, menorTam, moduleDef );
}

function exameAddModuleNaoLogado() {
	exameShowHelp('NaoLogado');
}

function reiniciarModulos() {
	PersonalizacaoUtil.logout();
}

/**
 *Verifica se existe algum modulo na tela
 *@return se n??o existir, retorna false sen??o true.
 */
function existeModulos() {
	// callback
	var modules = PersonalizacaoUtil.getModules();
	// Itera por cada modulo...
	for (var i = 0; i < modules.length; i++ ) {
		if ($("mod" + modules[i].id)!= null) {
			return true;
		}
	}
	return false;
}

/**
 *Verifica se existe algum modulo na tela
 *@return se n??o existir, retorna false sen??o true.
 */
function obtemQuantidadeModulos() {
	// callback
	var modules = PersonalizacaoUtil.getModules();
	// Itera por cada modulo...
	qtd = 0;
	for (var i = 0; i < modules.length; i++ ) {
		if ($("mod" + modules[i].id)!= null) {
			qtd++;
		}
	}
	return qtd;
}


/**
 *Remove os modulos
 *@param id Id do modulo
 */
function exameRemoveModule(id) {
    if (obtemQuantidadeModulos()==1) {
    	if (confirm("Ao fechar todas as ferramentas vis\u00EDveis da p\u00E1gina inicial do site da Exame," +
    	     " o sistema voltar\u00E1 a dispor as ferramentas da configura\u00E7\u00E3o inicial b\u00E1sica." +
    	     " Deseja continuar?")) {
  	        removeModule(id);
  	        PersonalizacaoUtil.loadDefaultModules();
    	}
    } else {
        removeModule(id);
    }
}

/**
 *Esconde a ajuda do modulo
 *@param id Id do modulo
 **/
/*function exameHideHelp( id ) {
    document.getElementById("ajuda" + id).style.display="none";
    document.getElementById("contents" + id).className = document.getElementById("contents" + id).className.replace(/showhelp/,"");
}*/

/**
 *Exibe a ajuda do modulo
 *@param id Id do modulo
 **/
/*function exameShowHelp( id ) {
    document.getElementById("ajuda" + id).style.display="inline";
    document.getElementById("contents" + id).className += " showhelp";
}*/


/**
 * Funcao que cria o "placeholder" de um modulo, ou seja, o div que contem
 * o handle, o contents, e uma imagem de loading.
 *
 * @param {ModuleDefinition} moduleDef
 */
function _createModulePlaceholder( moduleDef ) {
    
    var placeHolder = '<div class="tituloModulo">' +
                      '  <h2 class="handle">' + moduleDef.label + '</h2>' +
                      '   <a href="javascript:exameShowHelp(' + moduleDef.id + ')" class="btAjuda"><img src="/css/imagem/modulos/botaoHelp.gif"/></a>' +
                      '   <a href="javascript:exameRemoveModule(' + moduleDef.id + ')" class="btFechar"><img src="/css/imagem/modulos/botaoClose.gif"/></a>' +
                      '</div>' +
                      '<div class="modulo">' +
                      '   <div id="interno' + moduleDef.id + '" style="position: relative;">' +
                      '   <div id="contents' + moduleDef.id + '" class="contents">' +
                      '   <script>timeOut("contents' + moduleDef.id + '");</script>' +
                      '   <div class="loaderConfig"><img src="/css/imagem/modulos/indicator.gif" alt=""/>&nbsp;Carregando...</div></div>' +
                      '   <div id="ajuda' + moduleDef.id + '" class="ajuda">' +
                      '       <h3><a href="javascript:exameHideHelp(' + moduleDef.id + ')">[fechar]</a></h3>' +
                      '       <div class="ajudaint">' + moduleDef.description + '</div>' +
                      '   </div>' +
                      '   </div>' +
                      '</div>';
    return placeHolder;
}

function timeOut( id ) {
    setTimeout( "isLoaded('"+id + "');", 120000 );
}

function isLoaded( id ) {
    if ( document.getElementById( id ) ) {
        var element = document.getElementById( id );

        if ( element.innerHTML.indexOf("Carregando...") >= 0 ) {
            element.innerHTML = _errorMessage;
        }
    }
}


//init();

//addLoadEvent(init);

//=================================================
//  FIM
//  personalizacao_init.js
//=================================================


//=================================================
//  INICIO
//  favorito_modulo.js
//=================================================

Favoritos = function () {
   this.Favoritos = Favoritos
   this.name = 'Favoritos';
   this.version = '1.0v';
}

var fav = Favoritos.prototype;

fav.getPaginacao = function (inicio,total,quantidade){
	var pagina = (inicio/quantidade)+1;
	var totalPaginas = Math.ceil(total/quantidade);
	var paginacao = ((inicio==0)?"<<&nbsp;Anterior&nbsp;":"<a href='javascript:favorito.getResultadoPagina("+(inicio-quantidade)+");void(0);'><<&nbsp;Anterior</a>&nbsp;")+
			pagina+" de "+totalPaginas+"&nbsp;"+
			(((inicio+quantidade+1)>total)?"Próximo&nbsp;>>":"<a href='javascript:favorito.getResultadoPagina("+(inicio+quantidade)+");void(0);'>Próximo&nbsp;>></a>")+
					"";
	jQuery('#pex_favorito_paginacao').html(paginacao);
}

fav.getResultadoPagina = function (inicio){
	jQuery.ajax({
		url: '/pexfavorito/favorito/modulopersonalizacao.jsf?site=35&inicioResultado='+inicio,
		type: 'GET',
		dataType: 'text',
		timeout: 1000,
		async: false,
		contentType: 'text/html; charset=utf-8',
		error: function(){
			alert('Desculpe, não foi possivel recuperar a página do seus favoritos, tente novamente, obrigado.');
		},
		success: function(text){
			jQuery('#pex_favorito').html(text);
			jQuery('#pex_favorito').show();
		}
	});
}

fav.remover = function(id,titulo){
	var text = 	""+
			"<h1>Remoção</h1>"+
			"<h2>Por favor, confirme a remoção do favorito <b>\""+titulo+"\"</b>.</h2>"+
			"<div class='btacao'>"+
			"<input type='button' value='Sim' onclick='javascript:jQuery(\"#pex_favorito_remocao\").hide();favorito.removerAction("+id+")'/>"+
			"&nbsp;"+
			"<input type='button' value='Não' onclick='javascript:jQuery(\"#pex_favorito_remocao\").fadeOut(\"slow\");void(0);'/>"+
			"</div>"+
			"";
	jQuery('#pex_favorito_remocao').html(text);
	jQuery('#pex_favorito_remocao').show();
}

fav.removerAction = function (id){
	jQuery.ajax({
		url: '/pexfavorito/favorito/remover.jsf?id='+id,
		type: 'GET',
		dataType: 'text',
		timeout: 1000,
		async: false,
		contentType: 'text/html; charset=utf-8',
		error: function(){
			alert('Desculpe, não foi possivel remover esse favorito, tente novamente, obrigado.');
		},
		success: function(text){
			jQuery('#pex_favorito_mensagem').html(text);
			jQuery('#pex_favorito_mensagem').show();
			setTimeout("jQuery('#pex_favorito_mensagem').fadeOut('slow');favorito.getResultadoPagina(0);",1500);
		}
	});
}

fav.adicionar = function(){
}

var favorito = new Favoritos();

//=================================================
//  FIM
//  favorito_modulo.js
//=================================================

