/*
 * Created on 15 avr. 2005
 *
 */
package geonoteOutils;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

/**
 * @author lefevre
 * 
 * Permet l'interaction avec un fichier xml
 * un traceur par fichier xml !!!
 */
public class Traceur {

	protected org.jdom.Document document = null;//new Document(racine);

	protected String chemin = "";
	
	/**
	 * Permet un chargement ulterieur pour permettre la recup du resultat du chargement (echec ...)
	 */
	public Traceur() {
	}
	
	/**
	 * ouvre le fichier demande et construit le TraceurSession correspondant
	 */
	//	public Traceur(String path) {
	//		//chemin = path; fait par "charger"
	//		charger(chemin);
	//	}
	
	/**
	 * creer le TraceurSession correspondant au fichier en parametre
	 */
	public Traceur(String path, String rac) {
		this.chemin = path;
		Element racine = new Element(rac);
		document = new Document(racine);
		//		try
		//		{
		//			XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
		//			sortie.output(document, new FileOutputStream(path,false));
		//		} catch (java.io.IOException e){System.out.println("echec creation du fichier");}
	}
	
	
	/*		//exemple d' Attribut
	 //grâce à la méthode setAttribute
	  Attribute classe = new Attribute("classe","P2");
	  etudiant.setAttribute(classe);
	  */
	
	/**
	 * 	ajouter un element directement a la racine
	 */
	protected void ajouter(String nomElt) {
		Element eltNouvo = new Element(nomElt);
		document.getRootElement().addContent(eltNouvo);
	}
	
	/**
	 * ajoute un element directement a la racine (ou le modif si deja present)
	 */
	public void ajouterElt(String nomElt, String texte) {
		Element eltNouvo = rechercher(document.getRootElement(),nomElt);
		if (eltNouvo == null) {
			eltNouvo = new Element(nomElt);
			document.getRootElement().addContent(eltNouvo);
		}
		if (texte.length() == 0) {
			eltNouvo.setText("vide");
		} else {
			eltNouvo.setText(texte);
		}
	}
	
	/**
	 * Ajoute une annotation a l'elt passé
	 */
//	public void ajouterAnnotation(String nomElt, String annotation) {
//		Element elt = rechercher(document.getRootElement(),nomElt);
//		if (elt != null) {
//			Element annotationElt = new Element("annotation");
//			annotationElt.setText(annotation);
//			elt.addContent(annotationElt);
//		} else {
//			System.out.println("element inexistant");
//		}
//	}
	
	/**
	 * rertourne un tablo contenant  : jour, mois, annee, heure, minute, seconde
	 * @param elt
	 */
	protected int[] exporteDate(Element elt) {
		int[] tab = new int[6];
		tab[0] = Integer.parseInt(rechercher(elt, "jour").getText());
		tab[1] = Integer.parseInt(rechercher(elt, "mois").getText());
		tab[2] = Integer.parseInt(rechercher(elt, "annee").getText());
		tab[3] = Integer.parseInt(rechercher(elt, "heures").getText());
		tab[4] = Integer.parseInt(rechercher(elt, "minutes").getText());
		tab[5] = Integer.parseInt(rechercher(elt, "secondes").getText());
		return tab;
	}
	
	/**
	 * 
	 * @param elt
	 * @return les fichiers datés (de donnees) contenus ds l'elt
	 */
	protected ArrayList exporteFichiersDates(Element elt) {
		ArrayList liste = new ArrayList();
		if (elt != null) {
			if (elt.getName().matches("fichier")) {
//				System.out.println("elt path : "+elt.getText());
				Element pere = elt.getParentElement();
				int[] date = exporteDate(pere);
				liste.add(elt.getText());//+" (le "+date[0]+"/"+date[1]+"/"+date[2]+" à "+date[3]+":"+date[4]+":"+date[5]+")");
			} else {
				List listElements = elt.getChildren(); //liste des fils de l'element ou se fait la recherche
				//	On crée un Iterator sur notre liste
				Iterator i = listElements.iterator();
				while (i.hasNext())	{
					Element courant = (Element)i.next();
					liste.addAll(exporteFichiersDates(courant));
				}
			}
		}
		//System.out.println("liste path : "+liste);
		return liste;
	}

