package jforex;

import com.dukascopy.api.indicators.*;

public class PrecioVsSMA implements IIndicator {
    private int numInputs    = 1;
    private int numOptInputs = 1;
    private int numOutputs   = 1;
    private IIndicator sma;        
    private int timePeriod;
    
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][] inputs = new double[numInputs][];
    private double[][] outputs = new double[numOutputs][];
    
    public void onStart(IIndicatorContext context) {
        indicatorInfo = new IndicatorInfo("PrecioVsSMA", "Diferencia entre precio y SMA", "My indicators",
                                          false, false, false, numInputs, numOptInputs, numOutputs);
                                          
        inputParameterInfos = new InputParameterInfo[] {
                              new InputParameterInfo("Precio", InputParameterInfo.Type.DOUBLE)
                              };
        optInputParameterInfos = new OptInputParameterInfo[] {
                                 new OptInputParameterInfo("Periodo", OptInputParameterInfo.Type.OTHER, new IntegerRangeDescription(14, 2, 100, 1))
                                 };                                 
        outputParameterInfos = new OutputParameterInfo[] {
                               new OutputParameterInfo("PrecioVsSMA", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM),
                               };

        sma = context.getIndicatorsProvider().getIndicator("SMA");                   
    }

    public IndicatorResult calculate(int startIndex, int endIndex) {
        
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        if (startIndex > endIndex) {
           return new IndicatorResult(0, 0);
        }

        double[] smaOutput = new double[endIndex - startIndex + 1 + sma.getLookback()];
        sma.setInputParameter(0, inputs[0]);
        sma.setOptInputParameter(0, timePeriod);
        sma.setOutputParameter(0, smaOutput);

        IndicatorResult smaResult = sma.calculate(startIndex - 1, endIndex);        

        int i, j;
        for (i = startIndex, j = 0; i <= endIndex; i++, j++) {
            outputs[0][j] = inputs[0][i] - smaOutput[j + 1];
        }
        return new IndicatorResult(startIndex, j);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }

    public int getLookback() {
        return timePeriod;
    }

    public int getLookforward() {
        return 0;
    }

    public OptInputParameterInfo getOptInputParameterInfo(int index) {
        if (index <= optInputParameterInfos.length) {
            return optInputParameterInfos[index];
        }
        return null;
    }

    public OutputParameterInfo getOutputParameterInfo(int index) {
        if (index <= outputParameterInfos.length) {
            return outputParameterInfos[index];
        }
        return null;
    }

    public void setInputParameter(int index, Object array) {
        inputs[index] = (double[]) array;
    }

    public void setOptInputParameter(int index, Object value) {
       switch (index) {
         case 0:    //Periodo
            timePeriod = (Integer)value;    sma.setOptInputParameter(0, timePeriod);          
            break;
        }
    }

    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
}