 /*
  *  FastSquirrel is a PHP 5.3 MVC O.O Framework
  *  Copyright (C) 2009 Marcus Vinicius Bastos Leandro <mvleandro@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2, or (at your option)
  *  any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  */



/**
 * Objeto principal do framework
 * */

var Squirrel = {
	
	/**
	 * Oculta ou exibe o elemento cujo seletor foi informado
	 * */
	'showOrHidde' : function( event, elementSelector ){
		
		if( (typeof event) == 'object' ){
			
			var element = $(event.target);
			
			if( element.attr('checked') ){
				
				$(elementSelector).removeClass('off');
				
			}else{
				
				$(elementSelector).addClass('off');
				
			}
			
		}else{
			
			if( event == 'show' ){
				
				$(elementSelector).removeClass('off');
				
			}else{
				
				$(elementSelector).addClass('off');
				
			}			
			
		}
		
	},
		
	/**
	 * Adiciona os options selecionados no select from no select to
	 * */
	'addToSelect' : function( event, from, to ){
	
		//Pego os options selecionados do from
		var fromSelectedOptions = $( from + ' option:selected' );
		
		//Adiciono os options selecionados do from no to
		$( from + ' option:selected' ).each(function( index, option ){			
			$( to ).append(option);		
		});		
		
		//Apago os options selecionados do from
		$( from + ' option:selected' ).each(function( index, option ){			
			$(option).remove();			
		});		
		
	},	
		
	/**
	 * Seleciona todos os options do select
	 * */
	'selectAll' : function( event ){
				
		var element = $(event.target);
		var options = $( '#' + element.attr('id') + ' > option' );
	
		$(options).each(function( index, option ){			
			option = $(option);			
			option.attr( 'selected', 'selected' );			
		});		
		
	},
		
	/**
	 * Redireciona o usuário para a url passafa
	 * */
	'redirect' : function( url ){
		document.location.href = url;
	},
		
	/**
	 * Método que exibe o loader das requisições ajax
	 * */
	'showLoader' : function(){			

		var iTop = $(window).scrollTop();
		var	wHeight = $(window).height();
		var	dHeight = $(document).height();
		var	fTop = ( iTop + ( ( wHeight / 2 ) - ( $('#squirrelAjaxLoaderContainer').outerHeight() / 2 ) ) );
		var	left = ( $(window).width() / 2 ) - ( $('#squirrelAjaxLoaderContainer').outerWidth() / 2 ); 
		
		$('#squirrelAjaxLoaderContainer').css({ top: (fTop+'px'), left:(left+'px') }).removeClass('off');
		$('#squirrelAjaxLoader').removeClass('squirrelAjaxLoaderError');	
		$('#squirrelAjaxLoader').removeClass('squirrelAjaxLoaderSuccess');		
		$('#squirrelAjaxLoader').addClass('squirrelAjaxLoaderLoading');
		$('#squirrelAjaxLoader > div').html( squirrelLoadingMessage );
		
	},
	
	
	/**
	 * Método que esconde o loader das requisições ajax
	 * */
	'hideLoader' : function(){	
		$('#squirrelAjaxLoaderContainer').addClass('off');	
	},
	
	
	
	/**
	 * Carrega o conteúdo de uma template para dentro do elemento cujo identificador for informado
	 * 
	 * @param string identifier - Identificador do elemente que será atualizado
	 * @param string template - Nome da template
	 * @param mixed params - QueryString, form, ou objeto. Estes dados serão enviados na requisição
	 * @param bool enableCache - Flag booleana que determina se a requisição será cacheada ou não - Default false
	 * @param bool showLoader - Flag booleana que determina se o loader ajax será exibido - Default true
	 * 
	 * */
	'loadTemplate' : function( identifier, template, params, enableCache, showLoader, callback ){
		
		if( (typeof showLoader) == 'undefined' || showLoader == null ){
			showLoader = true;
		}
		
		if( showLoader ){
			
			//Exibo o loader
			Squirrel.showLoader();
			
		}
		
		//Inicializo variáveis
		var urlParams = '';
		var urlEnableCache = '';
	
		if( ( typeof params ) == 'string' ){
			
			urlParams = '&' + params;
			
		}else if( ( typeof params ) == 'object' ){
			
			urlParams = '&' + jQuery.param( params );
			
		}
	
		if( ( typeof enableCache ) == 'boolean' && enableCache ){			
			urlEnableCache = '&squirrelEnableCache=true';			
		}
		
		//Monto a url da requisição
		var url = siteInstallationPath + "/?ajaxRequest=1&squirrelAction=runTemplate&squirrelReturnType=text&squirrelTemplate=" + template + urlParams + urlEnableCache;
		
		//Carrego o elemento
		$(identifier).load( url, function( response, status, xhr ){
			
			if( status == 'error' ){
				
				//Sempre que houver um erro a resposta vem em JSON
				//Isto é controlado pela exception_handler no php
				var exception = eval( '(' + response + ')' ); 
				
				$('#squirrelAjaxLoaderContainer').removeClass( 'off' );
				$('#squirrelAjaxLoader').removeClass( 'squirrelAjaxLoaderLoading' );
				$('#squirrelAjaxLoader').addClass( 'squirrelAjaxLoaderError' );					
				$('#squirrelAjaxLoader > div').html( exception.message );
				
			}else{				
				
				if( (typeof callback) == 'function' ){
					callback();
				}
				
				Squirrel.hideLoader();
				
			}			
			
		} );
		
	
	},
		
	
	/**
	 * Executa um método de uma classe, remotamente
	 * 
	 * @param string className - Nome da classe
	 * @param string methodName - Nome do método que será executado da classe
	 * @param mixed params - QueryString, form, ou objeto. Estes dados serão enviados na requisição
	 * @param string returnType - Tipo de retorno da requisição: xml, html, script ou json - Default text
	 * @param function callback - Função de retorno
	 * @param bool isStatic - Determina se o método a ser executado é estático ou não - Defaul false
	 * @param bool enableCache - Flag booleana que determina se a requisição será cacheada ou não - Default false
	 * @param bool async - Flag booleana que determina se a requisição será síncrona ou assíncrona
	 * @param bool showLoader - Flag booleana que determina se o loader ajax será exibido - Default true
	 * 
	 * @return mixed
	 * */
	'runMethod' : function( className, methodName, params, returnType, callback, isStatic, enableCache, async, showLoader ){		
					
		if( (typeof showLoader) == 'undefined' ){
			showLoader = true;
		}
		
		if( (typeof showLoader) == 'boolean' && showLoader ){
			
			Squirrel.showLoader();
			
		}												
		
		//Inicialização de variáveis
		var urlReturnType = '';
		var urlIsStatic = '';
		var urlParams = '';	
		var urlEnableCache = '';
		
		if( ( typeof async ) == 'undefined' ){
			async = true;
		}
		
		if( ( typeof params ) == 'string' ){
			
			urlParams = '&' + params;
			
		}else if( ( typeof params ) == 'object' ){
			
			urlParams = '&' + jQuery.param( params );
			
		}	
		
		if( ( typeof returnType ) == 'string' ){
			urlReturnType = '&squirrelReturnType=' + returnType;
		}
		
		if( ( typeof isStatic ) == 'boolean' ){
			urlIsStatic = '&squirrelIsStatic=' + isStatic;
		}
		
		if( ( typeof returnType ) != 'string' ){
			returnType = 'json';
		}
		
		if( ( typeof enableCache ) == 'boolean' && enableCache ){			
			urlEnableCache = '&squirrelEnableCache=true';			
		}		
		
		urlReturnType = '&squirrelReturnType=' + returnType;
		
		//Monto a url da requisição
		var queryString = "ajaxRequest=1&squirrelAction=runMethod&squirrelClass=" + className + "&squirrelMethod=" + methodName + urlParams + urlReturnType + urlIsStatic + urlEnableCache;						
		
		if( async ){
			
			$.ajax({			
				type: "POST",				
				url: siteInstallationPath + '/',
				dataType: returnType,
				async: true,
				timeout: 60000,
				data: queryString,
				success: function( data ){
					callback(data);
					Squirrel.hideLoader();
				},
				error: function( request, error ){						
					
					//Sempre que houver um erro a resposta vem em JSON
					//Isto é controlado pela exception_handler no php
					var exception = eval( request.responseText ); 										//
					
					$('#squirrelAjaxLoader').removeClass( 'squirrelAjaxLoaderLoading' );
					$('#squirrelAjaxLoader').addClass( 'squirrelAjaxLoaderError' );					
					$('#squirrelAjaxLoader > div').html( exception.message );
					
				}
			});									
			
		}else{
			
			var response = $.ajax({			
				type: "POST",				
				url: siteInstallationPath + '/',
				async: false,
				data: queryString,
				complete: function(){
					Squirrel.hideLoader();
				}		
			}).responseText;
		
			if( returnType == 'json' ){
				
				response = eval( '(' + response + ')' );
				
			}			
		
			return response;
			
		}			
		
	},
	
	
	/**
	 * Executa um método de uma classe, remotamente e de forma síncrona, e retorna o valor de retorno do método
	 * 
	 * @param string className - Nome da classe
	 * @param string methodName - Nome do método que será executado da classe
	 * @param mixed params - QueryString, form, ou objeto. Estes dados serão enviados na requisição
	 * @param string returnType - Tipo de retorno da requisição: xml, html, script ou json - Default text
	 * @param bool isStatic - Determina se o método a ser executado é estático ou não - Defaul false
	 * @param bool enableCache - Flag booleana que determina se a requisição será cacheada ou não - Default false
	 * @param bool showLoader - Flag booleana que determina se o loader ajax será exibido - Default true
	 * 
	 * @return mixed
	 * */	
	'runMethodSync': function( className, methodName, params, returnType, isStatic, enableCache, showLoader ){
		
		return Squirrel.runMethod( className, methodName, params, returnType, false, isStatic, enableCache, false, showLoader );
		
	},
	
	/**
	 * Processa a resposta de uma requisição ajax
	 * */
	'processResponse':function( data ){
		
		data = eval( '(' + data + ')' );
		
		return data;
		
	},
	
	/**
	 * Envia um formulário via ajax
	 * 
	 * @param object or event element
	 * */
	'sendForm' : function( element ){												
				
		if( (typeof element) == 'object' ){
			var formId = $(element).attr('id');			
		}else{
			var formId = $(event.target).attr('id');			
		}											
		
		var squirrelClass = $( '#' + formId + '_' + 'squirrelClass' ).attr('value');
		var squirrelMethod = $( '#' + formId + '_' + 'squirrelMethod' ).attr('value');
		var squirrelAction = $( '#' + formId + '_' + 'squirrelAction' ).attr('value');
		var squirrelIsStatic = $( '#' + formId + '_' + 'squirrelIsStatic' ).attr('value');
		var squirrelReturnType = $( '#' + formId + '_' + 'squirrelReturnType' ).attr('value');
		
		
		if( squirrelAction == 'runMethod' ){
			
			var slices = squirrelClass.split( '\\' );
			
			//Inicializo a variável que conterá o caminho para o objeto de callback
			var fullObjectPath = '';
			
			//Monto o caminho para o método de callback
			for( var i = 0; i < slices.length; i++ ){
				
				if( slices[i].length > 0 ){
				
					if( fullObjectPath.length == 0 ){
						
						fullObjectPath = slices[i] + '.';
						
					}else{
						
						fullObjectPath = fullObjectPath + slices[i] + '.';
						
					}
					
				}
				
			}						
			
			//Processo classe e método a serem chamados via javascript
			var squirrelCallback = fullObjectPath + squirrelMethod;											
			
			//Efetuo a requisição ajax executando um método remoto
			Squirrel.runMethod( squirrelClass, squirrelMethod, $('#'+formId).serialize(), squirrelReturnType, function( response ){																
				
				/*
				//Exibo o a mensagem de feeback
				if( !response.code && ( typeof response.message ) != 'undefined' && response.message ){					
					$('#formFeedback_' + formId).html( response.message );
					$('#formFeedback_' + formId).removeClass( 'off' );					
				}
				*/
				
				try{
					
					//Executo o método de callback
					eval( squirrelCallback + '( response );' );
					
				}catch(e){
					
					Squirrel.showFormFeedback( response );
					
				}
				
				
			}, squirrelIsStatic, false, true, true );			
			
		}
		//Entro no else caso estejamos carregando uma template remotamente
		else if( squirrelAction == 'runTemplate' ){
			
			alert( "O método de envio de formulário rodando uma template ainda não foi implementado." );
			
		}			
		
	},
	
	/**
	 * Exibo o feedback no formulário atual
	 * */
	'showFormFeedback' : function( response ){
		
		document.location.href = "#" + response.data.squirrelFormId;
		
		$('#formFeedback_' + response.data.squirrelFormId).html( response.message );
		$('#formFeedback_' + response.data.squirrelFormId).removeClass( 'off' );		
		
		if( response.code > 0 ){
			$('#formFeedback_' + response.data.squirrelFormId).removeClass( 'formError' ).addClass( 'formSuccess' );
		}else{
			$('#formFeedback_' + response.data.squirrelFormId).removeClass( 'formSuccess' ).addClass( 'formError' );
		}
		
	},
	
	/**
	 * Demora uma quantia em miliseconds para executar uma ação
	 * */
	'sleep': function(miliseconds){		
		
		var date = new Date();
		
		var curDate = null;
		do {
			curDate = new Date();
		
		}while(curDate-date < miliseconds)
		
	}	
	
};

