package jforex;

import java.util.*;
import java.util.concurrent.*;

import com.dukascopy.api.*;

public class testCloseOrderWithTimerFIXED implements IStrategy {
	private IEngine engine;
	private IConsole console;
	private IHistory history;
	private IContext context;
	private IIndicators indicators;
	private IUserInterface userInterface;
	
    private IOrder order;
    
	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();
	}

	public void onAccount(IAccount account) throws JFException {
	}

	public void onMessage(IMessage message) throws JFException {
	}

	public void onStop() throws JFException {
	}

	public void onTick(Instrument instrument, ITick tick) throws JFException {
        //create order on first tick
        if (order == null) {
            double ask = tick.getAsk();
            long openTime = tick.getTime();
            double pip = instrument.getPipValue();
            order = engine.submitOrder("THIS_LABEL_HAS_TO_BUT_SHOULD_NOT_HAVE_TO_BE_UNIQUE",Instrument.EURUSD, IEngine.OrderCommand.BUY, 0.1, ask-300*pip,ask+300*pip);
            //time passed to timer is a delay, not a time when it should be executed
            long twoMins = 2 * 60000;
            console.getOut().println("scheduling order close");
            ScheduleOrderClose scheduleOrderClose = new ScheduleOrderClose(order, twoMins);
        }
	}
	
	public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
 	}

	class ScheduleOrderClose {
		Timer m_timer;
		IOrder m_order;
		
		public ScheduleOrderClose(IOrder order, long closeTime) {
			m_order = order;
			
			m_timer = new Timer();
			m_timer.schedule(new TimerAction(order), closeTime);
		}

		class TimerAction extends TimerTask {
			IOrder m_order;
			
			public TimerAction(IOrder order) {
				m_order = order;
			}
			
			public void run() {
                	console.getOut().println("Timer task run");
				if (m_order.getState() == IOrder.State.FILLED) {
                    //timer runs it's task in it's own thread, we need to close order in strategy thread, so create a task that will be executed in strategy thread
                    CloseOrderTask task = new CloseOrderTask(m_order);
                    context.executeTask(task);
				}
   				m_timer.cancel();
			}
		}//TimerAction
        private class CloseOrderTask implements Callable<Object> {
            IOrder m_order;
            public CloseOrderTask(IOrder order) {
                
m_order = order;
            }
            public Object call() {
                console.getOut().println("CloseOrderTask call");
                try {
                    //now we are in strategy thread, close order
                    
m_order.close();
                } catch (JFException e) {
                    //catching possible exception and printing it to messages
                    
console.getErr().println(e.getMessage());
                }
                return null;
            }
        }
	}//ScheduleOrderClose
}//testCloseOrderWithTimer