package devices.FA.Simplex4100;

import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.keywords.Bit;
import anywheresoftware.b4a.keywords.DateTime;
import anywheresoftware.b4a.keywords.Regex;

import java.text.ParseException;


@BA.ShortName("Simplex4100Data")
public class Simplex4100Data {

	private boolean valid_data = false;
	private String datastring;
	private String exceptionmsg;
	private long datetimetick = 0;
	private String _detectorlocation="";
	private String _detectorstatus="";
	
	public Simplex4100Data() {
		datastring = "";
		exceptionmsg = "";
	}
	public Simplex4100Data(String msg) {
		this();
		Analyze(msg);
	}
	
	/**
	 * Try to analyze a string
	 * @param msg : Simplex String
	 * @return true if valid
	 */
	public boolean Analyze(String msg) {
		valid_data = false;
		
		if (msg!=null) {
			if (msg.length()>0) {
				datastring = msg.trim();
				Check_Validity();
			} else datastring = "";
		} else datastring = "";	
		
		return valid_data;
	}
	
    /**
     * Check if Data is valid
     * @return true if valid
     */
	public boolean getIsValid() {
		return valid_data;
	}
	
	
	// Contoh : 
	// -134424-6250108 @2-2-0 T1* --> trouble
	// -134319-6250108 @2-2-0 T1- --> trouble acknowledged
	// -134335-6250108 @2-2-0 T0- --> trouble selesai
	// -134424-6250108 @2-2-0 F1* --> ada fire
	// -134430-6250108 @2-2-0 F1- --> fire acknowledged
	// -134515-6250108 @2-2-0 F0- --> fire sudah normal
	
	private void Check_Validity() {
		valid_data = false;
		if (datastring == null) {
			exceptionmsg = "Data is null";
		} else if (datastring.isEmpty()) {
			exceptionmsg = "Data is empty";
		} else {
			String[] cmds = Regex.Split(" ", datastring);
			if (cmds.length>=3) {
				if (cmds[0].startsWith("-")) {
					if (cmds[1].startsWith("@")) {
						if (cmds[2].length()>=3) {
							
							// Date and Time part
							boolean valid_date = false;
							this.datetimetick = 0;
							
							try {
								String timereceived = cmds[0].substring(1, 7);		// skip '-' awal, sampai sebelum '-' di tengah
								String datereceived = cmds[0].substring(9);		// skip '-6'
								
								String old_dateformat = DateTime.getDateFormat();
								String old_timeformat = DateTime.getTimeFormat();
								
								DateTime.setDateFormat("ddMMyy");
								DateTime.setTimeFormat("HHmmss");
								
								datetimetick = DateTime.DateTimeParse(datereceived, timereceived);
								
								// sampe sini sudah berhasil parse
								// balikin ke format awal
								DateTime.setDateFormat(old_dateformat);
								DateTime.setTimeFormat(old_timeformat);
								
								valid_date = true;
								
							} catch(IndexOutOfBoundsException e) {
								exceptionmsg = "Invalid Date Time String";
								return;
							} catch (ParseException e) {
								exceptionmsg = "Failed parsing Date Time";
								return;
							}
							
							if (!valid_date) return;
							
							// Detector Address Part
							this._detectorlocation = cmds[1].substring(1).trim();
							if (this._detectorlocation.isEmpty()) {
								exceptionmsg = "Empty Detector Location";
								return;
							}
							
							// Detector Status Part
							_detectorstatus = cmds[2].trim();
							if (this._detectorstatus.isEmpty()) {
								exceptionmsg = "Empty Detector Status";
								return;
							}
							
							valid_data = true;
							
						} else exceptionmsg = "Invalid Detector Status Part";						
					} else exceptionmsg = "Invalid Detector Address Part";
				} else exceptionmsg = "Invalid Date Time Part";
			} else exceptionmsg = "Regex is not 3";
		}
		
	}
	
	/**
	 * Print original protocol string to byte string for ASCII examination
	 * @param mode : 0 = desimal, 1 = hexadesimal
	 * @return "null" if data is null, "0" if data length 0, or data bytes separated with space(32)
	 */
	public String GetByteString(int mode) {
		if (datastring==null) {
			return "null";
		} else if (datastring.isEmpty()) {
			return "0";
		} else {
			byte[] datanya = datastring.getBytes();
			StringBuilder str = new StringBuilder();
			for(byte xx : datanya) {
				if (str.length()>0) str.append(" ");
				if (mode>0)
					str.append(Bit.ToHexString(Bit.And(xx, 0xFF)));
				else
					str.append(Bit.And(xx, 0xFF));
			}
			return str.toString();
		}
	}
	
	/**
	 * Get Original Protocol String
	 * @return protocol string
	 */
	public String GetOriginalProtocolString() {
		return datastring;
	}
	
	/**
	 * if IsValid() return false, check Exception message here
	 * @return exception message if available, or null if not available
	 */
	public String getExceptionMessage() {
		return exceptionmsg;
	}
	
	/**
	 * Get Date Received
	 * @return if not valid, return empty string
	 */
	public String getDateReceived() {
		if (datetimetick>0) return DateTime.Date(datetimetick); else return "";
	}
	
	/**
	 * Get Time Received
	 * @return if not valid, return empty string
	 */
	public String getTimeReceived() {
		if (datetimetick>0) return DateTime.Time(datetimetick); else return "";
	}
	
	/**
	 * Get Detector Location
	 * Detector Location is device(FA sensor) identification
	 * @return if not valid, return empty string
	 */
	public String getDetectorLocation() {
		return _detectorlocation;
	}
	
	/**
	 * Get Detector Status
	 * status = 
	 * 		T1*  --> Detector have trouble
	 * 		T1-  --> Trouble have been acknowledged
	 *		T0-  --> Trouble have been solved
	 *		F1*  --> Fire detected
	 *		F1-  --> Fire have been acknowledged
	 *		F0-  --> Fire have been solved 
	 * @return if not valid, return empty string
	 */
	public String getDetectorStatus() {
		return _detectorstatus;
	}
}
