package auxiliar;



import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder; 

import algoritmo.Agente;
import algoritmo.Alvo;
import algoritmo.ConjuntoDeAgentes;
import algoritmo.ConjuntoDeAlvos;
import algoritmo.ConjuntoDeObstaculos;
import algoritmo.EspacoDeBusca;
import algoritmo.Obstaculo;

public class XMLDealer {

	
	  
	public XMLDealer(){
		
		
	}
	 public static void escrever(String caminhoImagemInicial, 
			 					String caminhoImagemAmbiente, 
			 					String nomeArquivo,
			 					EspacoDeBusca espacoDeBusca) {  
		 
		 
		   ConjuntoDeAgentes conjuntoDeAgentes = espacoDeBusca.getAgentes();
		   ConjuntoDeAlvos conjuntoDeAlvos = espacoDeBusca.getAlvos();
		   ConjuntoDeObstaculos conjuntoDeObstaculos = espacoDeBusca.getObstaculos();
		   
			//Declara��o dos elementos que ir�o compor a estrutura do documento.  
		   int pontoIndex;
		   String nomeProjeto;
		   
		   if(nomeArquivo.contains(".")){
			   pontoIndex = nomeArquivo.indexOf(".");
			   nomeProjeto= nomeArquivo.substring(0, pontoIndex);
		   }
		   else{
			   nomeProjeto=nomeArquivo;
		   }
		   Element projeto = new Element("projeto");  
		   projeto.setAttribute("nome",nomeProjeto );
		   
		   Element imagemInicial = new Element("imagemInicial");  
		   imagemInicial.setAttribute("nome",nomeArquivo);
		   imagemInicial.setAttribute("source"  , caminhoImagemInicial);
		   
		   Element imagemAmbiente = new Element("imagemAmbiente");  
		   nomeArquivo = nomeArquivo.replaceAll(nomeProjeto, nomeProjeto+"Ambiente");
		   imagemAmbiente.setAttribute("nome",nomeArquivo);
		   imagemAmbiente.setAttribute("source" , caminhoImagemAmbiente);
		   
		   
		   
		   Element alvos = new Element("conjuntoAlvos");  
		   Element[] alvo =  new Element[conjuntoDeAlvos.getAlvos().size()];
		   
		   Vector<Alvo> alvosSet = conjuntoDeAlvos.getAlvos();
		   for(int i=0; i<conjuntoDeAlvos.getAlvos().size(); i++){
			   alvo[i]=new Element("alvo"); 
			   alvo[i].setAttribute("id", ""+alvosSet.get(i).getId());
			   Element[] eleListPontosAlvo = new Element[alvosSet.get(i).getListaDePontos().size()];
			   
			   Vector<double[]> listaPontosAlvo = alvosSet.get(i).getListaDePontos();
			   for(int j=0; j<eleListPontosAlvo.length; j++){
				   eleListPontosAlvo[j] = new Element("ponto");
				   eleListPontosAlvo[j].setAttribute("x", "" + listaPontosAlvo.get(j)[0]);
				   eleListPontosAlvo[j].setAttribute("y", "" + listaPontosAlvo.get(j)[1]);
				   
				   alvo[i].addContent(eleListPontosAlvo[j]);
			   }
			   
			   alvos.addContent(alvo[i]);
		   }
		 
		   
		   Element obstaculos = new Element("conjuntoObstaculos");  
		   Element[] obstaculo =  new Element[conjuntoDeObstaculos.getObstaculos().size()];
		   
		   Vector<Obstaculo> obstaculosSet = conjuntoDeObstaculos.getObstaculos();
		   for(int i=0; i<conjuntoDeObstaculos.getObstaculos().size(); i++){
			   obstaculo[i]=new Element("obstaculo"); 
			   obstaculo[i].setAttribute("id", ""+obstaculosSet.get(i).getId());
			   Element[] eleListPontosObstaculo = new Element[obstaculosSet.get(i).getListaDePontos().size()];
			   
			   Vector<double[]> listaPontosObstaculo = obstaculosSet.get(i).getListaDePontos();
			   for(int j=0; j<eleListPontosObstaculo.length; j++){
				   eleListPontosObstaculo[j] = new Element("ponto");
				   eleListPontosObstaculo[j].setAttribute("x", "" + listaPontosObstaculo.get(j)[0]);
				   eleListPontosObstaculo[j].setAttribute("y", "" + listaPontosObstaculo.get(j)[1]);
				   
				   obstaculo[i].addContent(eleListPontosObstaculo[j]);
			   }
			   
			   obstaculos.addContent(obstaculo[i]);
		   }
		   
		   Element agentes = new Element("conjuntoAgentes");  
		   Element[] agente = new Element[conjuntoDeAgentes.getNumAgentes()];
		   
		   for(int i=0; i<agente.length; i++){
			   Agente agt = conjuntoDeAgentes.get(i);
			   agente[i]= new Element("agente");
			   agente[i].setAttribute("id", ""+ agt.getIdAgente());
			   agente[i].setAttribute("x", ""+ agt.getPosicao()[0]);
			   agente[i].setAttribute("y", ""+ agt.getPosicao()[1]);
			   
			   agentes.addContent(agente[i]);
		   }
		   
		   
		   Element espacoBusca = new Element("espacoDeBusca");  
		   espacoBusca.setAttribute("xMax", ""+espacoDeBusca.getLimiteMaxCoordX());
		   espacoBusca.setAttribute("yMax", ""+espacoDeBusca.getLimiteMaxCoordY());
		   
		   Element melhorSolucaoEncontrada = new Element("melhorSolucao"); 
		   melhorSolucaoEncontrada.setAttribute("fitness", ""+ espacoDeBusca.getMelhorSolucaoPossivel().getFitness());
		   melhorSolucaoEncontrada.setAttribute("x", ""+ espacoDeBusca.getMelhorSolucaoPossivel().getPosicao()[0]);
		   melhorSolucaoEncontrada.setAttribute("y", ""+ espacoDeBusca.getMelhorSolucaoPossivel().getPosicao()[1]);
		   
		   espacoBusca.addContent(melhorSolucaoEncontrada);
		  
		  
		   //imagemInicial.setText(caminhoImagemInicial);  
		   //imagemAmbiente.setText(caminhoImagemAmbiente);   
		   
		   projeto.addContent(imagemInicial);  
		   projeto.addContent(imagemAmbiente);  
		   projeto.addContent(alvos);  
		   projeto.addContent(obstaculos);
		   projeto.addContent(agentes);
		   projeto.addContent(espacoBusca);
		   
		   //Criando o documento XML (montado)  
		   Document doc = new Document();  
		   doc.setRootElement(projeto);  
		  
		 
		
			try {  
		        Writer out = new BufferedWriter(new OutputStreamWriter(  
		            new FileOutputStream("projetos/"+ nomeProjeto+ ".xml"), "UTF8"));  
		           
		        XMLOutputter xout = new XMLOutputter();  
		        xout.output(doc,out);  
		        xout.output(doc, System.out);
		          
		        System.out.println("XML criado com sucesso!\n---------------------------");  
		    } catch (UnsupportedEncodingException e) {  
		        e.printStackTrace();  
		    } catch (IOException e) {  
		        e.printStackTrace();  
			} 
	 }
	
