package gps;

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

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

@BA.ShortName("GpsGPRMC")
public class GpsGPRMC {
	public String invalidmsg = "";
	public byte UTC_Hour = -1;
	public byte UTC_Minute = -1;
	public byte UTC_Second = -1;
	public byte UTC_Day = -1;
	public byte UTC_Month = -1;
	public int UTC_Year = -1;
	public boolean PositionFix = false;
	public double Latitude = 0;
	public double Longitude = 0;
	
	/**
	 * In Knot
	 */
	public double Ground_Speed = 0;
	
	/**
	 * In Degree
	 */
	public double Ground_Course = 0;
	
	/**
	 * In Degree
	 */
	public double Magnetic_Variation = 0;
	
	
	public GpsGPRMC(String msg) {
		
		String[] partB = msg.split(",");
		
		if (partB.length<12) {
			invalidmsg = "GPRMC Split less than 12";
			return;
		}
		
		List<String> err = new ArrayList<String>();
		
		byte[] utctime = new byte[] {0,0,0};
		if (mycodes.Gps_UTCTime(partB[1], utctime)) {
			UTC_Hour = utctime[0];
			UTC_Minute = utctime[1];
			UTC_Second = utctime[2];
		} else {			
			err.add("GPRMC dont have Time") ;
		}
		
		switch(mycodes.Gps_Char(partB[2])) {
			case 'A' :
				PositionFix = true;
				break;
			case 'V' :
				PositionFix = false;
				break;
			default :
				err.add("GPRMC Invalid Position Fix : "+partB[2]);
				break;
		}
				
		double[] result;
		result = new double[] {0};
		if (mycodes.Gps_Latitude_formatchange(partB[3], result)) {
			Latitude = result[0];
		} else {
			err.add("GPRMC Invalid Latitude : "+partB[3]);
		}
		
		switch(mycodes.Gps_Char(partB[4])) {
		case 'N' :
			Latitude = mycodes.SetPositive(Latitude);		//hasil harus positif
			break;
		case 'S' :
			Latitude = mycodes.SetNegative(Latitude);		// hasil harus negatif;
			break;
		default :
			Latitude = 0;
			err.add("GPRMC Invalid Latitude Polarity : "+partB[4]);
			break;
		}
		
		result = new double[] {0};
		if (mycodes.Gps_Longitude_formatchange(partB[5], result)) {
			Longitude = result[0];
		} else {
			err.add("GPRMC Invalid Longitude : "+partB[5]);
		}
		
		switch(mycodes.Gps_Char(partB[6])) {
		case 'W' :
			Longitude = mycodes.SetNegative(Longitude);		// hasil harus negative
			break;
		case 'E' :
			Longitude = mycodes.SetPositive(Longitude);		// hasil positive
			break;
		default : 
			err.add("GPRMC Invalid Longitude Polarity : "+partB[6]);
			break;
		}
		
		try {
			double knot = Double.parseDouble(partB[7]);
			Ground_Speed = knot;
		} catch( NumberFormatException e) {
			err.add("GPRMC invalid Ground Speed "+partB[7]);
			Ground_Speed = -1;
		}
		
		try {
			double course = Double.parseDouble(partB[8]);
			Ground_Course = course;
		} catch( NumberFormatException e) {
			err.add("GPRMC invalid Ground Course "+partB[8]);
			Ground_Course =-1;
		}
		
		byte[] utcdate = new byte[] {0,0,0};
		if (mycodes.Gps_UTCDate(partB[9], utcdate)) {
			UTC_Day = utcdate[0];
			UTC_Month = utcdate[1];
			UTC_Year = 2000 + utcdate[2];
		} else {
			err.add("GPRMC dont have Date");
		}
		
		try {
			double mag = Double.parseDouble(partB[10]);
			Magnetic_Variation = mag;
		}catch( NumberFormatException e) {
			err.add("GPRMC invalid Magnetic Variation "+partB[10]);
		}
		
		switch(mycodes.Gps_Char(partB[11])) {
		case 'E' :
			Magnetic_Variation = mycodes.SetPositive(Magnetic_Variation);
			break;
		case 'W' :
			Magnetic_Variation = mycodes.SetNegative(Magnetic_Variation);
			break;
		default :
			err.add("GPRMC invalid Magnetic Polarity : "+partB[11]);
			break;
		}
		
		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 (PositionFix) {
			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 "";
	}
	
	/**
	 * Get UTC Date String in format dd-MM-yyyy
	 * @return UTC Time String in format dd-MM-yyyy , or empty string if invalid data
	 */
	public String UTC_Date_ddMMyyyy() {
		if (PositionFix) {
			StringBuilder str = new StringBuilder();
			str.append(Common.NumberFormat(UTC_Day, 2, 0));
			str.append("-");
			str.append(Common.NumberFormat(UTC_Month, 2, 0));
			str.append("-");
			str.append(UTC_Year);
			return str.toString();
		} else return "";
	}
	
}