	/**
	 * ajoute une date a la racine
	 */
	public void ajouterDate(String j, String m, String a, String h, String min, String s) {
		ajouterDate(document.getRootElement(), j, m, a, h, min, s);
	}
	
	/**
	 * ajoute la date a un elt
	 */
	protected void ajouterDate(Element elt, String j, String m, String a, String h, String min, String s) {
		Element date = new Element("date");
		Element jour = new Element("jour");
		jour.setText(j);
		Element mois = new Element("mois");
		mois.setText(m);
		Element annee = new Element("annee");
		annee.setText(a);
		Element heure = new Element("heures");
		heure.setText(h);
		Element minute = new Element("minutes");
		minute.setText(min);
		Element seconde = new Element("secondes");
		seconde.setText(s);
		date.addContent(jour);
		date.addContent(mois);
		date.addContent(annee);
		date.addContent(heure);
		date.addContent(minute);
		date.addContent(seconde);
		elt.addContent(date);
	}
	
	/**
	 * retourne le type du doc (la racine du fichier xml)
	 * @return
	 */	
	public String exporteType() {
		return document.getRootElement().getName();
	}
	
	/**
	 * Permet de recuperer la valeur d'un elt dans le fichier xml 
	 */
	public String exporteInfo(String elt) {
		Element cible = rechercher(document.getRootElement(), elt);
		if (cible != null) {
			return cible.getText();
		} else {
			return null;
		}
	}
	
	/**
	 * @param nomFichier
	 * @return l'elt "donnee" qui a le bon nom de fichier
	 */
	protected Element rechercheDonnee(Element elt, String nomFichier) {
		Element cible = null; //elt recherché
		if (elt != null) {
			if(elt.getName().matches("donnee")){
				Element elt2 = rechercher(elt, "fichier");
				if (elt2 != null) {
					String text = elt2.getText();
//System.out.println("texte : "+text);
//System.out.println("chemin : "+chemin);
					if (text.equals(nomFichier)) cible = elt;
				}
			} else {
				List listElements = elt.getChildren(); //liste des fils de l'element ou se fait la recherche
				boolean trouvé = false;//pour arreter le parcours
				//	On crée un Iterator sur notre liste
				Iterator i = listElements.iterator();
				while((i.hasNext()) && !trouvé)	{
					//On recrée l'Element courant à chaque tour de boucle afin de pouvoir utiliser les méthodes propres aux Element comme :
					//selectionner un noeud fils, modifier du texte, etc...
					Element courant = (Element)i.next();
					// si l'elt courant a le bon nom alors on arrete
					cible = rechercheDonnee(courant, nomFichier);
					if (cible != null) {
						trouvé = true;
					}
				}
			}
		}
		return cible;
	}
	
	/**
	 * Recherche la PREMIERE occurance de l'element cherché ds l'arborescence de elt (RECURSIF)
	 */
	protected Element rechercher(Element elt, String cherché) {
		Element cible = null; //elt recherché
		if (elt != null) {
			if(elt.getName().equals(cherché)){
				cible = elt;
			} else {
				List listElements = elt.getChildren(); //liste des fils de l'element ou se fait la recherche
				boolean trouvé = false;//pour arreter le parcours
				
				//	On crée un Iterator sur notre liste
				Iterator i = listElements.iterator();
				while((i.hasNext()) && !trouvé)
				{
					//On recrée l'Element courant à chaque tour de boucle afin de pouvoir utiliser les méthodes propres aux Element comme :
					//selectionner un noeud fils, modifier du texte, etc...
					Element courant = (Element)i.next();
					// si l'elt courant a le bon nom alors on arrete
					cible = rechercher(courant, cherché);
					if (cible != null) {
						trouvé = true;
					}
				}
			}
		}
		return cible;
	}
	
	/**
	 * retourne un tab de 3 elts : h, m, s
	 */
	protected int[] horodatage() {
		Date date = new Date();
		String[] dateTab = date.toString().split(" ");
		String[] dateH = dateTab[3].split(":");
		int[] tabI = new int[3];
		tabI[0] = Integer.parseInt(dateH[0]);
		tabI[1] = Integer.parseInt(dateH[1]);
		tabI[2] = Integer.parseInt(dateH[2]);
		return tabI;
	}
	