	 public static void ler(String nomeArquivo, EspacoDeBusca espBusca) { 
		 
		   EspacoDeBusca espacoDeBusca = espBusca;
		   ConjuntoDeAgentes conjuntoDeAgentes = espacoDeBusca.getAgentes();
		   ConjuntoDeObstaculos conjuntoDeObstaculos = espacoDeBusca.getObstaculos();
		   ConjuntoDeAlvos conjuntoDeAlvos = espacoDeBusca.getAlvos();
		   
		   //Aqui voc� informa o nome do arquivo XML.  
		   File f = new File("projetos/" + nomeArquivo);  
		  
		   //Criamos uma classe SAXBuilder que vai processar o XML4  
		   SAXBuilder sb = new SAXBuilder();  
		  
		   //Este documento agora possui toda a estrutura do arquivo.  
		   Document d;
			try {
				d = sb.build(f);
				//Recuperamos o elemento root  
				Element projeto = d.getRootElement();  
			  
				//Recuperamos os elementos filhos (children)  
				List elements = projeto.getChildren();  
				  
			  
				Element eleImagemInicial = (Element) elements.get(0);
				Element eleImagemAmbiente = (Element) elements.get(1);
				Element eleConjuntoAlvos = (Element) elements.get(2);
				Element eleConjuntoObstaculos = (Element) elements.get(3);
				Element eleConjuntoAgentes = (Element) elements.get(4);
				Element eleEspacoDeBusca = (Element) elements.get(5);
				
				System.out.println("Imagem Inicial:"+ eleImagemInicial.getAttributeValue("source"));
				System.out.println("Imagem Anima��o:"+ eleImagemAmbiente.getAttributeValue("source")); 
				
				/*********************La�o iteConjuntoAlvos********************************/
				List eleListAlvos = eleConjuntoAlvos.getChildren();
				Iterator iteConjuntoAlvos = eleListAlvos.iterator();
				 
				List pontosAlvo=null;
				Iterator itePontosAlvo =null;
				System.out.println("Conjunto de Alvos:"); 
				while (iteConjuntoAlvos.hasNext()) {  
					//Cria um alvp
					Element eleAlvo = (Element) iteConjuntoAlvos.next(); 
					int idAlvo = Integer.parseInt(eleAlvo.getAttributeValue("id")); 
					double diametro = Double.parseDouble(eleAlvo.getAttributeValue("diametro")); 
					
					System.out.println("    Alvo id:"+ eleAlvo.getAttributeValue("id"));  
					if( !conjuntoDeAlvos.existeAlvo(idAlvo) ){
						//conjuntoDeAlvos.adicionarAlvo(idAlvo );
					}
								
					pontosAlvo = eleAlvo.getChildren(); 
					itePontosAlvo = pontosAlvo.iterator();
					int i=0;
					//cria os pontos do alvo criado
					while (itePontosAlvo.hasNext()) { 
						Element ponto =  (Element) itePontosAlvo.next();
						System.out.println("\t ["+i+"]\tx:"+ponto.getAttributeValue("x") + "\ty:"+ponto.getAttributeValue("y"));  
						i++;
						double[] posicao = new double[2];
						posicao[0] = Double.parseDouble(eleAlvo.getAttributeValue("x")); 
						posicao[1] = Double.parseDouble(eleAlvo.getAttributeValue("y")); 
						conjuntoDeAlvos.adicionarPonto(posicao,idAlvo );
					}
				}
				
				/*********************La�o iteConjuntoObstaculos********************************/
				List obstaculos = eleConjuntoObstaculos.getChildren();
				Iterator iteConjuntoObstaculos = obstaculos.iterator();
				
				List pontosObstaculo=null;
				Iterator itePontosObstaculo =null;
				System.out.println("Conjunto de Obstaculos:"); 
				while (iteConjuntoObstaculos.hasNext()) {  
					Element obstaculo = (Element) iteConjuntoObstaculos.next();  
					
					System.out.println("    Obstaculo id:"+ obstaculo.getAttributeValue("id"));  
					
					pontosObstaculo = obstaculo.getChildren(); 
					itePontosObstaculo = pontosObstaculo.iterator();
					while (itePontosObstaculo.hasNext()) { 
						Element ponto =  (Element) itePontosObstaculo.next();
						System.out.println("\tx:"+ponto.getAttributeValue("x") + "\ty:"+ponto.getAttributeValue("y"));  
					}
				}
				
				/*********************La�o iteConjuntoAgentes********************************/
				List agentes = eleConjuntoAgentes.getChildren();
				Iterator iteConjuntoAgentes = agentes.iterator();
				
				System.out.println("Conjunto de Agentes:"); 
				while (iteConjuntoAgentes.hasNext()) {  
					Element agente = (Element) iteConjuntoAgentes.next();  
					
					System.out.println("    Agente\tid:" +agente.getAttributeValue("id") 
												+"\tx:"+agente.getAttributeValue("x")	
												+"\ty:"+agente.getAttributeValue("y")
											);  
					
				
				}

				/*********************La�o eleEspacoDeBusca********************************/
				System.out.println("Espa�o de Busca:"
						 				+ "\txMax= "+ eleEspacoDeBusca.getAttributeValue("xMax")
						 				+ "\tyMax= "+ eleEspacoDeBusca.getAttributeValue("yMax"));
				List eleListEspacoDeBusca = eleEspacoDeBusca.getChildren();
				Iterator iteEspacoDeBusca = eleListEspacoDeBusca.iterator();
				System.out.println("Espa�o de Busca:"); 
				while (iteEspacoDeBusca.hasNext()) { 
				   Element melhorSolucaoEncontrada = (Element)iteEspacoDeBusca.next();
				   System.out.println("\tGBest:\tfitness"+ melhorSolucaoEncontrada.getAttributeValue("fitness")
						               +"\tx:" + melhorSolucaoEncontrada.getAttributeValue("x")
						               +"\ty:" + melhorSolucaoEncontrada.getAttributeValue("y")); 
				}
		   
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  
	 }
	  
	public static void main(String[] args) {
		XMLDealer teste = new XMLDealer();
		teste.escrever("CA", "MP",  "Love.xml",
					EspacoDeBusca.getInstance());
		
		teste.ler("Love.xml", EspacoDeBusca.getInstance());
	}
	   

}
