package gps;

import java.util.ArrayList;
import java.util.List;

import anywheresoftware.b4a.BA;
import jGPIO.mycodes;
import anywheresoftware.b4a.keywords.Common;

@BA.ShortName("GpsGPGGA")
public class GpsGPGGA {
	
	public String invalidmsg = "";
	public byte UTC_Hour = -1;
	public byte UTC_Minute = -1;
	public byte UTC_Second = -1;
	public double Latitude = 0;
	public double Longitude = 0;
	public double HDOP = -1;
	public boolean PositionFixed = false;
	public int Satellites = -1;
	public double Altitude = -1;
	public double GeoID_Height = -1;
	
	public GpsGPGGA(String msg) {
		String[] partB = msg.split(",");		// pisahkan konten berdasar koma
		if (partB.length<13) {
			invalidmsg = "GPGGA Split is less than 13";
			return;
		}
		
		List<String> err = new ArrayList<String>();
		
		// waktu hhmmss.sss
		byte[] utc = new byte[] {0,0,0};
		if (mycodes.Gps_UTCTime(partB[1],utc)) {
			UTC_Hour = utc[0];
			UTC_Minute = utc[1];
			UTC_Second = utc[2];
		} else {
			err.add("GPGGA dont have Time");
		}
		
		// Latitude
		double[] result;
		result = new double[] {0};
		if (mycodes.Gps_Latitude_formatchange(partB[2], result)) {
			Latitude = result[0];	
		} else {
			err.add("GPGGA Invalid Latitude : "+partB[2]);
		}

		// Latitude polarity, N or S
		switch(mycodes.Gps_Char(partB[3])) {
		case 'N' :
			Latitude = mycodes.SetPositive(Latitude);	// hasil harus positif
			break;
		case 'S' :
			Latitude = mycodes.SetNegative(Latitude);	// hasil harus negatif
			break;
		default :
			Latitude = 0;			// tidak jelas
			err.add("GPGGA Invalid Latitude Polarity : "+partB[3]);
			break;
		}
		
		// Longitude
		result = new double[] {0};
		if (mycodes.Gps_Longitude_formatchange(partB[4], result)) {
			Longitude = result[0];
		} else {
			err.add("GPGGA Invalid Longitude : "+partB[4]);
		}
		
		// Longitude polarity, W or S
		
		switch(mycodes.Gps_Char(partB[5])) {
		case 'W' :
			Longitude = mycodes.SetNegative(Longitude);		// hasil harus negatif
			break;
		case 'E' :
			Longitude = mycodes.SetPositive(Longitude);		// hasil harus positif
			break;
		default : 
			Longitude = 0;					// tidak jelas
			err.add("GPGGA Invalid Longitude Polarity : "+partB[5]);
			break;
		}
		
		// Position Fix, 0 / 1 / 2
		try {
			int posfix = Integer.parseInt(partB[6]);
			if (posfix<1) PositionFixed = false; else PositionFixed = true;	
		} catch(NumberFormatException e) {
			err.add("GPGGA Invalid PositionFix : "+partB[6]);
		}

		// Number of satelites
		try {
			int satfix = Integer.parseInt(partB[7]);
			Satellites = satfix;
		} catch(NumberFormatException e) {
			err.add("GPGGA Invalid Satelite : "+partB[7]);
			
		}

		// HDOP di index 8
		try {
			double hd = Double.parseDouble(partB[8]);
			HDOP = hd;
		}catch(NumberFormatException e) {
			err.add("GPGGA Invalid HDOP : "+partB[8]);
		}
		
		// Altitude , nilai di 9, M di 10
		try {
			double alt = Double.parseDouble(partB[9]);
			Altitude = alt;
		} catch(NumberFormatException e) {
			err.add("GPGGA Invalid Altitude : "+partB[9]);
		}
		
		if (mycodes.Gps_Char(partB[10])!='M') {
			err.add("GPGGA Altitude M not found");
		}

		// GeoID_height, nilai di 11, M di 12
		try {
			double geoid = Double.parseDouble(partB[11]);
			GeoID_Height = geoid;
		} catch(NumberFormatException e) {
			err.add("GPGGA Invalid Altitude : "+partB[11]);
		}
		
		if (mycodes.Gps_Char(partB[12])!='M') {
			err.add("GPGGA GeoID M is not found");
		}
		
		invalidmsg = mycodes.Gps_ErrList_to_String(err);
	}
	
	public boolean isValid() {
		if (invalidmsg=="") return true; else return false;
	}
	
	/**
	 * Get UTC Time String in format hh:mm:ss
	 * @return UTC Time String in format hh:mm:ss, or empty string if invalid data
	 */
	public String UTC_Time_hhmmss() {
		if (isValid()) {
			StringBuilder str = new StringBuilder();
			str.append(Common.NumberFormat(UTC_Hour, 2, 0));
			str.append(":");
			str.append(Common.NumberFormat(UTC_Minute, 2, 0));
			str.append(":");
			str.append(Common.NumberFormat(UTC_Second,2,0));
			return str.toString();
		} else return "";
	}
	
	
}
