/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sajidsiraj.priest;

import com.sajidsiraj.priest.entities.*;
import com.sajidsiraj.priest.utils.*;
import com.sajidsiraj.priest.facades.*;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.canvas.*;
import javafx.scene.chart.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.util.Callback;

/**
 * FXML Controller class
 *
 * @author Sajid Siraj
 */
public class TemplateMainController implements Initializable {

    @FXML Label _lblTitle;
    @FXML Label _lblParticipant;
    @FXML Label _lblCriterion;
    
    @FXML ListView<Problem>  _listMyDecisionProblems;
    @FXML ListView<Problem>  _listMyParticipations;
    
    @FXML TextField  _textProblemTitle;
    @FXML DatePicker  _dateProblemDeadline;
    @FXML DatePicker  _dateProblemStart;
    @FXML ChoiceBox  _choiceProblemAccess;
    @FXML ListView<Criterion>  _listProblemCriteria;
    @FXML ListView<Participant>  _listProblemParticipants;
    @FXML ListView<Option>  _listProblemOptions;	
    
    @FXML ListView<Criterion>  _listAssessCriteria; 
    @FXML ListView<Participant>  _listAssessParticipants; 
    @FXML Canvas  _canvasGraph;
    @FXML BarChart  _chartThermometer;
    @FXML ListView  _listPairwiseSliders;
    @FXML TableView  _tablePCMatrix; 

    @FXML Button  _btnCalculate; 
    @FXML ListView<Criterion>  _listResultsCriteria;
    @FXML ListView<Participant>  _listResultsParticipants; 
    @FXML Canvas  _canvasSMAA; 
    @FXML Canvas  _canvasPCA;
    
    @FXML TextField  _textUsername; 
    @FXML PasswordField  _passPassword; 
    @FXML Button  _btnSynchronize; 
    
    @FXML ListView<Method>  _listElicitationMethods; 
    @FXML ListView<Method>  _listAggregationMethods; 
    @FXML ListView<Method>  _listNegotiationMethods; 
    
    ObservableList _dataUsers = FXCollections.observableArrayList();
    ObservableList _dataProblems = FXCollections.observableArrayList();

    ObservableList _dataParticipants = FXCollections.observableArrayList();
    ObservableList _dataCriteria = FXCollections.observableArrayList();
    ObservableList _dataOptions = FXCollections.observableArrayList();

    ObservableList _dataJudgments = FXCollections.observableArrayList();
    ObservableList _dataScores = FXCollections.observableArrayList();

    private final UserService    _svcUsers;
    private final ProblemService _svcProblems;
    private final CriterionService _svcCriteria;
    private final OptionService _svcOptions;
    private final ParticipantService _svcParticipants;
    
    protected User _curUser;
    protected Problem _curProblem;
    protected Participant _curParticipant;
    protected Criterion _curCriterion;
    protected Option _curOption;
    protected Judgment _curJudgment;
    protected Score _curScore;
    protected Method _curMethod;

    public TemplateMainController() throws IOException {
        PersistenceUtilities.getInstance().getEntityManagerFactory(PersistenceUtilities._PU, null);
        this._svcUsers = new UserService(PersistenceUtilities._PU);
        this._svcProblems = new ProblemService(PersistenceUtilities._PU);
        this._svcCriteria = new CriterionService(PersistenceUtilities._PU);
        this._svcOptions = new OptionService(PersistenceUtilities._PU);
        this._svcParticipants = new ParticipantService(PersistenceUtilities._PU);
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
        _dataUsers.setAll(_svcUsers.findAll());
        
        _dataProblems.setAll(_svcProblems.findAll());
        _listMyDecisionProblems.setItems(_dataProblems);
        
        _dataParticipants.setAll(_svcParticipants.findAll());
        _listProblemParticipants.setItems(_dataParticipants);
        _listAssessParticipants.setItems(_dataParticipants);        
        _listResultsParticipants.setItems(_dataParticipants);
        
        
        _dataCriteria.setAll(_svcCriteria.findAll());
        _listProblemCriteria.setItems(_dataCriteria);
        _listAssessCriteria.setItems(_dataCriteria);        
        _listResultsCriteria.setItems(_dataCriteria);
        
        _dataOptions.setAll(_svcOptions.findAll());
        _listProblemOptions.setItems(_dataOptions);
        
        connectSignalsAndSlots();
    }    
    
