/* ----------------------------------------
 * Origin  : GFI INFORMATIQUE 
 * Project : CDPP Propagation Tool 
 * ----------------------------------------
 * History 
 * Version : 25/08/2016 : SCA : V2.2.2
 * 	Creation
 * ----------------------------------------
 */
package fr.tlse.irap.pt.client.controller.tools.externalLinks;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import eu.omp.irap.vespa.epntapclient.granule.Granule;
import eu.schudt.javafx.controls.calendar.DatePicker;
import fr.tlse.irap.pt.client.component.DialogComponent;
import fr.tlse.irap.pt.client.component.IDialogComponent;
import fr.tlse.irap.pt.client.controller.common.FilterKeyEvent;
import fr.tlse.irap.pt.client.controller.common.Formatter;
import fr.tlse.irap.pt.client.controller.dialogbox.DialogBox;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.MenuButton;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
/**
 * 
 * @author frup03304
 * @version
 */
public class ApisComponent extends AnchorPane implements Initializable, IDialogComponent {

	public static DialogComponent dialog;

	@FXML protected GridPane endTimeGridPane;
	@FXML protected final DatePicker datePicker1 = new DatePicker("endTime");
    @FXML private ChoiceBox<String> targetCb;
    @FXML private TextField timeInterval;
    @FXML private ChoiceBox<String> unitTimeInt;
    @FXML private TextField timeInt;
    @FXML private MenuButton chooseMenuBtn;
    @FXML private ChoiceBox<String> processLevel;
    @FXML private Button okBtn;
    
    private List<Granule> granules = new ArrayList<Granule>();
    
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		// init date picker
		datePicker1.selectedDateProperty().set(new Date());
		addDatePicker();

		// init combo boxes
		initTargets();
		ExternalLinks.initUnitTime(unitTimeInt);

		timeInterval.addEventFilter(KeyEvent.ANY, new FilterKeyEvent(
				timeInterval, 10, 1, 9999, Formatter.getFormatter(), new SimpleBooleanProperty(), timeInterval.focusedProperty()));

		okBtn.setOnMouseClicked(new EventHandler<Event>() {
			@Override
			public void handle(Event event) {
				callApis();
			}
		});
	}

	public void initComponentWith(String target, Date date) {
		initComponent(target, date);
		dialog.show();
	}

	private void initComponent(String target, Date date) {
		this.targetCb.setValue(target);
		// set default values
		timeInterval.setText("10");
		unitTimeInt.setValue(unitTimeInt.getItems().get(3));
		processLevel.setValue(processLevel.getItems().get(0));
		// init end time
		datePicker1.selectedDateProperty().set(date);
		
	}

	public void setDialog(DialogComponent dlg) {
		dialog = dlg;
	}

	public DialogComponent getDialog() {
		return dialog;
	}

	protected void addDatePicker() {
		ExternalLinks.setStyleDate(datePicker1);
		endTimeGridPane.add(datePicker1, 0, 0);
	}

	/**
	 * call Apis interface with selected arguments
	 */
	private void callApis() {
		final Task<Object> callApisWorker = callApisWorker();

		callApisWorker.stateProperty().addListener(
				new ChangeListener<Worker.State>() {
					@Override
					public void changed(
							ObservableValue<? extends Worker.State> observableValue,
							Worker.State oldState, Worker.State newState) {

						if (newState == Worker.State.SUCCEEDED) {
							// thread is done with success
							endCursor();
					    	if (granules.size() > 0) {
								new ApisImagesDialogBox("Selected " + targetCb.getValue() + " " + processLevel.getValue() + " images").show(granules);
							}
							else {
								DialogBox.warn("No APIS images found", dialog);
							}
							
						} else if (newState == Worker.State.FAILED || newState == Worker.State.CANCELLED) {
							// thread is failed or cancelled
							endCursor();
							DialogBox.error(" Error while calling APIS interface.\n", dialog);
							if (callApisWorker.getException() != null) {
								//System.out.println(callApisWorker.getException().getMessage());
								System.out.println(callApisWorker.getException().getStackTrace());

							}
						}
					}

				});
		new Thread(callApisWorker).start();
		waitCursor();
	}

	private Task<Object> callApisWorker() {
		return new Task<Object>() {
			@Override
			protected Object call() throws Exception {
				granules = ExternalLinks.getApisGranules(targetCb.getValue(), datePicker1.selectedDateProperty().get(), getInterval(), getProcLevel());
				return true;
			}
		};
	}

	/**
	 * get interval in seconds
	 * @return
	 */
	private long getInterval() {
		long ti = Formatter.toDouble(timeInterval.getText()).longValue();
		return ExternalLinks.computeTimeInSeconds(ti, unitTimeInt.getValue());
	}
	
	/**
	 * get processus level
	 * @return
	 */
	private int getProcLevel() {
		if (processLevel.getValue().equals("raw")) {
			return 3;
		}
		else if (processLevel.getValue().equals("processed")) {
			return 4;
		}
		else if (processLevel.getValue().equals("projections")) {
			return 5;
		}
		else { // default value
			return 4;
		}
	}

	public void initTargets() {
		targetCb.getItems().clear();
		targetCb.getItems().add("JUPITER");
		targetCb.getItems().add("SATURN");
		targetCb.getItems().add("URANUS");
	}

	private void waitCursor() {
		this.setDisable(true);
		this.getScene().setCursor(Cursor.WAIT);
	}

	private void endCursor() {
		this.setDisable(false);
		this.getScene().setCursor(null);
	}
	
}