	//	ajouter un element "nomElt" a l'element "eltCible"
	//	public void ajouterSousElt(String nomElt, String eltCible) {
	//		Element cible = null;
	//		cible = rechercher(document.getRootElement(), eltCible);
	//		if (cible != null) {
	//			//creation de l'element a ajouter
	//			Element eltNouvo = new Element(nomElt);
	//			//ajout
	//			cible.addContent(eltNouvo);
	//		}
	//	}
	
	//ajouter un element "nomElt" avec le texte a l'element "eltCible"
	//	public void ajouterSousElt(String nomElt, String eltCible, String texte) {
	//		Element cible = null;
	//		cible = rechercher(document.getRootElement(), eltCible);
	//		if (cible != null) {
	//			//creation de l'element a ajouter
	//			Element eltNouvo = new Element(nomElt);
	//			eltNouvo.setText(texte);
	//			//ajout
	//			cible.addContent(eltNouvo);
	//		}
	//		else {
	//System.out.println("pas de cible pour l'ajout");			
	//		}
	//	}
	
	/**
	 * retourne l'arret dont l'id correspond a idArret
	 * @param histo
	 * @param idArret
	 */
	protected Element rechercheArret(Element elt, String idArret) {
		Element cible = null;
		if (elt != null) {
			List listElements = elt.getChildren(); //liste des fils de l'element ou se fait la recherche
			boolean trouvé = false;//pour arreter le parcours
			//	On crée un Iterator sur notre liste
			Iterator i = listElements.iterator();
			while((i.hasNext()) && !trouvé)
			{
				//On recrée l'Element courant à chaque tour de boucle afin de pouvoir utiliser les méthodes propres aux Element comme :
				//selectionner un noeud fils, modifier du texte, etc...
				Element courant = (Element)i.next();
				if (courant.getName()=="arret") {
					Element id = rechercher(courant,"id"); //on recherche l'elt stockant l'id de l'arret
					if (id.getText().matches(idArret)) {
						trouvé = true;
						cible = courant;
					}
				}
			}
		}
		return cible;
	}
	
	/**
	 * retourne la liste des Arrets contenu par elt
	 * @param histo
	 * @param idArret
	 */
	protected ArrayList rechercheArrets(Element elt) {
		ArrayList cible = new ArrayList();
		if (elt != null) {
			List listElements = elt.getChildren(); //liste des fils de l'element ou se fait la recherche
			//	On crée un Iterator sur notre liste
			Iterator i = listElements.iterator();
			while (i.hasNext())
			{
				//On recrée l'Element courant à chaque tour de boucle afin de pouvoir utiliser les méthodes propres aux Element comme :
				//selectionner un noeud fils, modifier du texte, etc...
				Element courant = (Element)i.next();
				if (courant.getName()=="arret") {
					cible.add(courant);
				}
			}
		}
		return cible;
	}
	
	/**
	 *  affichage dans la console
	 */
	public void afficher() {
		try
		{
			//On utilise ici un affichage classique avec getPrettyFormat()
			XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
			sortie.output(document, System.out);
		}
		catch (java.io.IOException e){}
	}
	
	/**
	 * enregistrement dans le fichier xml
	 */
	public boolean enregistrer() {
		try
		{
			//On utilise ici un affichage classique avec getPrettyFormat()
			XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
			sortie.output(document, new FileOutputStream(chemin,false));
			return true;
		} catch (java.io.IOException e){
			System.out.println("echec enregistrement du fichier : "+chemin);
			return false;
		}
	}
	
	//	/**
	//	 * chargement du fichier correspondant au chemin (attribut)
	//	 */
	//	public boolean chargerConfig(URL path) {
	//		SAXBuilder sxb = new SAXBuilder();
	//		try
	//		{
	//			//On crée un nouveau document JDOM avec en argument le fichier XML
	//			document = sxb.build(path);
	//			return true;
	//		}
	//		catch(Exception e){
	//			System.out.println("echec chargement du fichier : "+path);
	//			return false;
	//		}
	//	}
	
	public boolean charger(String path) {
		SAXBuilder sxb = new SAXBuilder();
		try
		{
			//System.out.println("chargement du fichier : "+path);
			//On crée un nouveau document JDOM avec en argument le fichier XML
			document = sxb.build(path);
			chemin = path;
			return true;
		}
		catch(Exception e){
			System.out.println("echec chargement du fichier : "+path);
			return false;
		}
	}
	
} //fin de classe