    protected void connectSignalsAndSlots(){
        MultipleSelectionModel model;
        model = _listMyDecisionProblems.getSelectionModel();
        model.setSelectionMode(SelectionMode.SINGLE);
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectProblem((Problem)newVal);                    
        });
        _listMyDecisionProblems.setEditable(true);
        _listMyDecisionProblems.setCellFactory(new Callback<ListView<Problem>, ListCell<Problem>>() {
            @Override
            public ListCell<Problem> call(ListView<Problem> param) {
                TextFieldListCell<Problem> textCell = new TextFieldListCell<Problem>() {
                    @Override
                    public void updateItem(Problem item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null) {
                            setText(item.toString());
                        } else {
                            setText("");
                        }
                    }
                };
                return textCell;
            }
        });
        model = _listProblemParticipants.getSelectionModel();
        model.setSelectionMode(SelectionMode.SINGLE);
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectParticipant((Participant)newVal);
        });
        model = _listAssessParticipants.getSelectionModel();
        model.setSelectionMode(SelectionMode.SINGLE);
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectParticipant((Participant)newVal);
        });
        model = _listResultsParticipants.getSelectionModel();
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectParticipant((Participant)newVal);
        });
        
        model = _listProblemCriteria.getSelectionModel();
        model.setSelectionMode(SelectionMode.SINGLE);
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectCriterion((Criterion)newVal);
        });
        model = _listAssessCriteria.getSelectionModel();
        model.setSelectionMode(SelectionMode.SINGLE);
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectCriterion((Criterion)newVal);
        });
        model = _listResultsCriteria.getSelectionModel();
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectCriterion((Criterion)newVal);
        });

        model = _listProblemOptions.getSelectionModel();
        model.selectedItemProperty().addListener((ObservableValue obsVal, 
                Object oldVal, Object newVal) -> {
            selectOption((Option)newVal);
        });
    }


    private void selectProblem(Problem problem) {
        _curProblem = problem;
        MultipleSelectionModel model;
        if(problem==null){
            model = _listMyDecisionProblems.getSelectionModel();
            model.clearSelection();                    
        }else{
            model = _listMyDecisionProblems.getSelectionModel();
            model.select(_curProblem);        
        }
    }

    private void selectParticipant(Participant participant) {
        _curParticipant = participant;
        MultipleSelectionModel model;
        _listProblemParticipants.scrollTo(_curParticipant);
        model = _listProblemParticipants.getSelectionModel();
        model.select(_curParticipant);        
        _listAssessParticipants.scrollTo(_curParticipant);
        model = _listAssessParticipants.getSelectionModel();
        model.select(_curParticipant);        
        _listResultsParticipants.scrollTo(_curParticipant);
        model = _listResultsParticipants.getSelectionModel();
        model.select(_curParticipant);        
    }

    private void selectCriterion(Criterion criterion) {
        _curCriterion = criterion;
        MultipleSelectionModel model;
        _listProblemCriteria.scrollTo(_curCriterion);
        model = _listProblemCriteria.getSelectionModel();
        model.select(_curCriterion);        
        _listAssessCriteria.scrollTo(_curCriterion);
        model = _listAssessCriteria.getSelectionModel();
        model.select(_curCriterion);        
        _listResultsCriteria.scrollTo(_curCriterion);
        model = _listResultsCriteria.getSelectionModel();
        model.select(_curCriterion);
/*
        _listProblemCriteria.scrollTo(_curCriterion);
        FocusModel focus=_listProblemCriteria.getFocusModel();
        focus.focus();
*/
    }

    private void selectOption(Option option) {
        _curOption = option;
        MultipleSelectionModel model;
        model = _listProblemOptions.getSelectionModel();
        model.select(_curOption);        
    }
}
