from umetrics import *
from ribbonabc import RibbonAddInABC
from tkinter import Tk, ttk, LEFT
import csv
import tempfile
import io
import os

class ChooseOne():
    def __init__(self, items, message, default=0):
        """
        Create a dialog that lets the user choose one of several text strings.
        The dialog will have a label with a message, a combobox and an OK and Cancel button
        items   --- a list of strings to choose from.
        message --- a message to display in the dialog
        default --- the index of the default string in the list
        """
        self.root = Tk()
        self.root.title('Choose')
        label=ttk.Label(self.root, text=message)
        label.pack(padx=5, pady=5)

        self.combobox = ttk.Combobox(self.root, state='readonly')
        self.combobox['values'] = items
        self.combobox.current(default)
        self.combobox.pack(fill='x', padx=5, pady=5)

        # Call the on_ok() method when the button is clicked.
        ok_button = ttk.Button(self.root, text = "OK", command = self.on_ok)
        ok_button.pack(side=LEFT, padx=5, pady=5);

        # Call root.destroy() when the button is clicked
        cancel_button = ttk.Button(self.root, text = "Cancel", command = self.root.destroy)
        cancel_button.pack(side=LEFT, padx=5, pady=5);

        # Initialize the selected value to an empty string
        self.selected=''
        self.root.mainloop()

    def on_ok(self):
        # Get the currently selected string and close the dialog.
        self.selected=self.combobox.get()
        self.root.destroy()

    def get_selected(self):
        """
        Returns the selected string or an empty string if the user pressed cancel.
        """
        return self.selected

class AddInCommand(RibbonAddInABC):
    def __init__(Self):
        Self.icon_file_name = r'umetrics_cube.png'
        Self.tooltip = 'Create a new PLS model using the first dataset.'

    def enable_command(Self):
        # Disable button if SIMCA has no active project
        with SimcaApp.get_active_project() as project:
            if not project:
                return False
            return True

    def on_command(Self) :
        project = SimcaApp.get_active_project()
        datasets = project.get_dataset_infos()
        dataset = project.get_dataset(datasets[0].ID)
        variables = dataset.get_var_names()
        dialog = ChooseOne(variables, 'Select Y-variable')
        y_variable = dialog.get_selected();
        # If the string is empty, the user pressed Cancel.
        if not y_variable:
            return
        print("Selected Y-variable: ", y_variable)
        # Create a new workset using the first dataset
        workset=project.create_workset(datasets[0].ID)
        # Set all variables as X variables
        workset.set_x([])
        # And set the slected variable as Y
        workset.set_y(y_variable)
        workset.set_type(simca.modeltype.pls)
        models=workset.create_model()
        # create_model returns a list of the created models numbers.
        # If the workset contains classes more than one model will be created.
        # In this case we will only get one but we still fit the model in a loop.
        for model in models:
            # Fit the model with at least one component.
            project.fit_model(model, mincomp=1)
        project.save()

    def get_button_name(Self):
        return 'New PLS model'

class ExportData(RibbonAddInABC):
    def __init__(Self):
        Self.tooltip = 'Exports scores from the last model to a spreadsheet.'

    def enable_command(Self):
        with SimcaApp.get_active_project() as project:
            if not project:
                return False
            model=project.get_active_model();
            if model <= 0:
                return False
            model_infos=project.get_model_infos()
            active_model_info=next(info for info in model_infos if info.number == model)
            if not active_model_info.components:
                return False
            return True

    def on_command(Self):
        project = SimcaApp.get_active_project()
        data_builder=project.data_builder()
        model_number=project.get_active_model()
        scores=data_builder.create('t', model=model_number)
        # Create a csv file in windows temp directory
        file_name = tempfile.mktemp(suffix='.csv')
        file=io.open(file_name, mode='w', newline='')
        csv_file=csv.writer(file, delimiter=';')
        # Write the value identifiers (in this case observation names) to the first row. 
        # We need to insert an empty string first since the first column contains series names.
        first_line=[''] + scores.get_value_ids().get_names()
        csv_file.writerow(first_line)
        series_names = scores.series_names()
        data=scores.matrix()
        for serie_index in range(len(series_names)):
            serie=[series_names[serie_index]] + list(data[serie_index])
            csv_file.writerow(serie)
        file.close()
        # Let windows open the file with the default application for .csv files.
        os.startfile(file_name)

    def get_button_name(Self):
        return 'Export scores'

group_name = 'Example 2'
group_order = [AddInCommand, ExportData]