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.Enseignant;
import model.QCM;
import model.Question;
import model.Reponse;
import model.Utilisateur;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class HandlerQCM extends DefaultHandler {
	private int niveau = 0;
	private int balise = 0;
	private int id = 0;
	private ArrayList<Utilisateur> lUtil;
	
	private String libelle;
	private String libelle_qu;
	private String libelle_r;
	private boolean prive = false;
	private boolean vraie = false;
	private Enseignant createur;
	private ArrayList<Question> lQuestions;
	private ArrayList<Reponse> lReponses;
	
	private ArrayList<QCM> liste;
	
	public HandlerQCM(ArrayList<Utilisateur> lUtil) {
		super();
		this.liste = new ArrayList<QCM>();
		this.lUtil = lUtil;
	}
	
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if (qName.equals("qcm")) {
			lQuestions = new ArrayList<Question>();
			niveau = 1;
		} else if (qName.equals("libelle")) {
			switch (niveau) {
			case 1 : balise = 1;
			break;
			case 2 : balise = 3;
			break;
			case 3 : balise = 4;
			break;
			}
		} else if (qName.equals("createur")) {
			balise = 2;
		} else if (qName.equals("question")) {
			lReponses = new ArrayList<Reponse>();
			niveau = 2;
		} else if (qName.equals("reponse")) {
			niveau = 3;
		} else if (qName.equals("prive")) {
			prive = true;
		} else if (qName.equals("vraie")) {
			vraie = true;
		} else if (qName.equals("id")) {
			balise = 5;
		}
	}
	
	public void characters(char ch[], int start, int length) throws SAXException {
		String input = new String(ch, start, length);
		switch (balise) {
		case 1 : this.libelle = input;
		break;
		case 2 : this.createur = (Enseignant) HandlerUtilisateurs.getUtilisateur(input, this.lUtil);
		break;
		case 3 : this.libelle_qu = input;
		break;
		case 4 : this.libelle_r = input;
		break;
		case 5 : this.id = Integer.parseInt(input);
		}
	}
	
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (qName.equals("qcm")) {
			ArrayList<Question> lqu_tmp = new ArrayList<Question>();
			lqu_tmp.addAll(lQuestions);
			this.liste.add(new QCM(this.libelle, this.prive, this.createur, lqu_tmp));
			lQuestions.clear();
			prive = false;
			niveau = 0;
		} else if (qName.equals("libelle")) {
			balise = 0;
		} else if (qName.equals("id")) {
			balise = 0;
		} else if (qName.equals("createur")) {
			balise = 0;
		} else if (qName.equals("question")) {
			ArrayList<Reponse> lr_tmp = new ArrayList<Reponse>();
			lr_tmp.addAll(lReponses);
			this.lQuestions.add(new Question(libelle_qu, lr_tmp));
			lReponses.clear();
			niveau = 1;
		} else if (qName.equals("reponse")) {
			this.lReponses.add(new Reponse(libelle_r, vraie, id));
			vraie = false;
			niveau = 2;
		}
	}
	
	public ArrayList<QCM> getListe() {
		return this.liste;
	}
	
	public static ArrayList<QCM> getOwnAndPublic(Enseignant e, ArrayList<QCM> lQCM) {
		int i;
		ArrayList<QCM> res = new ArrayList<QCM>();
		for (i = 0 ; i < lQCM.size() ; i++) {
			if (!lQCM.get(i).isPrive() || lQCM.get(i).getCreateur().equals(e)) {
				res.add(lQCM.get(i));
			}
		}
		return res;
	}
	
	public static QCM getQCM(String libelle, ArrayList<QCM> lQCM) {
		int i = 0;
		String tmp = "";
		while (!(tmp.equals(libelle)) && (i < lQCM.size())) {
			tmp = lQCM.get(i).getLibelle();
			i++;
		}
		if (tmp.equals(libelle)) {
			return lQCM.get(i-1);
		} else {
			return null;
		}
	}
	
	public void updateDatabase() {
		int i;
		try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("bin/data/QCM.xml"), "utf-8"))) {
			writer.write("<?xml version=\"1.0\"?>\n");
			writer.write("<qcms>\n	");
			for (i = 0 ; i < this.liste.size() ; i++) {
				this.writeQCM(writer,this.liste.get(i));
			}
		    writer.write("\n</qcms>");
		} catch (IOException e) {
		    System.out.println("Error: Database update failed.");
		}  
	}
	
	private void writeQCM(Writer w, QCM qcm) throws IOException {
		int i;
		w.write("<qcm>\n		");
		w.write("<libelle>" + qcm.getLibelle() + "</libelle>\n		");
		w.write("<createur>" + qcm.getCreateur().getLogin() + "</createur>\n		");
		if (qcm.isPrive()) {
			w.write("<prive/>\n		");
		}
		for (i = 0 ; i < qcm.getQuestions().size() ; i++) {
			this.writeQuestions(w,qcm.getQuestions().get(i));
		}
		w.write("\n	</qcm>\n	");
	}
	
	private void writeQuestions(Writer w, Question q) throws IOException {
		int i;
		w.write("<question>\n			");
		w.write("<libelle>" + q.getLibelle() + "</libelle>\n			");
		for (i = 0 ; i < q.getReponses().size() ; i++) {
			this.writeReponses(w,q.getReponses().get(i));
		}
		w.write("\n		</question>\n		");
	}
	
	private void writeReponses(Writer w, Reponse r) throws IOException {
		w.write("<reponse>\n				");
		w.write("<id>" + r.getId() + "</id>\n			");	
		w.write("<libelle>" + r.getLibelle() + "</libelle>\n				");
		if (r.isVraie()) {
			w.write("<vraie/>");
		}
		w.write("\n			</reponse>\n			");
	}
}
