import DataReader as Dr
import PlottingAdapter as ad


class Plot:

    def __init__(self, model_files_path, single_sd_plot, list_of_params):
        self.listOfParams = list_of_params
        self.singlePlot = single_sd_plot
        self.modelFilesPath = model_files_path
        self.listOfFileTypes = ['._os', '._ww', '._r', '._w', '._ws', '._sd', '._sc', '._sc_svd', '._svd', '._pcc',
                                '._so', '._s1', '._pa', '._ss', '._scgrp']

        self.size = len(self.listOfFileTypes)
        self.plots = dict()

    def check_data(self):
        try:
            for file_type in self.listOfFileTypes:
                if file_type not in ['._scgrp']:
                    open(self.modelFilesPath + file_type)
        except IOError as _:
            return False
        return True

    def check_file(self, file_type):
        try:
            open(self.modelFilesPath + file_type)
            return True
        except IOError as _:
            return False

    def plot_chart(self, param):
        data = Dr.Reader.read_calibration(self.modelFilesPath + param)

        # OS
        if param == '._os':
            plot = ad.PlottingAdapter.plot_scatter_os(data)
        # WW
        elif param == '._ww':
            plot = ad.PlottingAdapter.plot_scatter_ww(data)
        # R
        elif param == '._r':
            x, y = Dr.Reader().modify_data_r(data)
            plot = ad.PlottingAdapter.plot_bar(x, y)
        # W
        elif param == '._w':
            x, y = Dr.Reader().modify_data_w(data)
            plot = ad.PlottingAdapter.plot_bar(x, y)
        # WS
        elif param == '._ws':
            plot = ad.PlottingAdapter.plot_scatter_ws(data)
        # SD
        elif param == '._sd':
            pf = Dr.Reader.modify_data_sd(data, self.listOfParams)


            if self.singlePlot:
                plot = ad.PlottingAdapter.plot_multiple_in_one(pf)
            else:
                if len(self.listOfParams) == 0:
                    col_wrap = 3
                elif len(self.listOfParams) <= 1:
                    col_wrap = 1
                elif len(self.listOfParams) <= 4:
                    col_wrap = 2
                else:
                    col_wrap = 3

                tmp = ad.PlottingAdapter.plot_facet(pf, col_wrap)
                plot = tmp.fig
        # SC
        elif param == '._sc':
            x, y = Dr.Reader.modify_data_sc(data)
            plot = ad.PlottingAdapter.plot_bar(x, y)
        # SC_GRP
        elif param == '._scgrp':
            data, groups = Dr.Reader.read_scgrp(self.modelFilesPath + param)
            plot = ad.PlottingAdapter.plot_bar_stacked_scgrp(data, groups)
        # SC_SVD
        elif param == '._sc_svd':
            data = Dr.Reader.read_calibration_without_first_and_last(self.modelFilesPath + param)
            plot = ad.PlottingAdapter.plot_bar_stacked(data)
            # sns.plt.ylabel('Composite Scaled Sensitivity Singular Value Decomposition')
        # SVD
        elif param == '._svd':
            data = Dr.Reader.read_calibration_without_first4(self.modelFilesPath + param)
            plot = ad.PlottingAdapter.plot_bar_stacked2(data)
            # sns.plt.ylabel('Process Model Parameter Contribution to each SVD Parameter')
            # sns.plt.xlabel('Singular Vector')
        # # PCC
        elif param == '._pcc':
            plot = ad.PlottingAdapter.plot_bar_positive_negative(data)
            # ssns.plt.ylabel('Parameter dependence, based on Parameter Correlation Coefficient')
        # SO
        elif param == '._so':
            x, y = Dr.Reader().modify_data_so(data)
            plot = ad.PlottingAdapter.plot_bar(x, y)
            # sns.plt.ylabel('Observation Dominance, based on Leverage')
        # S1
        elif param == '._s1':
            plot = ad.PlottingAdapter.plot_lines(data)
        # PA
        elif param == '._pa':
            data = Dr.Reader.read_pa(self.modelFilesPath + param)
            plot = ad.PlottingAdapter.plot_lines_itter(data, True)
        # SS
        elif param == '._ss':
            plot = ad.PlottingAdapter.plot_multiple_lines_annotated(data)
        else:
            return

        plot.tight_layout()

        self.plots[param] = plot

    def plot_figs(self):
        for file_type in self.listOfFileTypes:
            try:
                # print "plot and save: {}".format(file_type)
                if self.check_file(file_type):
                    self.plot_chart(file_type)
            except Exception as e:
                print e

    def make_plots(self):
        if not self.check_data():
            return False
        self.plot_figs()

    def get_plots(self):
        return self.plots

    def get_plot_without_label(self, which, label=False):
        # return new plot
        if which == 'OS':
            data = Dr.Reader.read_calibration(self.modelFilesPath + '._os')
            plot = ad.PlottingAdapter.plot_scatter_os(data, label)
        elif which == 'WW':
            data = Dr.Reader.read_calibration(self.modelFilesPath + '._ww')
            plot = ad.PlottingAdapter.plot_scatter_ww(data, label)
        elif which == 'WS':
            data = Dr.Reader.read_calibration(self.modelFilesPath + '._ws')
            plot = ad.PlottingAdapter.plot_scatter_ws(data, label)
        else:
            return None

        return plot  # path

    def getNotRelativePA(self):

        data = Dr.Reader.read_pa(self.modelFilesPath + '._pa')
        plot = ad.PlottingAdapter.plot_lines_itter(data, False)

        # path = os.path.join(self.tmpPath, 'plot' + 'pa_special' + 'without.png')
        # plot.savefig(path)
        # sns.plt.close()
        return plot  # path

