package de.edelweissschuetzen.meytonanalysis.view;

import de.edelweissschuetzen.meytonanalysis.Main;
import de.edelweissschuetzen.meytonanalysis.api.datastore.DatastoreReadonly;
import de.edelweissschuetzen.meytonanalysis.api.logic.Logic;
import de.edelweissschuetzen.meytonanalysis.api.resource.ResourceStatus;
import de.edelweissschuetzen.meytonanalysis.api.resource.ResourceType;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;

import java.util.ArrayList;
import java.util.Observable;
import java.util.logging.Logger;

/**
 * @author Hageneder
 * @version 2016-08-05
 */
public class RanklistController implements ChildViewController {
	@FXML
	private Label labelVersion;
	@FXML
	private Label labelRuntime;
	@FXML
	private Label labelLoglines;
	@FXML
	private ArrayList<Label> logStatusList;
	@FXML
	private Label statusShooterDB;
	@FXML
	private Label statusDatesDB;
	@FXML
	private Label statusResultsRemoveDB;
	@FXML
	private Label statusResultsAddDB;
	@FXML
	private Label moduleTitle;
	@FXML
	private TextArea logArea;
	@FXML
	private ProgressBar progressbar;
	
	private DatastoreReadonly datastore;
	private Logic logic;
	private Logger logger;


  /*
   * #########################################################################
   * StartUp
   */
	
	@Override
	public void init(Main main, Logic logic, ViewController parent) {
		// References
		this.logic = logic;
		this.datastore = logic.getDatastore();
		
		datastore.addObserver(this);
		logger = Logger.getLogger(getClass().getName());
		
		// GUI
		labelVersion.setText(datastore.getProperty("VERSION", "unknown"));
		
		logger.info("Ranklist Viewcontroller initialized");
	}
	
	@Override
	public void stop() {
		
	}
  
  /*
   * #########################################################################
   * Listener - Module
   */
	
	@FXML
	void startVMBest() {
		
	}
	
	@FXML
	void startVMDay() {
		
	}
	
	@FXML
	void startVMStat() {
		
	}
	
	@FXML
	void startLogsearch() {
		
	}
	
	@FXML
	void startEagle() {
		
	}
	
	@FXML
	void startEasterEgg() {
		
	}
	
	@FXML
	void startRWK() {
		
	}
	  
  /*
   * #######################################################################
   * External Resource Management
   */
	
	private void updateResoursceState(ResourceType res, ResourceStatus state, int index) {
		Platform.runLater(() -> {
			// get labels to change
			Label toChange;
			
			switch (res) {
				case LOG:
					toChange = logStatusList.get(index - 1);
					break;
				case SHOOTER_DB:
					toChange = statusShooterDB;
					break;
				case DATES_DB:
					toChange = statusDatesDB;
					break;
				case RESULTS_ADD_DB:
					toChange = statusResultsAddDB;
					break;
				case RESULTS_REMOVE_DB:
					toChange = statusResultsRemoveDB;
					break;
				default:
					return;
			}
			
			// apply changes
			
			toChange.getStyleClass().clear();
			
			if (state != null) { // clear Text if state == null
				switch (state) {
					case ERROR:
						toChange.setText("Fehler");
						toChange.getStyleClass().add("status_error");
						break;
					case BACKUP:
						toChange.setText("Backup");
						toChange.getStyleClass().add("status_backup");
						break;
					case LIVE:
						toChange.setText("Geladen");
						toChange.getStyleClass().add("status_live");
						break;
					case ISLOADING:
						toChange.setText("wird geladen...");
						toChange.getStyleClass().add("status_loading");
						break;
					default:
						toChange.setText(null);
				}
			} else {
				toChange.setText(null);
			}
		});
	}
	
	
	@Override
	public void update(Observable o, Object arg) {
		Platform.runLater(() -> {
			final long starttime = System.currentTimeMillis();
			synchronized (datastore) {
				for (int i = 1; i <= Integer.parseInt(datastore.getProperty("AMOUNT_OF_LOGS", "12")); i++)
					updateResoursceState(ResourceType.LOG, datastore.getResourceState(ResourceType.LOG, i), i);
				
				updateResoursceState(ResourceType.SHOOTER_DB, datastore.getResourceState(ResourceType.SHOOTER_DB, 0), 0);
				updateResoursceState(ResourceType.DATES_DB, datastore.getResourceState(ResourceType.DATES_DB, 0), 0);
				updateResoursceState(ResourceType.RESULTS_REMOVE_DB, datastore.getResourceState(ResourceType.RESULTS_REMOVE_DB, 0), 0);
				updateResoursceState(ResourceType.RESULTS_ADD_DB, datastore.getResourceState(ResourceType.RESULTS_ADD_DB, 0), 0);
				
				moduleTitle.setText(datastore.getModuleTitle());
				progressbar.setProgress(datastore.getModuleProgress());
				logArea.setText(datastore.getModuleLog());
				labelLoglines.setText(
						datastore.getModuleProcessedLogLines() < 0 ? null :
								Integer.toString(datastore.getModuleProcessedLogLines())
				);
				
				final long runtime = datastore.getModuleExecutionTime();
				if (runtime < 10000) {
					labelRuntime.setText(String.format("%d ms", runtime));
				} else {
					labelRuntime.setText(String.format("%.2f s", (float) runtime / 1000.0f));
				}
			}
			logger.config("Update ranklist screen took: ".concat((System.currentTimeMillis() - starttime) + " ms"));
		});
	}
}