var View = {
		
		'highlight':function( elementID ){
		
			$("#" + elementID).focus(
					function(){
						
						$("#" + elementID).addClass("highlight");				
						$("#" + elementID).parent().children().eq(0).addClass("highlight");
						
					}
				)
				
				$("#" + elementID).blur(
					function(){
		
						$("#" + elementID).removeClass("highlight");
						$("#" + elementID).parent().children().eq(0).removeClass("highlight");
															
					}
				)
		
		},
		
		'loadStates':function( event, callback ){
			
			if( (typeof event) == 'number' ){
				var value = event;
			}else{
				var element = $(event.target);
				var value = element.attr('value');
			}												
			
			if( value == 30 ){
				
				var qs = 'CountryId=' + value;								
				
				Squirrel.runMethod( '\\Zemoleza\\StateControl', 'ajaxGetStates', qs, 'json', function( data ){					
					
					$("#StateId").parent().removeClass("off");
					$("#StateId").html("");
					$("<option value=''>Carregando...</option>").appendTo("#StateId");
					
					$(data).each(function( index, state ){
						
						var optionHTML = "<option value='" + state.id + "'>" + state.title + "</option>";						
						$(optionHTML).appendTo("#StateId");
						
					});
					
					$("#StateId option:selected").text( "Escolha" );
					
					$("#StateId").attr("disabled", false);
					
					if( callback ){
						callback();
					}					
					
				},false, true, true, true );
				
			}else{
				
				$("#StateId").val("");
				$("#CityId").val("");
				$("#StateId").attr("disabled", true);
				$("#CityId").attr("disabled", true);
				$("#StateId").parent().addClass("off");				
				$("#CityId").parent().addClass("off");				
				
			}
			
		},
		
		
		'loadCities':function( event, callback ){						
			
			if( (typeof event) == 'number' ){
				var value = event;
			}else{
				var element = $(event.target);
				var value = element.attr('value');
			}					
			
			if( value > 0 ){
			
				var qs = 'StateId=' + value;								
				
				Squirrel.runMethod( '\\Sites\\Ofertax\\CityControl', 'ajaxGetCities', qs, 'json', function( data ){					
					
					$("#CityId").parent().removeClass("off");
					$("#CityId").html("");
					$("<option value=''>Carregando...</option>").appendTo("#CityId");				
					
					$(data).each(function( index, city ){
						
						var optionHTML = "<option value='" + city.id + "'>" + city.name + "</option>";						
						$(optionHTML).appendTo("#CityId");
						
					});
					
					$("#CityId option:selected").text( "Escolha" );
					
					$("#CityId").attr("disabled", false);
					
					if( callback ){
						callback();
					}
					
				}, false, true, true, true );							
			
			}else{
				
				$("#CityId").val("");
				$("#CityId").attr("disabled", true);
				$("#CityId").parent().addClass("off");
				
			}
			
		}
		
	};


