package code;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Iterator;

import org.json.JSONException;
import org.json.JSONObject;

public class Automa {
	private JSONObject jsonObject; //tabella che descrive l'automa
	private Hashtable<String,Integer> deltaSensori; // ad ogni sensore di movimento e' associato il valore di delta
	private int statoAttuale;
	private String statoInterruttore;
	private String statoSuono;
	private static final String FILE_AUTOMA = "../res/automa.json";
	public static final String FILE_STATO = "../res/stato.json";
	private static final String FILE_DELTA_SENSORI = "../res/CONF/deltaSensoriMovimento.json";
	
	
	public Automa() throws JSONException, IOException {
		this.jsonObject = new JSONObject(Helper.leggiFile(FILE_AUTOMA));
		setStati(false);
		riempiHashTable();
	}
	
	
	private synchronized void setStati(boolean write) throws JSONException, IOException {
		JSONObject statoJson = new JSONObject(Helper.leggiFile(FILE_STATO));
		if(write) {
			// devo aggiornare lo stato nel FILE_STATO
			Helper.scriviFile(statoJson.put("stato",this.statoAttuale), FILE_STATO);
		}
		else {
			// devo capire in quale stato mi trovo e impostare di conseguenza lo statoInterruttore e lo statoSuono
			this.statoAttuale = statoJson.getInt("stato");
			aggiornaInterruttoreESuono();	
		}
	}
	
	
	private void riempiHashTable() throws JSONException, IOException {
		this.deltaSensori = new Hashtable<String, Integer>();
		JSONObject jsObj = new JSONObject(Helper.leggiFile(FILE_DELTA_SENSORI));
		Iterator<String> keys = jsObj.keys();
		while(keys.hasNext()) {
			String key = keys.next();
			int value = jsObj.getInt(key);
			deltaSensori.put(key, value);
		}
	}
	
//	private synchronized void scriviFile(JSONObject json, String path) throws IOException {
//		BufferedWriter b = new BufferedWriter(new FileWriter(path));
//		b.write(json.toString());
//		b.close();
//	}
	
	
//	private String leggiFile(String path) throws IOException {
//		String line;
//		String answer = "";
//		FileReader fileReader = new FileReader(path);
//		BufferedReader bufferedReader = new BufferedReader(fileReader);
//		while((line = bufferedReader.readLine()) != null) {
//			answer += line;
//		}
//		bufferedReader.close();
//		return answer;
//	}
	
	public int getDelta(String nomeSensore) {
		return deltaSensori.get(nomeSensore);
	}
	
// SERVIRA FORSE PER LA PERSISTENZA	
//	private synchronized void calcolaStato(String newStatoInterruttore, String newStatoSuono) throws JSONException {
//		Iterator<String> keys = jsonObject.keys();
//		while(keys.hasNext()) {
//			String key = keys.next();
//			JSONObject riga = jsonObject.getJSONObject(key);
//			if(riga.getString("out0").equals(newStatoInterruttore) && riga.getString("out1").equals(newStatoSuono)) {
//				this.statoAttuale = riga.getInt("stato");
//				this.statoInterruttore = newStatoInterruttore;
//				this.statoSuono = newStatoSuono;
//			}
//		}
//	}
	
	
	// e' cambiato lo stato dell'interruttore, per cui cerco nel file json in quale nuovo stato devo andare
	private synchronized void calcolaNuovoStatoMsgFromInterruttore(String newStatoInterruttore) throws JSONException, IOException {
		Iterator<String> keys = jsonObject.keys();
		while(keys.hasNext()) {
			String key = keys.next();
			JSONObject riga = jsonObject.getJSONObject(key);
			if(riga.getInt("stato")==statoAttuale) {
				this.statoAttuale = riga.getInt("cmd"+newStatoInterruttore);
				setStati(true); //scrivo nel file il nuovo stato in cui mi trovo
				aggiornaInterruttoreESuono();
			}
		}
	}
	//in base allo stato attuale dell'antifurto, calcolo lo stato dell'interruttore e del suono
	private synchronized void aggiornaInterruttoreESuono() throws JSONException {
		Iterator<String> keys = jsonObject.keys();
		while(keys.hasNext()) {
			String key = keys.next();
			JSONObject riga = jsonObject.getJSONObject(key);
			if(riga.getInt("stato")==statoAttuale) {
				this.statoInterruttore = riga.getString("out0");
				this.statoSuono = riga.getString("out1");
			}
		}
	}
	
	// e' cambiato lo stato del suono, per cui cerco nel file json in quale nuovo stato devo andare
	private synchronized void calcolaNuovoStatoMsgFromSuono(String newStatoSuono) throws JSONException, IOException {
		String jsonKey = "";
		if(newStatoSuono.equals("on"))
			jsonKey = "eventValMaggioreSoglia";
		else
			jsonKey = "eventValMinoreSoglia";
		Iterator<String> keys = jsonObject.keys();
		while(keys.hasNext()) {
			String key = keys.next();
			JSONObject riga = jsonObject.getJSONObject(key);
			if(riga.getInt("stato")==statoAttuale) {
				this.statoAttuale = riga.getInt(jsonKey);
				setStati(true); //scrivo nel file il nuovo stato in cui mi trovo
				aggiornaInterruttoreESuono();
			}
		}
	}
	
	
	public synchronized void changeStatoInterruttore() throws JSONException, IOException {
		if(statoInterruttore.equals("on"))
			calcolaNuovoStatoMsgFromInterruttore("off");
		else 
			calcolaNuovoStatoMsgFromInterruttore("on");
	}
	
	public synchronized void aggiornaStatoSuono(String newStatoSuono) throws JSONException, IOException {
		calcolaNuovoStatoMsgFromSuono(newStatoSuono);
	}
	
	
	public synchronized String getStatoAutoma() {
		return "{\"stato\":"+statoAttuale+",\"interruttore\":\""+statoInterruttore+"\",\"allarme\":\""+statoSuono+"\"}";
	}
	
	
	public synchronized String getStatoInterruttore() {
		return statoInterruttore;
	}
	
	
	public synchronized String getStatoSuono() {
		return statoSuono;
	}
	
	
	// Ritorna true se l'antifurto e' attivo
	public synchronized boolean antifurtoAttivo() {
		if(statoInterruttore.equals("on"))
			return true;
		return false;
	}
	
	// Ritorna true se l'antifurto sta suonando
	public synchronized boolean allarme() {
		if(statoSuono.equals("on"))
			return true;
		return false;
	}
	
	
	// con input la stringa "0" restituisce "off"
	// con input la stringa "1" restituisce "on"
	public String converter(int num) {
		if(num==0)
			return "off";
		return "on";
	}
}