/* ----------------------------------------
 * Origin  : Akkodis
 * Project : CDPP Propagation Tool 
 * ----------------------------------------
 * History 
 * Version : V2.12
 * DM-ID : Redmine#11103 : 25/03/2025 : LBE : Radio spectro interface added
 * ----------------------------------------
 */
package fr.tlse.irap.pt.client.controller.tools.radio;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.tlse.irap.pt.client.component.CustomComponent;
import fr.tlse.irap.pt.client.component.ICustomComponent;
import fr.tlse.irap.pt.client.controller.common.Formatter;
import fr.tlse.irap.fit.FitPoint;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;

/**
 * Graphic component for timetable of arrival times at spacecrafts and planets
 * (see IRAP specification : RadialTool_maquette.pdf on 29/10/2012)
 */
public class RadioFitParameterComponent extends VBox implements ICustomComponent {

    private static final Logger log = LoggerFactory.getLogger(RadioFitParameterComponent.class);

    @FXML
    private LineChart<Number, Number> radiusFitChart;
    private Series<Number, Number> fitPointsSeries = new Series<Number, Number>();
    private Series<Number, Number> clickPointsSeries = new Series<Number, Number>();

    @FXML
    private Label fitChartLabel;
    @FXML
    private Label resultFitTxtLabel;
    @FXML
    private Label resultFitValLabel;

    private List<FitPoint> fitPoints;
    private List<FitPoint> clickPoints;

    private Date startTime;
    private String observer;

    private static int TICK_RATIO = 4;

    public RadioFitParameterComponent() {
        super();
        CustomComponent.initCustomComponent(this);

        // Formatage des labels des abscisses
        NumberAxis.DefaultFormatter xAxisFormatter = new NumberAxis.DefaultFormatter((NumberAxis) radiusFitChart.getXAxis()) {
            @Override
            public String toString(Number object) {
                return Formatter.getTdf().format(object);
            }
        };

        // lineChartBestFit[0]: fit points
        // lineChartBestFit[1]: click points
        
        radiusFitChart.getData().add(fitPointsSeries);
        radiusFitChart.getData().add(clickPointsSeries);

        // some customization
        ((NumberAxis) radiusFitChart.getXAxis()).setTickLabelFormatter(xAxisFormatter);

    }

    public void setRadioRadialComponent(RadioRadialComponent pComponent) {
        // Subscription on clicked points changes (fitError)
        pComponent.setFitParameterComponent(this);

    }

    public Node getView() {
        return this;
    }

    public void setFitParam(String pObs, String pFitType, Date pStartTime, List<FitPoint> fitPoints, List<FitPoint> clickPoints,
            double pVel, double pStdErrVel, double[] pCIVel) {

        clearFitParam();

        this.observer = pObs;
        this.startTime = pStartTime;

        // FitPoints
        this.fitPoints = fitPoints;
        this.clickPoints = clickPoints;

        // update view fields 
        
        fitChartLabel.setText("Result of fitting with "+pFitType);
        String lStrTxtLabel = "Start time :\n";
        lStrTxtLabel += "Velocity :\n";
        lStrTxtLabel += "Standard Error of velocity :\n";
        lStrTxtLabel += "95% CI for velocity :";
        resultFitTxtLabel.setText(lStrTxtLabel);
        String lStrValLabel = Formatter.getSdf().format(startTime) + "\n";
        lStrValLabel += String.format("%.2f km/s%n", pVel);
        lStrValLabel += String.format("%.4f km/s%n", pStdErrVel);
        lStrValLabel += String.format("[%.4f, %.4f] km/s", pCIVel[0], pCIVel[1]);
        resultFitValLabel.setText(lStrValLabel);

        // draw
        drawBestFitGraph();

        radiusFitChart.setVisible(true);
    }

    public void reset() {
        clearFitParam();

        // reset view fields 
        // Set default 
        radiusFitChart.setVisible(true);
    }

    private void drawBestFitGraph() {
        for (int i = 0; i < fitPoints.size(); i++) {
            fitPointsSeries.getData().add(new Data<Number, Number>(fitPoints.get(i).getTime(), fitPoints.get(i).getElongation()));
        }
//        long lTimeGap = 1000;
//        FitPoint lP1 = fitPoints.get(0);
//        FitPoint lP2 = fitPoints.get(fitPoints.size() - 1);
//        System.out.println("*** draw fit line t1 t2: "+lP1.getTime()/1000+"-"+lP2.getTime()/1000);
//        ((NumberAxis) radiusFitChart.getXAxis()).setLowerBound(lP1.getTime() - lTimeGap);
//        ((NumberAxis) radiusFitChart.getXAxis()).setUpperBound(lP2.getTime() + lTimeGap);
//        ((NumberAxis) radiusFitChart.getXAxis()).setTickUnit((lP2.getTime() - lP1.getTime()) / TICK_RATIO);
        

        for (int i = 0; i < clickPoints.size(); i++) {
            System.out.println("Adding clickpoint time "+clickPoints.get(i).getTime()/1000);
            clickPointsSeries.getData().add(new Data<Number, Number>(clickPoints.get(i).getTime(), clickPoints.get(i).getElongation()));
        }

    }

    /**
     * Clear charts and data
     */
    public void clearFitParam() {

        // reset all previous values
        if (radiusFitChart != null) {
            fitPointsSeries.getData().clear();
            clickPointsSeries.getData().clear();
        }

        // FitPoints
        this.fitPoints = null;
        this.clickPoints = null;

    }
}
