"""Base classes for Formatters for analysis of image series"""


# Nonstandard
import pandas as pd


class Formatter:
    """Base class for formatting of results spit out by analysis methods"""

    def __init__(self, analysis):
        """Link formatter to analysis object"""
        self.analysis = analysis

    def _prepare_data_storage(self):
        """Prepare structure(s) that will hold the analyzed data"""
        pass

    def _store_data(self, data):
        """How to store data generated by analysis on a single image.

        Input
        -----
        data is a dictionary, output of Analysis.analyze()
        """
        pass

    def _to_results(self):
        """How to pass stored data into an AnlysisResults class/subclass."""
        pass

    def _regenerate_data(self, num):
        """How to go back to raw data (as spit out by the analysis methods
        during analysis) from data saved in results or files.

        Useful for plotting / animating results again after analysis, among
        other things.
        """
        pass

    def _generate_data(self, num):
        """Adds num and image data to _regenerate_data"""
        data = self._regenerate_data(num=num)
        data['num'] = num
        data['image'] = self.analysis.img_series.read(num=num)
        return data


class PandasFormatter(Formatter):
    """Base class for formatting of results ad a pandas dataframe"""

    def _to_pandas(self):
        """How to convert data generated by _store_data() into a pandas table.

        Define in subclass.
        """
        pass

    def _to_results(self):
        """Add file info (name, time, etc.) to analysis results if possible.

        (img_series.info is defined only if ImgSeries inherits from filo.Series,
        which is not the case if img data is in a stack).
        """
        data_table = self._to_pandas()

        data_table.index = self.analysis.nums
        data_table.index.name = 'num'

        if self.analysis.img_series.is_stack:
            self.analysis.results.data = data_table
        else:
            info = self.analysis.img_series.info
            self.analysis.results.data = pd.concat(
                [info, data_table],
                axis=1,
                join='inner',
            )
