package jforex;

import com.dukascopy.api.indicators.*;
import com.dukascopy.api.*;
import com.dukascopy.api.IIndicators.AppliedPrice;
import java.awt.*;

public class SSL implements IIndicator {
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private InputParameterInfo[] info;
    private OptInputParameterInfo[] optInputParameterInfos;
    private OutputParameterInfo[] outputParameterInfos;
    //Price includes 5 arrays: open, close, high, low, volume
    private double[][][] inputsPriceArr = new double[1][][];
    private int timePeriod = 10;
    
    private double[][] outputs = new double[3][];

    private IIndicator SMAhigh;
    private IIndicator SMAlow;
    
    private boolean init = true;
    private int trigger;
    
    private IConsole console;
   
    
    
    public void onStart(IIndicatorContext context) {
        
        this.console = context.getConsole();
        
        
        IIndicatorsProvider provider = context.getIndicatorsProvider();
        
        indicatorInfo = new IndicatorInfo("SSL", "SSL", "My indicators",
                true, false, false, 1, 1, 1);
        
        SMAhigh = provider.getIndicator("SMA");
        SMAlow = provider.getIndicator("SMA");

        inputParameterInfos = new InputParameterInfo[] { 
                new InputParameterInfo("Price arrays", InputParameterInfo.Type.PRICE)
        };
        
        optInputParameterInfos = new OptInputParameterInfo[] {
            new OptInputParameterInfo("Time period", OptInputParameterInfo.Type.OTHER,
                new IntegerRangeDescription(timePeriod, 2, 100, 1))
        };
        outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("SSL", OutputParameterInfo.Type.DOUBLE,
                OutputParameterInfo.DrawingStyle.LINE) {{ setColor(Color.green);
                                                          setColor2(Color.red);
                                                          setLineWidth(2); }}
        };
    }

    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        
        //Price includes 5 arrays: open, close, high, low, volume
        double[] SMAhighOutput = new double[endIndex - startIndex + 1];
        SMAhigh.setInputParameter(0, inputsPriceArr[0][2]);
        SMAhigh.setOutputParameter(0, SMAhighOutput);
        SMAhigh.calculate(startIndex, endIndex);
        
        
        double[] SMAlowOutput = new double[endIndex - startIndex + 1];
        SMAlow.setInputParameter(0, inputsPriceArr[0][3]);
        SMAlow.setOutputParameter(0, SMAlowOutput);
        SMAlow.calculate(startIndex, endIndex);
        

        
        int i, j;
        for (i = startIndex, j = 0; i <= endIndex; i++, j++) {
            if (inputsPriceArr[0][1][i-1] < SMAhighOutput[j] && inputsPriceArr[0][1][i] > SMAhighOutput[j]) {
                trigger = 1; //switch to low SMA 
            } else if (inputsPriceArr[0][1][i-1] > SMAlowOutput[j] && inputsPriceArr[0][1][i] < SMAlowOutput[j]) {
                trigger = 0; //switch to high SMA
            }
            /*
            if (init) {
                if (inputsPriceArr[0][1][i] > SMAhighOutput[j]) {
                    trigger = 1;
                } else if (inputsPriceArr[0][1][i] < SMAlowOutput[j]) {
                    trigger = 0;
                }
                init = false;
            }*/
                
            
            if (trigger == 1) {
                outputs[0][j] = SMAlowOutput[j];
            }
            
            if (trigger == 0) {
                outputs[0][j] = SMAhighOutput[j];
            }
        }
        return new IndicatorResult(startIndex, endIndex-startIndex + 1);
    }

    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public int getLookback() {
        SMAhigh.setOptInputParameter(0, timePeriod);
        int SMAhighLookback = SMAhigh.getLookback() + 100;
        SMAlow.setOptInputParameter(0, timePeriod);
        int SMAlowLookback = SMAlow.getLookback() + 100;
        return Math.max(SMAhighLookback, SMAlowLookback);
    }

    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) {
        inputsPriceArr[0] = (double[][]) array;
    }

    public void setOptInputParameter(int index, Object value) {
        timePeriod = (Integer) value;
    }

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