/* ----------------------------------------
 * Origin  : GFI INFORMATIQUE 
 * Project : CDPP Propagation Tool 
 * ----------------------------------------
 * History 
 * Version : 01/05/2015 : SCA : V2.1
 * Version : 24/03/2016 : SCA : V2.2 (PSWS-H2020)
 *  Add configuration of Space Elements
 * Version : 17/10/2018 : SCA : V2.2.5 (PSP)
 * Version : 12/09/2023 : LBE : V2.8
 * DM-ID : Redmine#10500 : 12/09/2023 : new END points
 * VERSION : V2.12
 * DM-ID : redmine#11920: 13/03/2025 : KHK : Add Europa Clipper
 * ----------------------------------------
 */
package fr.tlse.irap.server.serviceDAO.utils;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.zip.GZIPInputStream;

import javax.vecmath.Matrix3d;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import cdpp3dview.types.Tuple3D;
import fr.tlse.irap.spaceElement.Comet;
import fr.tlse.irap.spaceElement.Planet;
import fr.tlse.irap.spaceElement.Probe;
import fr.tlse.irap.spaceElement.SpaceElementWrapper;
import fr.tlse.irap.spaceElement.Sun;

public class SpiceHelper {

    /**
     * Parse an url string
     * @param url
     * @throws Exception
     */
    public static List<Tuple3D> parse(String url) throws Exception {
		TimeSerieSaxHandler lSaxHandler = new TimeSerieSaxHandler(Arrays.asList("x", "y", "z"));
		SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
		URL lUrl = new URL(url);
		try {
			saxParser.parse(new GZIPInputStream(lUrl.openStream()), lSaxHandler);
		}
		catch (Exception e) {
			saxParser.parse(lUrl.openStream(), lSaxHandler);
		}

    	List<Tuple3D> data = new ArrayList<Tuple3D>();
    	for (double[] value:lSaxHandler.getValues()) {
    		data.add(new Tuple3D(
    				value[0], value[1], value[2])
    		);
    	}

		return data;
    }

    /**
     * Parse an url string
     * @param url
     * @throws Exception
     */
    public static List<Matrix3d> urlToM3d(String url) throws Exception {
		TimeSerieSaxHandler lSaxHandler = new TimeSerieSaxHandler(Arrays.asList("xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz"));
		SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
		URL lUrl = new URL(url);
		saxParser.parse(new GZIPInputStream(lUrl.openStream()), lSaxHandler);

    	List<Matrix3d> data = new ArrayList<Matrix3d>();
    	for (double[] val:lSaxHandler.getValues()) {
    		data.add(new Matrix3d(
    				val[0], val[1], val[2], 
    				val[3], val[4], val[5], 
    				val[6], val[7], val[8])
    		);
    	}

		return data;
    }

    /**
     * get Naif ID from the orbit file name
     * @param file name
     * @return 0 if not found
     */
    public static int extractNaifId(String file) {
    	// extract NAIF id from filename as "/pub/orb-248_7012694850428315869.vot.gz"
    	String[] splitFile = file.split("_");
    	if (splitFile.length > 0) {
   			String result = splitFile[0].substring(8, splitFile[0].length());
   			return Integer.parseInt(result);
		}
    	return 0;
    }

    /**
     * Converts an XMLGregorianCalendar to java.util.Date
     * @param xGc Calendar to convert.
     * @return null if an error occurs
     */
    public static Date xGc2Date(XMLGregorianCalendar xGc) {
        if (xGc == null) {
            return null;
        } else {
            return xGc.toGregorianCalendar().getTime();
        }
    }
    
