package com.elphel.imagej.ims;

public abstract class Did_ins <T extends Did_ins <T>>{
	final static int WEEK_SECONDS = 7 * 24 * 3600;
	/** GPS number of weeks since January 6th, 1980 */
	public int				week;      // uint32_t
	/** GPS time of week (since Sunday morning) in seconds */
	public double			timeOfWeek;
	/** INS status flags (eInsStatusFlags). Copy of DID_SYS_PARAMS.insStatus */
	public int				insStatus; // uint32_t
	/** Hardware status flags (eHdwStatusFlags). Copy of DID_SYS_PARAMS.hdwStatus */
	public int				hdwStatus; // uint32_t
	/** WGS84 latitude, longitude, height above ellipsoid (degrees,degrees,meters) */
	public double []		lla =   new double [3];
	
	static int interpolateInt(double frac, int v_this, int v_next) {
		return (int) Math.round(frac * v_this + (1.0 - frac) * v_next);
	}
	static float interpolateFloat(double frac, float v_this, float v_next) {
		return (float) (frac * v_this + (1.0 - frac) * v_next);
	}

	static double interpolateDouble(double frac, double v_this, double v_next) {
		return frac * v_this + (1.0 - frac) * v_next;
	}
	
//https://www.swtestacademy.com/return-subclass-instance-java-generics/	
	public void interpolateBase(double frac, T next_did, T new_did) {
		new_did.week =     this.week;
    	double tow_next =  next_did.timeOfWeek;
    	if (next_did.week > this.week) {
    		tow_next +=  (next_did.week - this.week) *7 * 24 * 3600; // week in seconds
    	}
    	new_did.timeOfWeek = interpolateDouble ( frac, this.timeOfWeek, tow_next);
    	while (new_did.timeOfWeek >= WEEK_SECONDS) {
    		new_did.timeOfWeek -= WEEK_SECONDS;
    		new_did.week ++;
    	}
    	new_did.insStatus =     this.insStatus;
    	new_did.hdwStatus =     this.hdwStatus;
    	for (int i = 0; i < lla.length; i++) {
    		new_did.lla[i] =   interpolateDouble(frac, lla[i], next_did.lla[i]) ;
    	}
	}
}