package model.list;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;

import model.Module;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class HandlerModules extends DefaultHandler {
	private int balise = 0;
	private String libelle;
	private String syllabus;
	private ArrayList<String> pere;
	
	private ArrayList<Module> liste;
	private ArrayList<ArrayList<String>> liste_pere;

   public HandlerModules() {
	   super();
	   liste = new ArrayList<Module>();
	   liste_pere = new ArrayList<ArrayList<String>>();
   }
	
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		switch (qName) {
		case "module" : pere = new ArrayList<String>();
		break;
		case "libelle" : balise = 1;
		break;
		case "syllabus" : balise = 2;
		break;
		case "module_pere" : balise = 3;
		break;
		}
	}
	
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (qName.equals("module")) {
			this.liste.add(new Module(libelle, syllabus));
			libelle = "";
			syllabus = "";
			liste_pere.add(pere);
		}
	}
		
	public void characters(char ch[], int start, int length) throws SAXException {
		String input = new String(ch, start, length);
		switch (balise) {
		case 1 : { libelle = input; balise = 0; }
		break;
		case 2 : { syllabus = input; balise = 0; }
		break;
		case 3 : { pere.add(input); balise = 0; }
		break;
		}
	}
	
	public void endDocument() {
		int i;
		int j;
		ArrayList<Module> liste_tmp = new ArrayList<Module>();
		Module mod_tmp;
		
		for (i = 0 ; i < liste.size() ; i++) {
			pere = liste_pere.get(i);
			liste_tmp = new ArrayList<Module>();
			for (j = 0 ; j < pere.size() ; j++) {
				mod_tmp = HandlerModules.getModule(pere.get(j), this.liste);
				if (mod_tmp != null) {
					liste_tmp.add(mod_tmp);
				}
			}
			this.liste.get(i).setPere(liste_tmp);
		}
	}
	
	public void setListe(ArrayList<Module> liste) {
		this.liste = liste;
	}
	
	public ArrayList<Module> getListe() {
		return this.liste;
	}
	
	public void addListe(Module m) {
		this.liste.add(m);
	}
	
	public void removeListe(Module m) {
		this.liste.remove(m);
	}
	
	public static Module getModule(String libelle, ArrayList<Module> liste) {
		int i = 0;
		String tmp = "";
		while (!(tmp.equals(libelle)) && (i < liste.size())) {
			tmp = liste.get(i).getLibelle();
			i++;
		}
		if (tmp.equals(libelle)) {
			return liste.get(i-1);
		} else {
			return null;
		}
	}
	
	public void updateDatabase() {
		int i;
		Module m;
		try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("bin/data/Module.xml"), "utf-8"))) {
			writer.write("<?xml version=\"1.0\"?>\n");
			writer.write("<modules>\n	");
		    for (i = 0 ; i < this.liste.size() ; i++) {
		    	m = this.liste.get(i);
		    	this.writeModule(writer,m);
		    }
		    writer.write("\n</modules>");
		} catch (IOException e) {
		    System.out.println("Error: Database update failed.");
		}  
	}
	
	private void writeModule(Writer w, Module m) throws IOException {
		int i;
		w.write("<module>\n		");
		w.write("<libelle>"+m.getLibelle()+"</libelle>\n		");
		w.write("<syllabus>"+m.getSyllabus()+"</syllabus>\n		");
		if (!m.getPere().isEmpty()) {
			w.write("<pere>\n			");
			for (i = 0 ; i < m.getPere().size(); i++) {
				w.write("<module_pere>"+m.getPere().get(i).getLibelle()+"</module_pere>\n			");
			}
			w.write("\n		</pere>\n		");
		}
		w.write("</module>\n	");
	}
}
