// fold < creditos & copyright >
/* +++++++ CREDITOS & COPYRIGHT +++++++ 

   Funções de Javascript para controlar o interface de Front-End do projecto Millions Wheels [www.millionswheels.com]
   Criadas e adaptadas por alvaro Saraiva @ glups.pt @ julho 2007
   Update por alvaro Saraiva @ glups.pt @ julho 2007
   
   Glups - Atelier de Novas Tecnologias, Lda
   Rua Jaime Campos, Bloco D, Piso 3 Esq., 5000-431 Vila Real | Portugal
   Tel. [351] 259 322 183 | E-mail: info@glups.pt | URL: www.glups.pt

   Se utilizarem estas funções para os vossos trabalhos,
   a Glups agradece que ao menos no retirem estas linhas de cdigo,
   por respeito e agradecimento ao trabalho das pessoas que a criaram
   e ao trabalho que vocs pouparam. Keep Cool. Peace ;)

*/

// endfold

// fold < notas >
/*	Notas:
	- Esta classe serve para controlar a apresentação de parte do interface do portal.
	- É responsável por receber pedidos do front-end (navegação, chamadas aos scripts via AJAX e receber respostas do AJAX;
	- Usa classes/métodos da superClasse Prototype.js
*/
// endfold


/*	+++++++++++++++++++++++++++++++++++++++++++++++
				CRIAÇÃO DA CLASSE 
	+++++++++++++++++++++++++++++++++++++++++++++++*/

// criamos uma variavel para representar a classe
var coreTmpl = Class.create();

