package classes.matuto.core
{
	
	/*
	
		Classe responsavel por tudo gerenciamento 
		da aplicacao.
		
		autor: gustavo cosme
		data:  18/maio/2011
	
	*/
	
	import classes.matuto.core.module.ModuleBase;
	import classes.matuto.core.module.ModuleCollection;
	import classes.matuto.core.module.ModuleInfo;
	import classes.matuto.erro.Erro;
	import classes.matuto.events.MatutoEvent;
	import classes.matuto.model.ModelCollection;
	import classes.matuto.ui.RightMenu;
	import classes.swfAddress.SWFAddress;
	import classes.swfAddress.SWFAddressEvent;
	
	import flash.display.*;
	import flash.errors.IOError;
	import flash.events.*;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.ui.ContextMenuItem;
	import flash.utils.Timer;
	import flash.utils.setTimeout;
	
	public final class Matuto
	{
		
		
		private static var _dispatcher			:EventDispatcher = new EventDispatcher();
		
		private static var moduleCollection		:ModuleCollection;
		private static var moduleInfo			:ModuleInfo;
		private static var navCollection		:Array			 = new Array();
		private static var contextCollection	:Object			 = new Object();
		private static var contextAux			:int 			 = 0;
		private static var urlAnterior			:String;
		
		private static var config				:Config;
		private static var urlInfo				:URLInfo;
		private static var primeiraInicia		:Boolean;
		
		private static var index				:Index;
		private static var site					:SiteBase;
		private static var moduleBase			:ModuleBase;
		public  static var rootStage			:Stage;
		
		public  static  var onInit				:Function;
		private static var possoUpdateURL		:Boolean = false;
		private static var possoUpdate			:Boolean = false;
		private static var possoInit			:Boolean = true;
		private static var estaNoInicio			:Boolean = true; 
		public  static var idAtualContext:int; 
		
		public function Matuto()
		{
		    Erro.add("MATUTO NAO PODE SER INSTACIADA");   
		}
	
		//inicia o matuto
		
		public static function init():void
		{
			INICIALIZE_MATUTO();
		}
		
		//Verifica as configuracao do siteMaps do preloader ou interno
		
		protected static function INICIALIZE_MATUTO():void
		{
		
			if(SiteMaps.getCollection)
			{
			 
				moduleCollection = SiteMaps.getCollection;
				onInit();
				dispatchEvent(new MatutoEvent(MatutoEvent.INIT));	
				
			}else{
			
				var funcao:Object = new Object(); 
					
				funcao.call = function():void
				{
				   moduleCollection =	SiteMaps.getCollection;   
				   onInit();		
				}
					
				SiteMaps.init(funcao.call);
				
			}
			
					
			return void;	
			
		}
		
		
		//###############################################################
		//responsavel por registar a index e o rootStage do Matuto		
		//###############################################################
		
		public static function setSite(_index:Index,_stage:Stage):void
		{
			rootStage 		= _stage;
			index			= _index;
			
			site 			= index.getSite;	

			initContextMenu();		
			moduleBase   	= new ModuleBase(site.getContainer);
			site.init();
					
			addEventResize();
			init_SWFADDRESS();
			
		}
		
	
		
		//###############################################################

		//================================= URL ===================================================================================== //
		
	
		//responsavel por fazer o update da aplicao entre internas.
		//sempre que eu chamar esse metodo ele faz todas os updates necessario.
		
		//###############################################################

		
		public static function SET_URL(value:String):void
		{
			SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,onChangeUrl);
			
			SWFAddress.setValue(value);	
			onChangeUrl();
			
			dispatchEvent(new MatutoEvent(MatutoEvent.CHANGE));
			
			setTimeout(function():void{
				
				SWFAddress.addEventListener(SWFAddressEvent.CHANGE,onChangeUrl);
				possoUpdate = true;
				
			},100);
		
		}
		
		private static function init_SWFADDRESS():void
		{
			SWFAddress.addEventListener(SWFAddressEvent.CHANGE,onInitA);
		}
		
		private static function onInitA(e:SWFAddressEvent):void
		{			
			
			SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,onInitA);	

			
			if(possoInit)
			{	
				
				possoInit = false

				TRATAMENTO_URL_INIT();
				
				if(moduleInfo)
				{
				
					validationNav();
					initModule();			
					
					SWFAddress.setTitle(moduleInfo.getTitle);
					SWFAddress.setValue(moduleInfo.getId+"/"+urlInfo.getParamText);
					
					SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,onInitA);	
					
					setTimeout(function():void{
					
							SWFAddress.addEventListener(SWFAddressEvent.CHANGE,onChangeUrl);
							possoUpdate = true;
					
					},100);
			
				}//end 
				
			}
		}
		

		//###############################################################
		//responsavel por tudo update
		//###############################################################

		
		private static function onChangeUrl(e:SWFAddressEvent=null):void
		{
			
			SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,onChangeUrl);

			if(possoUpdate)
			{
				
				TRATAMENTO_URL();	
				
				if(moduleInfo)
				{
				
					if(urlAnterior == moduleInfo.getId)
					{
					   
			            updateModuleUrl();
						dispatchEvent(new MatutoEvent(MatutoEvent.CHANGE));

					}else
					{
						
						validationNav();
						
						updateModule();
						SWFAddress.setTitle(moduleInfo.getTitle);

					}
				
				}//end
					
			}
		
			setTimeout(function():void{
				
				SWFAddress.addEventListener(SWFAddressEvent.CHANGE,onChangeUrl);
				possoUpdate = true;
				
			},100);
			
		}
		
		
		//trata a url para termos em maos, os paramentos da URL, o modulo info atual
	
		
		private static function TRATAMENTO_URL():void
		{			
			
			
			urlAnterior					=  moduleInfo.getId;

			var patch		:String 	= 	SWFAddress.getPath();
			var array		:Array		=   patch.split("/");
			
			urlInfo 					= 	new URLInfo(array);
			
			moduleInfo					=   moduleCollection.getCollection[urlInfo.getModulo];
		
			if(moduleInfo == null)
			{
				navigateToURL(new URLRequest("pageNotFound.html"),"_self");	
			}	
			
			
		}
		
		
		
		private static function TRATAMENTO_URL_INIT():void
		{
			
			
			var patch		:String 	= 	SWFAddress.getPath();
			var array		:Array		=   patch.split("/");
			
			urlInfo 					= 	new URLInfo(array);
			
			moduleInfo					=  moduleCollection.getCollection[urlInfo.getModulo];
			
			if(moduleInfo == null)
			{
				
				moduleInfo 				=  moduleCollection.getCollection[getConfig.getDefaultModule];
	
			}

			if(moduleInfo)
			urlAnterior					=  moduleInfo.getId;

			
		}
		

		//###############################################################
		
		
		
		//###############################################################		
		//======================== NAVEGACAO ==========================//
		//responsavel pelo update de navegacao de tudo o Site
		//###############################################################
		
		
		private static function initContextMenu():void
		{
			
			RightMenu.addMenuItem(getConfig.getNomeContext, getContainer, true, true, true, function():void
			{ 
				navigateToURL(new URLRequest(getConfig.getLinkContext),"_BLANK");
			});
			
			var colecao	:Object = getModelCollection.getCollection;
			var right	:int;
			
			var list:XMLList = SiteMaps.getXML.modules.module;
						
			for ( var i :int=0; i< list.length(); i++)
			{	
				
				var nome:String = list[i].attribute("id").toString();
				var module:ModuleInfo = getModelCollection.getCollection[nome] as ModuleInfo;
				
				if(module.getContext=="true")
				{
					right 		 = RightMenu.addMenuItem(getConfig.getContext+" "+module.getId,getContainer,false,true,true,selectContext(nome,i));
					validationContextInit(nome,i);
					contextCollection[module.getId] = RightMenu.getItemByIndex(i);
				}
				
			}
			
		}
		
		private static function selectContext(id:String,_int:int = 0):Function
		{
			var f:Function =  function():void
			{	
				RightMenu.getItemByIndex(idAtualContext).enabled = true;	
				idAtualContext = _int+1;
				RightMenu.getItemByIndex(idAtualContext).enabled = false;	
				SET_URL(id);	
			};
			
			return f;
		}
		
		private static function validationContextInit(value:String,aux:int):void
		{
			if(RightMenu.getItemByIndex(aux+1))
			{
			
				if(value == SiteMaps.getConfig.getDefaultModule)
				{
					idAtualContext = aux+1;
					RightMenu.getItemByIndex(aux+1).enabled = false;	
					
				}else
				{
					RightMenu.getItemByIndex(aux+1).enabled = true;	
				}
			
			}
		}
		
	
		public static function addReference(botao:ButtonNav,url:String):void
		{
			
			var t:Array 		= url.split('/');	
			botao.setUrl		= t[0];
			botao.setId			= t[0];
			
/*			if (moduleCollection.getCollection[botao.getId].getContext == "true")
			{
				botao.params.idContext = contextAux;
				contextAux++;
			}*/
			
			//navCollection.push(botao);

			botao.addEventListener(Event.SELECT, function(e:Event):void
			{
			
				SET_URL(e.currentTarget.getId);
			
			});
			
			/*if (context)
			{
			
				var indexLocal:* = getContainer;			
				var right:int = RightMenu.addMenuItem(getConfig.getContext+" "+botao.getId,indexLocal,false,true,true,function():void
				{	           	
					var b:ButtonNav = navCollection[right-1];
					SET_URL(b.getId);
				});
			
			}*/
			
			return void;
		}
		
		
		private static function validationNav():void
		{
	
			if(navCollection)
			{
				
				for each(var botao:ButtonNav in navCollection)
				{
      					
					if(botao.getId == moduleInfo.getId)
					{
						
						
					   	botao.enabled = false;	
						
						if (botao.params.idContext)
						RightMenu.getItemByIndex(botao.params.idContext).enabled = false;

											   
					}else
					{
						botao.enabled = true;
						
						if(botao.params.idContext)						
						RightMenu.getItemByIndex(botao.params.idContext).enabled = true;
					}			
				}
				
			}
			
		}
		
		
		private static function addContext():void
		{
			var indexLocal:* = getContainer;
			
			RightMenu.addMenuItem(getConfig.getNomeContext,indexLocal,true,true,true,function():void
			{	
				navigateToURL(new URLRequest(getConfig.getLinkContext),"_BLANK");
			});
				
		}

		
		public static function get getContainer():*
		{
			var indexLocal:*;
			
			if(index.estaNoStage)
				indexLocal = index;
			else 
				indexLocal = index.parent;
			
			return indexLocal;
		}
		
	
		//###############################################################
		
		
		
		//###############################################################
		//===================== UPDATE MODULO =========================//
		//	`		responsavel pelo update dos modulos
		//###############################################################

		private static function initModule():void
		{
			setTimeout(moduleBase.init,getConfig.getDelay*1000,(moduleInfo));
		}
		
		private static function updateModule():void
		{
			moduleBase.change(moduleInfo);	
		}
		
		private static function updateModuleUrl():void
		{
		    moduleBase.getModule.changeUrl();
		}
		
		//======================================== GET ==============================================//
		

		public static function get getConfig():Config
		{
			return SiteMaps.getConfig;
		}
		
		public static function get getSite():SiteBase
		{
			return site;	
		}
		
		public static function get getModuleBase():ModuleBase
		{
			return moduleBase;	
		}
		
		public static function get getStage():Stage
		{
			return rootStage;
		}
		
		public static function get getModelCollection():ModuleCollection
		{
			return moduleCollection;
		}
		
		public static function get getUrlInfo():URLInfo
		{
		   return urlInfo
		}
		
		public static function getDefaultErro():void
		{	
			navigateToURL(new URLRequest("pageNotFound.html"),"_self");	
			return;
		}
		
		public static function get getModuleInfo():ModuleInfo
		{
			return moduleInfo;
			return;
		}
		
		//###############################################################
		
		
		
		//###############################################################
		//=================== SET =======================================//
		//###############################################################

		
		public static function setParams(value:String):void
		{
	
			possoUpdate 			= false;
			SWFAddress.removeEventListener(SWFAddressEvent.CHANGE,onChangeUrl);

			var array:Array 		= value.split("/");
			urlInfo.setParams		= array;
			
			SET_URL(moduleInfo.getId+"/"+value);
			
			setTimeout(function():void{
				
				SWFAddress.addEventListener(SWFAddressEvent.CHANGE,onChangeUrl);
				possoUpdate = true;
				
			},100);
			
		}

		
		//###############################################################
		
		
		
		//###############################################################
		//================== EVENTS ===================================//
		//###############################################################

		
		public static function addEventListener(type :String, listener :Function, useCapture :Boolean = false, priority :int = 0, useWeakReference :Boolean = false) :void
		{
			_dispatcher.addEventListener(type, listener, useCapture, priority);
		}
		
		public static function dispatchEvent(evt :Event) :Boolean
		{
			return _dispatcher.dispatchEvent(evt);
		}
		
		public static function hasEventListener(type :String) :Boolean
		{
			return _dispatcher.hasEventListener(type);
		}
		
		public static function removeEventListener(type :String, listener :Function, useCapture :Boolean = false) :void
		{
			_dispatcher.removeEventListener(type, listener, useCapture);
		}
		
		public static function willTrigger(type :String) :Boolean
		{
			return _dispatcher.willTrigger(type);
		}
		
		
		//###############################################################

		
		//###############################################################
		//=================== RESIZE ================================= //
		//###############################################################

		private static function addEventResize():void
		{
			Matuto.getStage.scaleMode = "noScale";
			Matuto.getStage.align     = "TL";
			Matuto.getStage.addEventListener(Event.RESIZE, onResize);
			onResize(null);
			
		}
		
		private static function onResize(e:Event):void
		{
		
			try{

				site.resize();	
				
			}catch(e:Error)
			{
			
				Erro.add("ERRO NO RESIZE DA CLASSE SITE");
			
			}
			
			
			try{
				
				if(moduleBase)
				{
					
					if(moduleBase.getModule)
					moduleBase.getModule.resize();
					
					if(moduleBase.getPreloader)
					moduleBase.getPreloader.resize();
					
				}	
				
			}catch(e:Error)
			{
				
				Erro.add("ERRO NO RESIZE NO MODULO ATUAL");
				
			}
			
			dispatchEvent(new MatutoEvent(MatutoEvent.RESIZE));
				
		
		}
		
		//###############################################################
		
		
	
		
		
		
		
	}//end class
}