import veusz.plugins as plugins
import numpy as np

class IntegrateDatasetPlugin(plugins.DatasetPlugin):
    """Dataset plugin to integrate a dataset."""

    # tuple of strings to build position on menu
    menu = ('Integrate',)

    # internal name for reusing plugin later
    name = 'Integ'

    # string which appears in status bar
    description_short = 'Integrate using the trapazoidal rule'
    
    # string goes in dialog box
    description_full = ('Integrate using the trapazoidal rule.')
    
    def __init__(self):
        """Define input fields for plugin."""
        self.fields = [
            plugins.FieldDataset('ds_y', 'Dataset to integrate (dependent variable)'),
            plugins.FieldDataset('ds_x', 'Dataset to integrate against (independent variable)'),
            plugins.FieldDataset('ds_out', 'Output dataset name'),
            ]

    def getDatasets(self, fields):
        """Returns single output dataset (self.dsout).
        This method should return a list of Dataset objects, which can include
        Dataset1D, Dataset2D and DatasetText
        """

        # raise DatasetPluginException if there are errors
        if fields['ds_out'] == '':
            raise plugins.DatasetPluginException('Invalid output dataset name')

        # make a new dataset with name in fields['ds_out']
        self.ds_out = plugins.Dataset1D(fields['ds_out'])

        # return list of datasets
        return [self.ds_out]

    def updateDatasets(self, fields, helper):
        """Do integration of dataset.
        This function should *update* the dataset(s) returned by getDatasets
        """

        # get the input dataset - helper provides methods for getting other
        # datasets from Veusz
        ds_y = helper.getDataset(fields['ds_y'])
        ds_x = helper.getDataset(fields['ds_x'])

        x = ds_x.data
        y = ds_y.data

        # integrate using the trapezoidal rule
        dx = np.array(x[1:]-x[:-1])
        ave = np.array((y[1:]+y[:-1])/2.0)
        newdata = np.array(y)
        newdata[0] = 0.0
        newdata[1:] = np.cumsum(ave*dx)
        
        # update output dataset with input dataset (plus value) and errorbars
        self.ds_out.update(data=newdata)
#                           serr=ds_in.serr, perr=ds_in.perr, nerr=ds_in.nerr)

# add plugin classes to this list to get used
plugins.datasetpluginregistry.append(IntegrateDatasetPlugin)