package {
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import fl.events.SliderEvent;
	import flash.events.Event;
	import flash.media.SoundMixer;
	import flash.media.SoundTransform;
	
	public class Grafica {
		// Reúne os objetos criados
		static public var territorios:Array = [];
		static public var dados:Array = [];
		static public var root:MovieClip;
		static public var cartas:Array = [];
		static public var objetivos:Array = [];
		static public var continentes:Array = [];
		static public var salas:Array = [];
		static public var jogadores:Array = [];
		static public var cores:Array = [];
		static public var continente_destacado:Continente;
		static public var editando_jogo:Boolean = false;
		static public var editando_mundo:Boolean = false;
		
		// Retorna o objeto Territorio com o nome desejado
		static public function get_territorio(nome:String):Territorio {
			var i:String;
			for (i in territorios) {
				if (territorios[i].nome == nome) {
					return territorios[i];
				}
			}
			return null;
		}
		
		// Retorna o objeto Territorio com o nome desejado
		static public function get_territorio_by_mc(mc:String):Territorio {
			var i:String;
			for (i in territorios) {
				if (territorios[i].mc == mc) {
					return territorios[i];
				}
			}
			return null;
		}
		
		// Retorna o objeto Continente com o nome desejado
		static public function get_continente(nome:String):Continente {
			var i:String;
			for (i in continentes) {
				if (continentes[i].nome == nome) {
					return continentes[i];
				}
			}
			return null;
		}
		
		// Atualiza o número mostrado sobre o território
		// ops é um objeto com as propriedades dono, delta, fundo e aviso
		static public function atualizar_territorio(terra:Territorio, ops:Object=null):void {
			var backup:int = int(root[terra.mc].txt_texto.text);
			
			// Atualiza tudo
			if (ops == null) {
				ops = {"dono" : null, "delta" : null, "fundo" : null, "aviso" : false};
			}
			
			// Atualiza o dono
			if (ops.dono === null) {
				ops.dono = Relacao.get_relacao(terra, Relacao.DONO);
			}
			if (ops.dono !== undefined) {
				root[terra.mc].gotoAndStop(ops.dono.id);
			}
			
			// Atualiza o nº de soldados
			if (ops.delta === null) {
				ops.delta = terra.soldados-backup;
			}
			if (ops.delta !== undefined) {
				root[terra.mc].txt_texto.text = String(backup+ops.delta);
				if (ops.aviso && ops.delta !== 0) {
					root["mc_aviso"+terra.mc.substr(2)].mc_aviso.txt_texto.text = (ops.delta>0 ? "+" : "")+String(ops.delta);
					root["mc_aviso"+terra.mc.substr(2)].mc_aviso.txt_texto.textColor = ops.delta>0 ? 0x000000 : 0xFF0000;
					root["mc_aviso"+terra.mc.substr(2)].gotoAndPlay(2);
				}
			} else {
				root[terra.mc].txt_texto.text = String(backup);
			}
			
			// Atualiza o fundo
			if (ops.fundo === null) {
				ops.fundo = 1;
			}
			if (ops.fundo !== undefined) {
				root[terra.mc].mc_fundo.gotoAndStop(ops.fundo);
			}
			
			// Atualiza o tamanho
			backup = int(root[terra.mc].txt_texto.text);
			root[terra.mc].scaleX = root[terra.mc].scaleY = backup ? (.75+(2-.75)*Math.log(backup)/Math.log(150)) : .75;
		}
		
		// Retira os efeitos sobre os territórios
		static public function atualizar_territorios():void {
			var i:String;
			for (i in territorios) {
				atualizar_territorio(territorios[i], {"fundo" : null});
			}
			continente_destacado = null;
		}
		
		// Atualiza os campos que não irão mudar durante o jogo
		static public function campos_estaticos():void {
			var i:String;
			for (i in jogadores) {
				root["mc_conexao"+i].gotoAndStop(jogadores[i].ativo ? 1 : 4);
				root["txt_num_territorios"+i].visible = jogadores[i].jogou;
				root["txt_nome"+i].visible = jogadores[i].jogou;
				root["txt_nome"+i].text = jogadores[i].nome;
				root["txt_num_territorios"+i].text = Reguladora.formatar_num(Relacao.get_relacoes(jogadores[i], Relacao.DONO).length, 2);
			}
			root["txt_sala"].text = Reguladora.sala;
			root["txt_chat"].text = "";
		}
		
		// Atualiza os campos que dependem do jogador ativo
		static public function campos_jogador(so_cartas:Boolean=false):void {
			var soma:int, i:String, nums:Array = [0, 0, 0, 0], cartas:Object;
			if (so_cartas && Reguladora.ativo) {
				cartas = Relacao.get_relacoes(Reguladora.ativo, Relacao.CARTA);
				for (i in cartas) {
					nums[cartas[i].figura]++;
				}
			} else if (Reguladora.ativo) {
				soma = 0;
				for (i in Reguladora.ativo.perdas) {
					soma += Reguladora.ativo.perdas[i];
				}
				root["txt_mortos_em_combate"].text = Reguladora.formatar_num(soma, 4);
				soma = 0;
				for (i in jogadores) {
					soma += jogadores[i].perdas[int(Reguladora.ativo.id)-1];
				}
				root["txt_inimigos_mortos"].text = Reguladora.formatar_num(soma, 4);
				
				root["mc_cor"].gotoAndStop(Reguladora.ativo.id);
				root["mc_cor"].txt_nome.text = Reguladora.ativo.nome;
				
				cartas = Relacao.get_relacoes(Reguladora.ativo, Relacao.CARTA);
				for (i in cartas) {
					nums[cartas[i].figura]++;
				}
			} else {
				root["txt_mortos_em_combate"].text = Reguladora.formatar_num(0, 4);
				root["txt_inimigos_mortos"].text = Reguladora.formatar_num(0, 4);
				root["mc_cor"].gotoAndStop(7);
				root["mc_cor"].txt_nome.text = "";
			}
			
			root["txt_num_bonus"].text = Reguladora.formatar_num(nums[0], 1);
			root["txt_num_bolas"].text = Reguladora.formatar_num(nums[1], 1);
			root["txt_num_cubos"].text = Reguladora.formatar_num(nums[2], 1);
			root["txt_num_cones"].text = Reguladora.formatar_num(nums[3], 1);
		}
		
		// Atualiza os campos com informações gerais
		static public function campos_gerais():void {
			var tempo:Number, h:int, min:int;
			root["txt_rodada"].text = Reguladora.formatar_num(Reguladora.vez.rodada, 3);
			root["txt_troca"].text = Reguladora.formatar_num(Reguladora.troca, 3);
			root["txt_exercitos"].text = Reguladora.formatar_num(Reguladora.troca<6 ? 2*Reguladora.troca+2 : 5*Reguladora.troca-15, 3);
			tempo = ((new Date()).time-Reguladora.inicio)/60000;
			min = Math.floor(tempo)%60;
			h = Math.floor(tempo/60);
			root["txt_tempo"].text = Reguladora.formatar_num(h, 2)+":"+Reguladora.formatar_num(min, 2);
			root["mc_soldado"].gotoAndStop(Reguladora.vez.id);
			root["txt_jogando"].text = "Jogando: Exército "+cores[Reguladora.vez.id].toUpperCase();
		}
		
		// Destaca os territórios desse continente
		static public function destacar_continente(cont:Continente):void {
			var terras:Object, i:String;
			terras = Relacao.get_relacoes(cont, Relacao.CONTINENTE);
			for (i in terras) {
				atualizar_territorio(terras[i], {"fundo" : 5});
			}
			continente_destacado = cont;
		}
		
		// Mostra a tela de fim de jogo
		static public function mostrar_fim():void {
			var i:String, j:int = 1;
			
			root["mc_fundo_janelas"].visible = true;
			root["mc_janela_fim"].visible = true;
			root["mc_janela_fim"]["mc_soldado"].gotoAndStop(Reguladora.ganhador.id);
			for (i in jogadores) {
				if (jogadores[i].jogou) {
					root["mc_janela_fim"]["mc_fundo"+j].gotoAndStop(jogadores[i].id+1);
					root["mc_janela_fim"]["mc_objetivo"+j].visible = true;
					root["mc_janela_fim"]["mc_objetivo"+j].gotoAndStop(Relacao.get_relacao(jogadores[i], Relacao.OBJETIVO).id);
					j++;
				}
			}
			for (; j<=jogadores.length; j++) {
				root["mc_janela_fim"]["mc_fundo"+j].gotoAndStop(1);
				root["mc_janela_fim"]["mc_objetivo"+j].visible = false;
			}
			(new SomFim()).play();
		}
		
		// Monta o formulário com os dados corretos
		static public function montar_formulario():void {
			var i:String;
			
			// Faz o backup das informações
			Reguladora.fazer_backup();
			
			for (i in jogadores) {
				if (jogadores[i].jogou) {
					if (jogadores[i].humano) {
						root["mc_luz"+i].gotoAndStop(2);
					} else {
						root["mc_luz"+i].gotoAndStop(3);
					}
					root["txt_nome"+i].text = jogadores[i].nome;
				} else {
					root["mc_luz"+i].gotoAndStop(1);
					root["txt_nome"+i].text = "";
				}
				
				// Cria os botões
				root["mc_botao"+i].addEventListener(MouseEvent.CLICK, montar_opcoes);
			}
			
			root["mc_cor"].gotoAndStop(7);
			
			// Define os comandos dos sliders
			root["slider_agressividade"].addEventListener(SliderEvent.CHANGE, aplicar_mudanca);
			root["slider_objetividade"].addEventListener(SliderEvent.CHANGE, aplicar_mudanca);
			root["slider_sorte"].addEventListener(SliderEvent.CHANGE, aplicar_mudanca);
			root["slider_velocidade"].addEventListener(SliderEvent.CHANGE, aplicar_mudanca);
			root["slider_velocidade"].value = Reguladora.velocidade;
			root["slider_volume"].addEventListener(SliderEvent.CHANGE, aplicar_mudanca);
			root["slider_volume"].value = SoundMixer.soundTransform.volume;
			
			// Define o comando do checkbox
			root["check_computador"].addEventListener(Event.CHANGE, aplicar_mudanca2);
			
			// Define o comando do input
			root["input_nome"].addEventListener(Event.CHANGE, aplicar_mudanca3);
			
			// Define os botões
			root["bt_pronto"].addEventListener(MouseEvent.CLICK, botao);
			root["bt_convidar"].addEventListener(MouseEvent.CLICK, botao);
			root["bt_retornar"].addEventListener(MouseEvent.CLICK, botao);
			root["bt_iniciar"].addEventListener(MouseEvent.CLICK, botao);
			root["bt_editar_mundo"].addEventListener(MouseEvent.CLICK, botao);
			root["bt_abandonar"].visible = editando_jogo;
			root["bt_abandonar"].addEventListener(MouseEvent.CLICK, botao);
			
			montar_opcoes();
		}
		
		// Monta as opções do jogador selecionado
		static public function montar_opcoes(e:MouseEvent=null):void {
			var jog:Jogador;
			if (e === null) {
				jog = jogadores[0];
			} else {
				jog = jogadores[int(e.currentTarget.name.substr(-1))];
			}
			root["mc_cor"].gotoAndStop(jog.id);
			root["input_nome"].text = jog.nome;
			root["slider_agressividade"].value = jog.agressividade;
			root["slider_agressividade"].enabled = !jog.humano;
			root["slider_objetividade"].value = jog.objetividade;
			root["slider_objetividade"].enabled = !jog.humano;
			root["slider_sorte"].value = jog.sorte;
			root["check_computador"].selected = !jog.humano;
		}
		
		// Aplica a mudança feita por um slider
		static public function aplicar_mudanca(e:SliderEvent):void {
			var prop:String = e.target.name.substr(7);
			var jog:Jogador = jogadores[root["mc_cor"].currentFrame-1];
			if (prop == "volume") {
				SoundMixer.soundTransform = new SoundTransform(e.value);
			} else if (prop == "velocidade") {
				Reguladora.velocidade = e.value;
			} else {
				jog[prop] = e.value;
			}
		}
		
		// Aplica a mudança feita pelo checkbox
		static public function aplicar_mudanca2(e:Event):void {
			var jog:Jogador = jogadores[root["mc_cor"].currentFrame-1];
			jog.humano = !root["check_computador"].selected;
			if (jog.jogou) {
				root["mc_luz"+String(jog.id-1)].gotoAndStop(jog.humano ? 2 : 3);
			}
			root["slider_agressividade"].enabled = !jog.humano;
			root["slider_objetividade"].enabled = !jog.humano;
		}
		
		// Aplica a mudança feita pelo input
		static public function aplicar_mudanca3(e:Event):void {
			var jog:Jogador = jogadores[root["mc_cor"].currentFrame-1];
			jog.nome = root["input_nome"].text;
			if (jog.jogou) {
				root["txt_nome"+String(jog.id-1)].text = jog.nome;
			}
		}
		
		// Executa um comando quando um botão for clicado
		static public function botao(e:MouseEvent):void {
			var nome:String = e.target.name;
			var jog:Jogador, i:int, j:String;
			
			if (nome == "bt_pronto") {
				// Inclui ou exclui o jogador do jogo
				jog = jogadores[root["mc_cor"].currentFrame-1];
				if (jog.jogou) {
					jog.jogou = false;
					jog.ativo = false;
					root["mc_luz"+String(jog.id-1)].gotoAndStop(1);
					root["txt_nome"+String(jog.id-1)].text = "";
				} else {
					jog.jogou = true;
					jog.ativo = true;
					root["mc_luz"+String(jog.id-1)].gotoAndStop(jog.humano ? 2 : 3);
					root["txt_nome"+String(jog.id-1)].text = jog.nome;
				}
			} else if (nome == "bt_convidar") {
				// Adiciona um jogador aleatório ao jogo
				for (j in jogadores) {
					if (jogadores[j].jogou == false) {
						j = "sim";
						break;
					}
				}
				if (j != "sim") {
					return;
				}
				
				do {
					i = Math.floor(Math.random()*6);
				} while (jogadores[i].jogou);
				jogadores[i].jogou = true;
				jogadores[i].ativo = true;
				jogadores[i].humano = false;
				root["mc_luz"+String(i)].gotoAndStop(3);
				root["txt_nome"+String(i)].text = jogadores[i].nome;
				
				if (i == root["mc_cor"].currentFrame-1) {
					root["check_computador"].selected = true;
					root["slider_agressividade"].enabled = true;
					root["slider_objetividade"].enabled = true;
				}
			} else if (nome == "bt_retornar") {
				// Restaura o backup e volta para a página anterior
				Reguladora.restaurar_backup();
				if (editando_jogo) {
					root.nextFrame();
					Reguladora.continuar_jogo();
					editando_jogo = false;
				} else {
					root.prevFrame();
				}
			} else if (nome == "bt_iniciar") {
				// Inicia o jogo
				i = 0;
				for (j in jogadores) {
					if (jogadores[j].jogou) {
						i++;
					}
				}
				
				if (i>1) {
					root.nextFrame();
					if (editando_jogo) {
						Reguladora.continuar_jogo();
						editando_jogo = false;
					} else {
						Reguladora.iniciar_jogo();
					}
				}
			} else if (nome == "bt_editar_mundo") {
				// Se o jogo ainda não começou, então distribui os territorios
				if (!editando_jogo) {
					i = 0;
					for (j in jogadores) {
						if (jogadores[j].jogou) {
							i++;
						}
					}
					
					if (i<2) {
						return;
					}
				}
				// Vai para a tela de jogo, porém para edita-lo
				editando_mundo = true;
				for (j in jogadores) {
					if (jogadores[j].jogou) {
						jogadores[j].ativo = true;
					}
				}
				root.nextFrame();
				if (editando_jogo) {
					Reguladora.continuar_jogo(false);
				} else {
					Reguladora.iniciar_jogo(false);
				}
			} else if (nome == "bt_abandonar") {
				editando_jogo = false;
				root.prevFrame();
			}
		}
		
		// Configura os botões dos territórios
		static public function configurar_botoes():void {
			var i:String;
			
			for (i in territorios) {
				root[territorios[i].mc].addEventListener(MouseEvent.CLICK, Usuario.botao_territorio);
			}
		}
	}
}