/*
*	@desc			Método 'prototype' da classe coreTmpl que define quais os métodos que torna público e disponíveis 
*					a quem instanciar esta classe
*	@retutn void
*/
coreTmpl.prototype = {
	
	/*
	*	@desc			Método constructor 'prototype' da classe coreTmpl
	*					Define logo por defeito algumas variáveis privadas da classe
	*	@param string	nomeCanal: nome do canal onde estamos a executar a classe
	*	@param string	idioma: código do idioma do user, qd se inicializa a clase
	*	@retutn void
	*/
	initialize: function(canal,idioma){ 
		this.canalDefault		= canalDefault;
		this.urlBase			= urlBaseSite;
		this.srcImgPreloader	= srcImgPreloader;
		this.setNomeCanal(canal);
		this.setIdioma(idioma);
		this.tools				= this._initTools();
	},
	
	/*	++++++++++++++++++++++++++++++++++++++++++++++++++++
				SETTERS E GETTERS DE CONFIGS DA CLASSE 
		++++++++++++++++++++++++++++++++++++++++++++++++++++ */
	
	/*
	*	@desc			Método para setar o nome do canal em que estamos na variável da classe 'canal'
	*					Caso venha vazia, coloca o canal por defeito que é a homepage
	*	@param string	nomeCanal
	*	@return void
	*/
	setNomeCanal: function(nomeCanal){
		this.canal = (nomeCanal.length >0) ? nomeCanal : canalDefault;	
	},
	
	/*
	*	@desc			Método para devolver o nome do canal em que estamos
	*	@return string	nomeCanal
	*/
	getNomeCanal: function(){
		return this.canal;	
	},
		
	/*
	*	@desc			Método para setar o código do idioma em que estamos
	*					Caso venha vazia, coloca o idioma por defeito que é 'PT'
	*	@param string	idioma
	*	@return void
	*/
	setIdioma: function(idioma){
		this.idioma = (idioma.length >0) ? idioma : idiomaDefault;	
	},
	
	/*
	*	@desc			Método para devolver o codigo do idioma em que estamos
	*	@return string	idioma
	*/
	getIdioma: function(){
		return this.idioma;	
	},
	
	/*
	*	@desc			Método instanciar a classe _coreTools.js
	*	@return object	Devolve ums instância da classe Tools
	*/
	_initTools: function(){
		return new coreTools();
	},
	
	/*
	*	@desc			Método para validar o formulario da pesquisa no tmpl global
	*	@return mixed	Ou devolve boolean (falso) caso esteja vazio o campo, ou submete o formulario
	*/
	_pesquisarTopo: function(){
		if (verificarCampos('alert','_pesquisaInput','R','Palavra para Pesquisar')){
			var palavra = $('_pesquisaInput').value;
			$('pesquisaTopo').action += '&gwf_pesquisa='+ palavra;
			$('pesquisaTopo').submit();
		}
		return false;
	},
	
	/*
	*	@desc			Método para validar o formulario de inscricao nas Newsletters no tmpl global HTML
	*	@return mixed	Ou devolve boolean (falso) caso esteja vazio o campo, ou submete o formulario
	*/
	_inscreverNewsletter: function(){
		tmpl.tools._limpaCampo('nome','Insira nome');
		tmpl.tools._limpaCampo('mail','Insira e-mail');
		if (verificarCampos('alert',
							'nome','R','Nome',
							'mail','RisEmail','Endereço de E-mail',
							'data_nascimento','isData','Data de Nascimento',
							'telefone','isContacto','Telefone',
							'site','isURL','Site'
							)){
			$('registoNewsletters').submit();
		}
		return false;
	},
	
	/*
	*	@desc			Método para fazer a verificacao do login dos utilizadores no site/fórum
	*	@return mixed	Ou devolve boolean (falso) caso esteja vazio o campo, ou submete o formulario
	*/
	loginUtilizadores: function(){
		if (verificarCampos('alert','navbar_username','R','Utilizador','vb_login_password','R','Password')){
			// de acordo com o controlo do login no vBulletin
			if (navigator.userAgent.indexOf("Mozilla/") == 0 && parseInt(navigator.appVersion) >= 4){
				var vb_login_password = $('vb_login_password');
				var vb_login_md5password = $('vb_login_md5password');
				var vb_login_md5password_utf = $('vb_login_md5password_utf');
				md5hash(vb_login_password,vb_login_md5password,vb_login_md5password_utf);
			}
			document.loginUsers.submit();
		}
	},
	
	/*
	*	@desc			Método para fazer o logout dos users
	*	@return boollean	Devolve true caso ele faça logout, ou false, caso ele cancele
	*/
	logOutUtilizadores: function(){
		//ht = $("html");
		ht = document.getElementsByTagName('html');
		ht[0].style.filter = "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
		if (confirm('Tem a certeza que deseja efectuar o Logout?')){
			return true;
		}
		else{
			ht[0].style.filter = "";
			return false;
		}
	},
	
	/*	++++++++++++++++++++++++++++++++++++++++++++++++++++
		  MÉTODOS PARA TRABALHAR COM DIVS E O SCRIPTACULOUS 
		++++++++++++++++++++++++++++++++++++++++++++++++++++ */
	
	/*
	* @desc					Metodo publico que permite expandir e mostrar uma série de DIvs no template
	*						Muda ainda o texto da Label de acordo com a acção que efectuou
	*						Para que funcione, ele verifica a accão pelo sinal '+', que deve estar por defeito no texto da Label
	* @param array			objArray: Array com os Divs para manipular
	* @param array			camposArray: Array com os Divs com o titulos para manipular
	* @param String 		txtLabel: Div com a Label de texto para alterar
	* @return void
	*/
	mostraEscondeTudo: function(objArray,camposArray,txtLabel){
		campoTxt	= $(txtLabel);
		accao 		= (campoTxt.innerHTML.indexOf('+')==-1) ? 'esconder' : 'mostrar';
		// mandamos abrir ou fechar os Divs
		this.fechaDivs(objArray,camposArray);
		// trocamos o texto
		switch(accao){
			case 'esconder':
				campoTxt.innerHTML = 'Expandir Tudo [+]';
			break;
			case 'mostrar':
				campoTxt.innerHTML = 'Esconder Tudo [-]';
			break;
		}
	},
	
	/*
	* @desc					Metodo que serve de handler para fechar todos os divs duma página, qd ela arranca, e usa o mostraDiv pra tratar do assunto
	* @param Array			objArray: array com os id's dos objectos para fechar ;)
	* @return Void
	*/
	fechaDivs: function(objArray,camposArray){
		for(var i=0; i < objArray.length; i++){
			var obj = $(objArray[i]);
			if(obj != undefined){
				obj.estado = true;
				this.slideDiv(obj.id,camposArray[i])
			}
		}
	},
	
	/*
	* @desc					Metodo que serve de handler para tornar invisíveis um array de objectos
	* @param Array			objArray: array com os id's dos objectos para fechar ;)
	* @return Void
	*/
	escondeDivs: function(objArray){
		for(var i=0; i < objArray.length; i++){
			var obj = $(objArray[i]);
			if(obj != undefined){
				$(obj).hide();
				obj.aberto = false;
			}
		}
	},

	/*
	* @desc					Método que serve de handler todas as funções que queiram alterar a visibilidade de divs com slides
	* @param string			objNome: nome do objecto para 'slidar' ;)
	* @param string			btnImg: nome da label de texto ou imagem para alterar ;)
	* @return Void
	*/
	slideDiv: function(nomeDiv,nomeLabel){
		//alert(arguments.length);
		var obj = $(nomeDiv);
		var tipoCampo;
		var campoObj = $(nomeLabel);
		//alert(typeof($(nomeLabel)));
		
		if(nomeLabel!='' && nomeLabel != undefined){
			if(campoObj.src){	
				tipoCampo = 'img'; 
				var caminhoImgs = (campoObj != undefined) ? campoObj.src.substring(0,campoObj.src.lastIndexOf('/')+1) : null ;
			}
			else if(campoObj.innerHTML != undefined){	
				tipoCampo = 'txtLabel';
				txtLabel_Original = campoObj.innerHTML;
				if(txtLabel_Original.indexOf('[+]')!=-1){
					regra = new RegExp("(\\[\\+\\])");	// sempre que se usa uma expressão com o obj de regExp, tem que se escapar com 2 \\ os caracteres textuais que queremos verificar
					//regra = /(\[\+\])/;
					txtLabel = txtLabel_Original.replace(regra, '[-]');
				}
				else if(txtLabel_Original.indexOf('[-]')!=-1){
					regra = new RegExp("(\\[-\\])");
					txtLabel = txtLabel_Original.replace(regra, '[+]');
				}
				else{	txtLabel = txtLabel_Original; }
			}
		}
		
		obj.aberto = (obj.aberto == undefined || obj.aberto == true) ? true : false ;
		if(!obj.aberto){		
			Effect.SlideDown(obj, {duration:.50});
			if(tipoCampo != undefined){
				switch(tipoCampo){
					case 'img':
						//campoObj.src = caminhoImgs + 'tmpl_admin_fundotd_erro_btn_fechar.gif';
					break;
					case 'txtLabel':
						campoObj.innerHTML = txtLabel;
					break;
					default:
					
					break;
				}
			}	
		}
		else{						
			Effect.SlideUp(obj,{duration:.48});			
			if(tipoCampo != undefined){
				switch(tipoCampo){
					case 'img':
						//campoObj.src = caminhoImgs + 'tmpl_admin_fundotd_erro_btn_abrir.gif';
					break;
					case 'txtLabel':
						campoObj.innerHTML = txtLabel;
					break;
					default:
					
					break;
				}
			}
		}
		obj.aberto = !obj.aberto;
	},
	
	/*
	* 	@desc			Objecto/Método que esconde os divs
	*
	* 	@param string	divEliminar: o id do div para eliminar
	* 	@return Void
	*/
	escondeDiv: function(divEsconder,efeitoClass){
		if($(divEsconder)!=null){
			switch(efeitoClass){
				case 'SlideUp':
					Effect.SlideUp(divEsconder,{duration:.48, afterFinish: tmpl.eliminaDiv});
				break;
				case 'SwitchOff':
					Effect.SwitchOff(divEsconder,{duration:.48, afterFinish: callback});
				break;
			}
		}
	},
	
	/*
	* 	@desc			Objecto/Método que elimina os divs
	*
	* 	@param string	divEliminar: o id do div para eliminar
	* 	@return Void
	*/
	eliminaDiv: function(divEliminar){
		if($(divEliminar)!=null){
			new Element.remove($(divEliminar.element.id));
		}
	},
	
	/*	++++++++++++++++++++++++++++++++++++++++++++++++++++
		     MÉTODOS PARA CHAMAR BANNERS DE PUBLICIDADE 
		++++++++++++++++++++++++++++++++++++++++++++++++++++ */
	
	/*
	* 	@desc			Objecto/Método que devolve o código invocado para chamar 
	*					os banners do divulgar para users COM javascript activo
	*
	* 	@param number	O id da zona para devolver o anúncio
	* 	@param number	se NÃO for permitido meter campanhas 2X no mesmo template, colocar 1, senão deixar vazio
	* 	@return Void
	*/
	getBanner: function(zona_id,campanhas_diferentes){
		
		var m3_u = (location.protocol=='https:'?'https://www.divulgar.net/ads/www/delivery/ajs.php':'http://www.divulgar.net/ads/www/delivery/ajs.php');
		var m3_r = Math.floor(Math.random()*99999999999);
		if (!document.MAX_used) document.MAX_used = ',';
		
		var codigo_banner = "<scr"+"ipt type='text/javascript' src='"+m3_u;
		codigo_banner += "?zoneid="+zona_id+"&amp;target=_blank";
		codigo_banner += (campanhas_diferentes==1) ? "&amp;blockcampaign=1" : "";
		codigo_banner += "&amp;cb=" + m3_r;
		codigo_banner += (document.MAX_used != ',') ? "&amp;exclude=" + document.MAX_used : "";
		codigo_banner += "&amp;loc=" + escape(window.location);
		codigo_banner += (document.referrer) ? "&amp;referer=" + escape(document.referrer) : "";
		codigo_banner += (document.context) ? "&context=" + escape(document.context) : "";
		codigo_banner += (document.mmm_fo) ? "&amp;mmm_fo=1" : "";
		codigo_banner += "'><\/scr"+"ipt>";
		
		//alert(codigo_banner);
		return codigo_banner;
	},
	
	/*	++++++++++++++++++++++++++++++++++++++++++++++++++++
		  MÉTODOS PARA ACTIVAR O FLASH DE FORMA AUTOMÁTICA 
		++++++++++++++++++++++++++++++++++++++++++++++++++++ */
	
	/*
	*	Readme: Conjunto de funcoes criadas pela equipa da Adobe para contornar o problema do IE 
	*			Copyright 2006 Adobe Systems, Inc. All rights reserved.		// v1.0
	*/

	/*
	* @desc 			Metodo que é chamado pelo template de HTML para escrever o codigo para um SWF ou Director no HTML
	*					Alterei o nome desta função para uma coisa mais pt ;)
	* @return Void
	*/
	activaFlash: function(){
	  var ret = 
		this._AC_GetArgs
		(  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
		 , "application/x-shockwave-flash"
		);
	  this._AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
	},
	
	/* 
	* @desc 			Metodo 'handler' para determinar o nome de um ficheiro com as respectiva extensão
	* @param String 	src: Nome do ficheiro para carregar
	* @param String 	ext: Extensão do ficheiro para carregar
	* @return String 	O nome do ficheiro completo já com a extensão e algumas query strings que traga no texto
	*/
	_AC_AddExtension:function(src, ext){
	  if (src.indexOf('?') != -1)
		return src.replace(/\?/, ext+'?'); 
	  else
		return src + ext;
	},

	/*
	* @desc				Metodo 'handler' que gera o HTML referente ao obj de falsh e faz o document.write no documento de HTML
	* @param Array 		objAttrs: Atributos do parametro object
	* @param Array 		params: Parametros do objecto
	* @param Array 		embedAttrs: Atributos para o objecto embed
	* @retun Void 		Escreve no documento o HTML
	*/
	_AC_Generateobj: function(objAttrs, params, embedAttrs){ 
	  var str = '<object ';
	  for (var i in objAttrs)
		str += i + '="' + objAttrs[i] + '" ';
	  str += '>';
	  for (var i in params)
		str += '<param name="' + i + '" value="' + params[i] + '" /> ';
	  str += '<embed ';
	  for (var i in embedAttrs)
		str += i + '="' + embedAttrs[i] + '" ';
	  str += ' ></embed></object>';
	  //alert(str);
	  document.write(str);
	},

	/*
	* @desc 			Metodo 'handler' que é chamado para determinar os parametros de um src (Director)
	* @return Void
	*/
	_AC_SW_RunContent: function(){
	  var ret = 
		this._AC_GetArgs
		(  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
		 , null
		);
	  this._AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
	},

	/*
	* @desc				Metodo 'handler' que é chamado para determinar os parametros de um swf (Flash)
	*					Devolve um objecto. Ver mais no return deste método
	* @param Array 		arg: Atributos do object que vem do HTML
	* @param String 	ext: Extensão do Ficheiro
	* @param String 	srcParamName: tipo de objecto. Normalmente é 'movie'
	* @param String 	classid: Id da classe para o plugin. Normalmente é 'clsid:166B1BCA-3F9C-11CF-8075-444553540000'
	* @param String 	mimeType: Normalmente é 'application/x-shockwave-flash'
	* @retun Array 		Devolve um Objecto com as props do Flash em 3 elementos: embedAttrs, params e objAttrs
	*/
	_AC_GetArgs: function(args, ext, srcParamName, classid, mimeType){
	  var ret = new Object();
	  ret.embedAttrs = new Object();
	  ret.params = new Object();
	  ret.objAttrs = new Object();
	  for (var i=0; i < args.length; i=i+2){
		var currArg = args[i].toLowerCase();    

		switch (currArg){	
		  case "classid":
			break;
		  case "pluginspage":
			ret.embedAttrs[args[i]] = args[i+1];
			break;
		  case "src":
		  case "movie":	
			args[i+1] = this._AC_AddExtension(args[i+1], ext);
			ret.embedAttrs["src"] = args[i+1];
			ret.params[srcParamName] = args[i+1];
			break;
		  case "onafterupdate":
		  case "onbeforeupdate":
		  case "onblur":
		  case "oncellchange":
		  case "onclick":
		  case "ondblClick":
		  case "ondrag":
		  case "ondragend":
		  case "ondragenter":
		  case "ondragleave":
		  case "ondragover":
		  case "ondrop":
		  case "onfinish":
		  case "onfocus":
		  case "onhelp":
		  case "onmousedown":
		  case "onmouseup":
		  case "onmouseover":
		  case "onmousemove":
		  case "onmouseout":
		  case "onkeypress":
		  case "onkeydown":
		  case "onkeyup":
		  case "onload":
		  case "onlosecapture":
		  case "onpropertychange":
		  case "onreadystatechange":
		  case "onrowsdelete":
		  case "onrowenter":
		  case "onrowexit":
		  case "onrowsinserted":
		  case "onstart":
		  case "onscroll":
		  case "onbeforeeditfocus":
		  case "onactivate":
		  case "onbeforedeactivate":
		  case "ondeactivate":
		  case "type":
		  case "codebase":
			ret.objAttrs[args[i]] = args[i+1];
			break;
		  case "width":
		  case "height":
		  case "align":
		  case "vspace": 
		  case "hspace":
		  case "class":
		  case "title":
		  case "accesskey":
		  case "name":
		  case "id":
		  case "tabindex":
			ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
			break;
		  default:
			ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
		}
	  }
	  ret.objAttrs["classid"] = classid;
	  if (mimeType) ret.embedAttrs["type"] = mimeType;
	  return ret;
	},
	
	
	/*	++++++++++++++++++++++++++++++++++++++++++++++++++++
					MAPAS DO GOOGLE (API GOOGLE MAPS)
		++++++++++++++++++++++++++++++++++++++++++++++++++++ */
	
	/*
	* @desc				Método para implementar a API do Google Maps
	*					Basta ser chamado num template que tenha o respectivo DIV, com um objecto com várias propriedades para desenhar o mapa:
						Para que a API funcione o site tem que estar registado no Google. Fazer registo em http://www.google.com/apis/maps/signup.html
	* @access			public
	* @param Array		Um array/objecto com as seguintes props:
						- icones: Array (Array com a localização de cada icone para desenhar no mapa)
						- div_mapa: String (O id do div no template que vai albergar o mapa)
						- centro_mapa: Object (Objecto com 2 props para a localização do centro do mapa (Normalmente é o local para assinalar): 
								- lat		: Inteiro (Latitude)
								- long 		: Inteiro (Longitude) 
						- zoom: Inteiro (O factor de zoom com que vai carregar o mapa: quanto mais alto, mais perto.
						- icone: Objecto com as seguintes props: 
								- imagem	: String (Nome do ficheiro da imagem),
								- largura	: Inteiro (largura da img em pixeis),	
								- altura	: Inteiro (altura da img em pixeis),
								- lat		: Inteiro (desvio HZ do centro do mapa em pixeis),	
								- long		: Inteiro (desvio VT do centro do mapa em pixeis)
						- icone_sombra: Objecto com as seguintes props: 
								- imagem	: String (Nome do ficheiro da imagem),
								- largura	: Inteiro (largura da img em pixeis),	
								- altura	: Inteiro (altura da img em pixeis),
								- lat		: Inteiro (desvio HZ do centro do mapa em pixeis),	
								- long		: Inteiro (desvio VT do centro do mapa em pixeis)
	* @return 			void
	*/
	getMapaGoogle: function(dadosMapa) {
		if (GBrowserIsCompatible()) {
			// criação do obj para o mapa			
			var map = new GMap2($(dadosMapa['div_mapa']));
			
			// colocamos o controle para o zoom e o tipo de mapa
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
			
			// Posição central do mapa
			map.setCenter(new GLatLng(dadosMapa['centro_mapa']['lat'], -dadosMapa['centro_mapa']['long']), dadosMapa['zoom']);		
			
			/* +++ testes +++ 
			//map.addMapType(new GMapTypeControl(), new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10, 10)));	// bug de javascript
			
				alert(map.getMapTypes());
				var tiposMapas = map.getMapTypes();
				for(var prop in tiposMapas){ msg+='\n'+ prop + ': ' + tiposMapas[prop]; }
				alert(msg);
			*/
			
			// Retiramos o 2, no caso de vir com www2, uma vez que o google precisa de aceder às imagens dos icones para as representar
			var regraValidacao = new RegExp("(www2)","g");
			urlImgsTmplSite = urlImgsTmplSite.replace(regraValidacao,'www');
			
			// vamos colocar icones no mapa
			for(i=0; i < dadosMapa['icones'].length; i++){
				var icon 			= new GIcon();
				icon.image 			= urlImgsTmplSite + dadosMapa['icone']['imagem'];
				icon.shadow 		= urlImgsTmplSite + dadosMapa['icone_sombra']['imagem'];
				icon.iconSize 		= new GSize(dadosMapa['icone']['largura'], dadosMapa['icone']['altura']);
				icon.shadowSize 	= new GSize(dadosMapa['icone_sombra']['largura'], dadosMapa['icone_sombra']['altura']);
				icon.iconAnchor 	= new GPoint(dadosMapa['icone']['lat'], dadosMapa['icone']['long']);
				//icon.infoWindowAnchor = new GPoint(5, 1);
				//adicionamos o icone e a sombra ao layout
				map.addOverlay(	new GMarker(new GLatLng(dadosMapa['icones'][i]['lat'],-dadosMapa['icones'][i]['long'] ), icon));
			}
		}
	}
	
}
