package singlejartest.Indicators;

import com.dukascopy.api.*;
import com.dukascopy.api.indicators.*;

import java.awt.*;

// dummy indicator for testing purposes only...
public class TestIndicator implements IIndicator {

    private IIndicatorContext context;
    private IndicatorInfo indicatorInfo;
    private InputParameterInfo[] inputParameterInfos;
    private InputParameterInfo barInput;
    private OutputParameterInfo[] outputParameterInfos;
    private OptInputParameterInfo[] optInputParameterInfos;
    private IBar[][] inputs = new IBar[1][];
    private double[][] outputs = new double[5][];
    private IBar iBar;
    private IBar iBarLast;
    private Period period;
    private int nDisplayType;


    public void onStart(IIndicatorContext _context) {

    	context = _context;
        indicatorInfo = new IndicatorInfo("TestIndicator", "Test", "TEST", false, false, true, 1, 3, 5);
    	
        //load Period values and names
        int[] periodValues = new int[Period.values().length];
        String[] periodNames = new String[Period.values().length];
        for (int i = 0; i < periodValues.length; i++)
        {            
        	periodValues[i] = i;            
        	periodNames[i] = Period.values()[i].name();
        }
        //load currency values and names
        int[] instrumentValues = new int[Instrument.values().length];
        String[] instrumentNames = new String[Instrument.values().length];
        for (int i = 0; i < instrumentValues.length; i++)
        {            
        	instrumentValues[i] = i;            
        	instrumentNames[i] = Instrument.values()[i].name();
        }

        //define displaytype
        int[] valueDisplayTypeValues = new int[]{0, 1, 2};
        String[] valueDisplayTypeNames = new String[]{"Block", "0.0 to 1.0", "-1.0 to 1.0"};
        
        
        optInputParameterInfos = new OptInputParameterInfo[]
        {
	   		//period as optional input (only shows, if selected period is higher than the currently selected period on the chart)
    	   	new OptInputParameterInfo("Instrument", OptInputParameterInfo.Type.OTHER,
    	    new IntegerListDescription(Instrument.EURUSD.ordinal(), instrumentValues, instrumentNames)),
	   		new OptInputParameterInfo("Period", OptInputParameterInfo.Type.OTHER,
	   		new IntegerListDescription(Period.FIFTEEN_MINS.ordinal(), periodValues, periodNames)),
    	   	new OptInputParameterInfo("ValueDisplayType", OptInputParameterInfo.Type.OTHER,
    	    	    new IntegerListDescription(0, valueDisplayTypeValues, valueDisplayTypeNames))
	    };
    	
        barInput = new InputParameterInfo("Bar.Input", InputParameterInfo.Type.BAR);
        inputParameterInfos = new InputParameterInfo[] {
                barInput
        };
        outputParameterInfos = new OutputParameterInfo[] {
            new OutputParameterInfo("Value1", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.GREEN.darker());
                }},
           new OutputParameterInfo("Value2", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.GREEN);
                }},
           new OutputParameterInfo("Value3", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.GRAY);
                }},
           new OutputParameterInfo("Value4", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.RED);
                }},
           new OutputParameterInfo("Value5", OutputParameterInfo.Type.DOUBLE, OutputParameterInfo.DrawingStyle.HISTOGRAM)
                {{
                     setColor(Color.RED.darker());
                }}
        };
    }

    public IndicatorResult calculate(int startIndex, int endIndex) {
        //calculating startIndex taking into account lookback value
        if (startIndex - getLookback() < 0) {
            startIndex -= startIndex - getLookback();
        }
        if (startIndex >= endIndex || inputs[0].length < endIndex) {
        	context.getConsole().getOut().println("Testindicator: index/inputs-arraysize problem: startIdx/endIdx=" + startIndex + "/" + endIndex + ", inputs.length=" + inputs[0].length);
            return new IndicatorResult(0, 0);
        }

        int i = 0;
        for(i=startIndex+1; i <= endIndex; i++){
        	
        	outputs[0][i] = Double.NaN;
        	outputs[1][i] = Double.NaN;
        	outputs[2][i] = Double.NaN;
        	outputs[3][i] = Double.NaN;
        	outputs[4][i] = Double.NaN;
        	
            //indicator logic here:
            
            //dummy statement for testing the input arraysize error
            outputs[i % 5][i] = 1.0;
        }
        return new IndicatorResult(startIndex, i);
    }


    public IndicatorInfo getIndicatorInfo() {
        return indicatorInfo;
    }

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

    public int getLookback() {
        return 0;
    }

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

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

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

    //this method reacts on every optional input parameter change
    public void setOptInputParameter(int index, Object value)
    {
        int enumIndex = ((Integer) value).intValue();
        if (index == 0)
        {          
        	barInput.setInstrument(Instrument.values()[enumIndex]);
        }
        else if (index == 1) 
        {          
        	period = Period.values()[enumIndex];
        	//autochange the period, if it is smaller than the currently selected chart-period
        	if (context != null && context.getPeriod() != null && context.getPeriod().getInterval() > period.getInterval())
        	{
        		period = context.getPeriod();
        	}
        	barInput.setPeriod(period);
        }
        else if (index == 2)	//display type
        {
        	nDisplayType = enumIndex;
        }
    }

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

    public int getLookforward() {
        return 0;
    }
}