package jforex;

import com.dukascopy.api.*;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;


public class DisableTradeOnWeekend implements IStrategy {

	private IEngine engine;
	private IConsole console;
	private IHistory history;
	private IIndicators indicators;
	private IContext context;

	@Configurable("Instrument")
	Instrument instrument = Instrument.EURUSD;
	@Configurable("Period")
	Period period = Period.TEN_MINS;


	@Configurable("Open hour")
	public int openHour = 0;
	@Configurable("Open min")
	public int openMin = 0;
	@Configurable("Open day")
	public DayOfWeek openDayOfWeek = DayOfWeek.MONDAY;

	@Configurable("Close hour")
	public int closeHour = 24;
	@Configurable("Close min")
	public int closeMin = 0;
	@Configurable("Close day")
	public DayOfWeek closeDayOfWeek = DayOfWeek.FRIDAY;

	enum DayOfWeek {
		SUNDAY(1),
		MONDAY(2),
		TUESDAY(3),
		WEDNESDAY(4),
		THURSDAY(5),
		FRIDAY(6),
		SATURDAY(7);

		private int idx;

		private DayOfWeek(int idx) {
			this.idx = idx;
		}
		public int getIdx() {
			return idx;
		}
	}

	boolean canTrade = false;

	@Override
	public void onStart(IContext context) throws JFException {
		this.console = context.getConsole();
		this.indicators = context.getIndicators();
		this.history = context.getHistory();
		this.engine = context.getEngine();
		this.context = context;
	}


	@Override
	public void onTick(Instrument instrument, ITick tick) throws JFException {
		if(!this.instrument.equals(instrument)) {
			return;
		}

		boolean canTrade = isInInterval(tick.getTime(),
				openDayOfWeek.getIdx(),  openHour,  openMin,
				closeDayOfWeek.getIdx(), closeHour, closeMin);

		if(!canTrade) {
			closeAll();
			return;
		}

		/// trade logic
	}

	@Override
	public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
		if(!this.instrument.equals(instrument) || !this.period.equals(period)) {
			return;
		}

		if(!canTrade) {
			return;
		}

		/// trade logic
	}

	void closeAll() throws JFException {
		List<IOrder> orders = engine.getOrders();
		engine.closeOrders(orders);
	}

	@Override
	public void onMessage(IMessage message) throws JFException {
	}

	@Override
	public void onAccount(IAccount account) throws JFException {
	}

	@Override
	public void onStop() throws JFException {
	}

	public boolean isInInterval(long time, int fromDayOfWeek, int fromHour, int fromMin, int toDayOfWeek, int toHour, int toMin){
		Calendar calFrom = new GregorianCalendar();
		calFrom.setTimeZone(TimeZone.getTimeZone("GMT"));
		calFrom.setTimeInMillis(time);
		calFrom.set(Calendar.HOUR_OF_DAY, fromHour);
		calFrom.set(Calendar.MINUTE, fromMin);

		Calendar calTo = new GregorianCalendar();
		calTo.setTimeZone(TimeZone.getTimeZone("GMT"));
		calTo.setTimeInMillis(time);
		calTo.set(Calendar.HOUR_OF_DAY, toHour);
		calTo.set(Calendar.MINUTE, toMin);

		Calendar calCurrent = new GregorianCalendar();
		calCurrent.setTimeZone(TimeZone.getTimeZone("GMT"));
		calCurrent.setTimeInMillis(time);

		if(calFrom.getTimeInMillis() <= time && time <= calTo.getTimeInMillis() &&
				fromDayOfWeek <= calCurrent.get(Calendar.DAY_OF_WEEK) && calCurrent.get(Calendar.DAY_OF_WEEK) <= toDayOfWeek ) {
			return true;
		}
		return false;
	}

}
