package misc.support.jforex.indicators;
 
import com.dukascopy.api.IConsole;
import com.dukascopy.api.indicators.*;
import com.dukascopy.api.indicators.IIndicator;
import com.dukascopy.api.indicators.IIndicatorContext;
import com.dukascopy.api.indicators.IIndicatorsProvider;
import com.dukascopy.api.indicators.IndicatorInfo;
import com.dukascopy.api.indicators.IndicatorResult;
import com.dukascopy.api.indicators.InputParameterInfo;
import com.dukascopy.api.indicators.IntegerRangeDescription;
import com.dukascopy.api.indicators.OptInputParameterInfo;
import com.dukascopy.api.indicators.OutputParameterInfo;
 
public class own_ichi implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    private double[][][] inputs = new double[1][][];
    private int timePeriod1 = 9;
    private int timePeriod2 = 26;
    private int timePeriod3 = 52;
    private double[][] outputs = new double[5][];
    private IIndicator ichi;        
    
    private IConsole console;
 
    public void onStart(IIndicatorContext context) {
        IIndicatorsProvider indicatorsProvider = context.getIndicatorsProvider();
        this.console = context.getConsole();
        
        ichi = indicatorsProvider.getIndicator("ICHIMOKU");

        indicatorInfo = new IndicatorInfo("ichi_own", "own_ichi", "My indicators",
                false, false, true, 1, 3, 5);
        inputParameterInfos = new InputParameterInfo[] {
                new InputParameterInfo("Input data", InputParameterInfo.Type.PRICE)
        };
        optInputParameterInfos = new OptInputParameterInfo[] {
                new OptInputParameterInfo("tenkan", OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(9, 2, 1000, 1)),
                new OptInputParameterInfo("kijun", OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(26, 2, 1000, 1)),
                new OptInputParameterInfo("senkou", OptInputParameterInfo.Type.OTHER,
                                          new IntegerRangeDescription(52, 2, 1000, 1))};

        outputParameterInfos = new OutputParameterInfo[] {
                new OutputParameterInfo("Tenkan Sen", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
                new OutputParameterInfo("Kijun Sen", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
                new OutputParameterInfo("Chikou Span", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
                new OutputParameterInfo("Senkou A", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
                new OutputParameterInfo("Senkou B", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.LINE),
            };
    }
    
    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex = getLookback();
        }
        if (endIndex + getLookforward() >= inputs[0][0].length) {
            endIndex = inputs[0][0].length - 1 - getLookforward();
        }
        if (startIndex > endIndex) {
            return new IndicatorResult(0, 0);
        }
                 
        ichi.setInputParameter(0, inputs[0]);  
        
        ichi.setOptInputParameter(0, timePeriod1);   
        ichi.setOptInputParameter(1, timePeriod2);
        ichi.setOptInputParameter(2, timePeriod3);
        
        ichi.setOutputParameter(0, outputs[0]);    
        ichi.setOutputParameter(1, outputs[1]);    
        ichi.setOutputParameter(2, outputs[2]);     
        ichi.setOutputParameter(3, outputs[3]);     
        ichi.setOutputParameter(4, outputs[4]);     
        
        
        ichi.calculate(startIndex, endIndex);        
                
        IndicatorResult ir = ichi.calculate(startIndex, endIndex);
        
        return ir;
    }
 
    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }
 
    public InputParameterInfo getInputParameterInfo(int index) {
        if (index <= inputParameterInfos.length) {
            return inputParameterInfos[index];
        }
        return null;
    }
 
    public int getLookback() {
 
        return Math.max(timePeriod1, Math.max(timePeriod2, timePeriod3)) - 1;
    }
 
    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:
                timePeriod1 = (Integer) value;
                break;
            case 1:
                timePeriod2 = (Integer) value;
                break;
            case 2:
                timePeriod3 = (Integer) value;
                break;
        }
    }
 
    public void setOutputParameter(int index, Object array) {
        outputs[index] = (double[]) array;
    }
}