    /**
     * Converts java.util.Date to XMLGregorianCalendar Format
     * @param date Date to convert.
     * @return null if an error occurs
     */
    public static XMLGregorianCalendar date2Xgc(Date date) {
    	if (date == null) {
            return null;
        } else {
        	GregorianCalendar calendar = new GregorianCalendar();  
            calendar.setTimeInMillis(date.getTime());
            try {
                return DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar);
            } catch (DatatypeConfigurationException ex) {
                return null;
            }
        }
    }

    /**
     * Build space elements 
     * @return
     */
    public static SpaceElementWrapper buildSpaceElements () {
    	SpaceElementWrapper spaceElements = new SpaceElementWrapper();

    	//spaceElements.setSun(new Sun("SUN", 10, 9, "#FFFD55", 259200, 10));
    	spaceElements.setSun(new Sun("SUN", 10, 3, "#FFFD55", 259200, 10));
    	// add planets
    	spaceElements.getPlanets().add(new Planet("MERCURY", 199, 6, "#737373", 118746, 64));
    	spaceElements.getPlanets().add(new Planet("VENUS", 299, 10, "#FF8D00", 151659, 128));
    	spaceElements.getPlanets().add(new Planet("EARTH", 399, 11, "#425BE9", 164367, 192));
    	spaceElements.getPlanets().add(new Planet("MARS", 499, 7, "#F15B44", 206094, 288));
    	spaceElements.getPlanets().add(new Planet("JUPITER", 5, 20, "#FF0000", 1701575, 220));
    	spaceElements.getPlanets().add(new Planet("SATURN", 6, 16, "#58D3F7", 2323965, 400));
    	spaceElements.getPlanets().add(new Planet("URANUS", 7, 12, "#00FF11", 5304000, 500));
    	spaceElements.getPlanets().add(new Planet("NEPTUNE", 8, 12, "#0404B4", 6501260, 800));
    	spaceElements.getPlanets().add(new Planet("PLUTO", 9, 6, "#425BE9", 9308500, 840));
        // add comets
        spaceElements.getComets().add(new Comet("CHURYUMOV-GERASIMENKO", 1000012, 6, "#002211", 9308500, 840));
    	// add spacecrafts       
    	spaceElements.getProbes().add(new Probe("MESSENGER", -236, 4, "#00FF11", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("MMO",-68, 4, "#58D3F7", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("MPO",-121, 4, "#00FF11", 259200, 10, false));   	
        spaceElements.getProbes().add(new Probe("BEPI", "BepiColombo",-652, 4, "#00FF11", 259200, 10, false)); 	
        spaceElements.getProbes().add(new Probe("VEX", -248, 4, "#F15B44", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("STEREO-A", -234, 4, "#FF0004", 259200, 10, true));
    	spaceElements.getProbes().add(new Probe("WIND", -8, 4, "#FAAC58", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("ACE", -92, 4, "#58D3F7", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("STEREO-B", -235, 4, "#4978FF", 259200, 10, true));
    	spaceElements.getProbes().add(new Probe("SOLO", "Solar Orbiter", -144,  4, "#673300", 259200, 10, true, "2020-02-04T00:00:00"));
    	spaceElements.getProbes().add(new Probe("PSP", "Parker Solar Probe", -96,  4, "#F5EC42", 259200, 10, true));
    	spaceElements.getProbes().add(new Probe("SOHO", -21, 4, "#8181F7", 259200, 10, true));
    	spaceElements.getProbes().add(new Probe("SDO", -136395, 4, "#673300", 259200, 10, true));
    	spaceElements.getProbes().add(new Probe("DSCOVR", -78, 4, "#00FF11", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("MEX", -41, 4, "#CC99FF", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("MAVEN", -202, 3, "#BDBDBD", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("JUNO",-61, 4, "#9AFE2E", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("CASSINI", -82,  4, "#737373", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("ROSETTA", -226, 3, "#21610B", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("NH","New Horizons", -98, 4, "#CCCCCC", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("VGR-1","Voyager 1", -31, 4, "#888888", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("VGR-2","Voyager 2", -32, 4, "#888888", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("PIONEER-10","Pioneer 10", -23, 4, "#21618B", 259200, 10, false));
    	spaceElements.getProbes().add(new Probe("PIONEER-11","Pioneer 11", -24, 4, "#21618B", 259200, 10, false));
        //11920 add Europa Clipper
        // moving down the juice sc due to a loading problem
        spaceElements.getProbes().add(new Probe("JUICE", -28, 4, "#FAAC58", 259200, 10, false));
        spaceElements.getProbes().add(new Probe("EUROPA", "EuropaClipper", -159, 4, "#2DA529", 259200, 10, false));

//1500: ajouter New horizon(-98), VG1(-31) et VG2(-32), pioneer 10(-23) et 11(-24), HALLEY(1000036), 67P CHURYUMOV-GERASIMENKO (1000012), 26P GRIGG-SKJELLERUP (1000034)?
        
        
    	return spaceElements;
    }


}
