package tpStrategy;

import java.util.*;
import java.io.File;


//class loader
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;

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


public class TPStrategy implements IStrategy {
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;

    private static int startup=0;
    Object[][] copyOutputObj = new Object[2][]; // store raw output of the indicator
    double[]   copyOutputs; // store indicator's outputs converted to doubles
    
    private class Config {
        public Period mMonitorPeriod = Period.ONE_MIN;
        public Period mTradePeriod = Period.FIFTEEN_MINS;
        public Period mTrendPeriod = Period.FOUR_HOURS;
        }
    Config CFG =  new Config();
 
    public int registerCustomIndicator(IIndicators aIIndicators, String aIndicatorName, String aFileName) throws JFException {
        File tpiFile = new File(aFileName);
        aIIndicators.registerCustomIndicator(tpiFile);
        
        IIndicator tpiIndicator = aIIndicators.getIndicator(aIndicatorName);

        String tpiName = tpiIndicator.getIndicatorInfo().getName();
        int numOutputs = tpiIndicator.getIndicatorInfo().getNumberOfOutputs();
        
        console.getOut().print("onStart [indicatorName="+tpiName+"]: indicatorInfo - "+ tpiIndicator.getIndicatorInfo().getTitle() + " numOutputs="+numOutputs);
        return numOutputs;
       } 
       
    public void onStart(IContext context) throws  JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();
        this.history = context.getHistory();
        this.context = context;
        this.indicators = context.getIndicators();
        this.userInterface = context.getUserInterface();
        this.startup+=1;
        
        int numOutputs = registerCustomIndicator(indicators, "COPY","/Users/timepro/JForex/Indicators/Copy.jfx");
        copyOutputObj[0] = new Object[numOutputs];
             copyOutputs = new double[numOutputs];
        }
        
    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }

    public void onTick(Instrument aInstrument, ITick aTick) throws JFException {
    }
    
    public void onBar(Instrument aInstrument, Period aPeriod, IBar aAskBar, IBar aBidBar) throws JFException {
                 
        if(aPeriod == CFG.mTradePeriod) {
            /*
            ** save current indicator output if exists 
            */
            if(copyOutputObj[1] != null) System.arraycopy(copyOutputObj[1], 0, copyOutputObj[0], 0, copyOutputObj[0].length); 
            
            /*
            ** call COPY indicator
            */
            copyOutputObj[1] = indicators.calculateIndicator( 
                    aInstrument,
                    CFG.mTradePeriod,
                    new OfferSide[] {OfferSide.BID},
                    "COPY",
                    null, //new IIndicators.AppliedPrice[] {IIndicators.AppliedPrice.OPEN, IIndicators.AppliedPrice.CLOSE, IIndicators.AppliedPrice.HIGH, IIndicators.AppliedPrice.LOW, IIndicators.AppliedPrice.VOLUME}, 
                    new Integer[]{0}, 0); 
                  
            /*
            ** convert COPY indicator's output to double
            */
            for(int i=0; i<copyOutputs.length; i++) copyOutputs[i] = (Double)copyOutputObj[1][i];
            
            /*
            ** compare indicator's output with BidBar data
            */
            // Match with Bar Open
            if(aBidBar.getOpen() == copyOutputs[0])
                console.getOut().println("Bid bar Open = "+aBidBar.getOpen()+" == "+copyOutputs[0]);
            else 
                console.getErr().println("Bid bar Open = "+aBidBar.getOpen()+" != "+copyOutputs[0]);
                
            // Match with Bar Close
            if(aBidBar.getClose() == copyOutputs[1])
                console.getOut().println("Bid bar Close = "+aBidBar.getClose()+" == "+copyOutputs[1]);
            else 
                console.getErr().println("Bid bar Close = "+aBidBar.getClose()+" != "+copyOutputs[1]);    
            
            // Match with Bar High
            if(aBidBar.getHigh() == copyOutputs[2])
                console.getOut().println("Bid bar High = "+aBidBar.getHigh()+" == "+copyOutputs[2]);
            else 
                console.getErr().println("Bid bar High = "+aBidBar.getHigh()+" != "+copyOutputs[2]);
                
            // Match with Bar Low
            if(aBidBar.getLow() == copyOutputs[3])
                console.getOut().println("Bid bar Low = "+aBidBar.getLow()+" == "+copyOutputs[3]);
            else 
                console.getErr().println("Bid bar Low = "+aBidBar.getLow()+" != "+copyOutputs[3]);
                
            // Match with Bar Volume
            if(aBidBar.getVolume() == copyOutputs[4])
                console.getOut().println("Bid bar Volume = "+aBidBar.getVolume()+" == "+copyOutputs[4]);
            else 
                console.getErr().println("Bid bar Volume = "+aBidBar.getVolume()+" != "+copyOutputs[4]);
            }                                                              
        }
    
    /*
    ** draw (UNUSED)
    */    
    public void drawBarOutput(String aTag, Instrument aInstrument, Period aPeriod, Object[][] aOutput) throws JFException {
        IChart myChart=context.getChart(aInstrument);
        IChartObject myObject;
            
        if (myChart == null || aOutput[0]==null || aOutput[1]==null) return;
        
        IBar prevBar = history.getBar(aInstrument, aPeriod, OfferSide.BID, 2);
        IBar currBar = history.getBar(aInstrument, aPeriod, OfferSide.BID, 1);
          
        for(int i=0; i<aOutput[1].length-1; i++) { 
            
            console.getOut().println(i+"="+Double.parseDouble(aOutput[0][i].toString())+"-"+Double.parseDouble(aOutput[0][i].toString()));
            //line = chart.getChartObjectFactory().createHorizontalLine("objectname", tick.getBid());
            //IShortLineChartObject createShortLine(java.lang.Object... params)
            
            myObject = myChart.draw(aTag+"["+i+"]"+currBar.getTime(), 
                                    IChart.Type.SHORT_LINE,
                                    prevBar.getTime(), 
                                    (Double)aOutput[0][i], // aOutput[0]=previous output vector
                                    currBar.getTime(),
                                    (Double)aOutput[1][i]);// aOutput[1]=new output vector
            } // END FOR
        }
    }
    