/**
 * Objeto criado para exibir uma pop
 * */
var Pop = {
	
	/**
	 * Função criada para exibir uma pop
	 * 
	 * @param string template - Template section que será exibida
	 * @param string data - Dados no formato querystring que serão enviados para a pop
	 * @param integer width - Largura da pop
	 * @param integer height - Altura da pop
	 * @param boolean modal - Determina se a janela abrirá como modal
	 * @param string POPId - Especificação do id da pop
	 * */
	'show' : function( template, data, width, height, modal, POPId, callback ) {//function called when the user clicks on a thickbox link		
	
		if( (typeof template) == 'object' ){
			var buttonId = $(template.target).attr('id');
			var templateFieldId = buttonId + '_template';
			var templateName = $('#' + templateFieldId).attr('value');
			template = templateName;
		}
	
		try {
			
			if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
				$("body","html").css({height: "100%", width: "100%"});
				$("html").css("overflow","hidden");
				if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
					$("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
					$("#TB_overlay").click(tb_remove);
				}
			}else{//all others
				if(document.getElementById("TB_overlay") === null){
					$("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");
					$("#TB_overlay").click(tb_remove);
				}
			}
			
			if(tb_detectMacXFF()){
				$("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
			}else{
				$("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
			}
						
			//$("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");//add loader to the page
			//$('#TB_load').show();//show loader
								
			TB_WIDTH = (width*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
			TB_HEIGHT = (height*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
			
			ajaxContentW = TB_WIDTH - 30;
			ajaxContentH = TB_HEIGHT - 45;
			
		
			if($("#TB_window").css("display") != "block"){
				if(modal != "true"){//ajax no modal
				$("#TB_window").append("<div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Fechar'>Fechar</a></div><div id='TB_ajaxContent' style='height:"+ajaxContentH+"px'></div>");
				}else{//ajax modal
				$("#TB_overlay").unbind();
				$("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='height:"+ajaxContentH+"px;'></div>");	
				}
			}else{//this means the window is already up, we are just loading new content via ajax
				$("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
				$("#TB_ajaxContent")[0].scrollTop = 0;
			}
			
					
			$("#TB_closeWindowButton").click(tb_remove);			
			
			Squirrel.showLoader();
			$("#squirrelAjaxLoaderContainer").css('z-index', 99999);			
			
			//Aqui eu chamo o ajax para carregar a template
			Squirrel.loadTemplate( '#TB_ajaxContent', template, data, false, true, callback );
			
			tb_position();
			$("#TB_load").remove();
			tb_init("#TB_ajaxContent a.thickbox");
			$("#TB_window").css({display:"block"});			

			if(!modal){
				document.onkeyup = function(e){ 	
					if (e == null) { // ie
						keycode = event.keyCode;
					} else { // mozilla
						keycode = e.which;
					}
					if(keycode == 27){ // close
						tb_remove();
					}	
				};
			}		
				
		} catch(e) {
					//nothing here
		}	
	},


	/**
	 * Fecha uma pop aberta
	 * */
	'close' : function(callback){
		
		$('#TB_window').remove();
		$('#TB_overlay').remove();
		
		try{
			callback();
		}catch(e){
			
		}
		
	},
	
	/**
	 * Exibe uma mensagem de erro
	 * */
	'success' : function( code, message ){

		var data = 'code=' + code + '&' + 'message=' + message;			
		Pop.show( 'Pop/Success', data, 500, 70 );		
		
	},
	
	/**
	 * Exibe uma mensagem de erro
	 * */
	'error' : function( code, message ){

		var data = 'code=' + code + '&' + 'message=' + message;			
		Pop.show( 'Pop/Error', data, 500, 70 );		
		
	},
	
	/**
	 * Exibe uma mensagem de sucesso ou de erro
	 * */
	'message': function( code, message ){
		
		message = escape(message);
		
		if( code > 0 ){			
			Pop.success(code, message);			
		}else{			
			Pop.error(code, message);						
		}
		
	}	
		
};


