// if (order.getComment() == 1; bskets

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import com.dukascopy.api.Configurable;
import com.dukascopy.api.IAccount;
import com.dukascopy.api.IBar;
import com.dukascopy.api.IConsole;
import com.dukascopy.api.IContext;
import com.dukascopy.api.IEngine;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IStrategy;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.Period;
import com.dukascopy.api.IEngine.OrderCommand;

public class Little_Red_Riding_Hood_Basket_V1 implements IStrategy {
    private IEngine engine;
    private IConsole console;
    private String string = "";
    private int counter = 0;
    private Map<String, Set<IOrder>> baskets;

    private Stack<IOrder> buyOrdrsInstrument1 = new Stack<IOrder>();
    private Stack<IOrder> sellOrdrsInstrument1 = new Stack<IOrder>();

    private Stack<IOrder> buyOrdrsInstrument2 = new Stack<IOrder>();
    private Stack<IOrder> sellOrdrsInstrument2 = new Stack<IOrder>();

    @Configurable("Instrument 1")
    public Instrument instrument1 =  Instrument.AUDJPY;
    @Configurable("Instrument 2")
    public Instrument instrument2 = Instrument.CADJPY;

    @Configurable("Profit per Basket BUY/SELL")
    public double maxProfit = 100;
    @Configurable("Slippage")
    public double slippage = 2;
    @Configurable("Amount")
    public double amount = 0.1;

    private Set<String> processedOrdersId;

    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.setConsole(context.getConsole());

        this.baskets = new HashMap<String, Set<IOrder>>();
        processedOrdersId = new HashSet<String>();

    }

    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 {
        List<IOrder> orders = engine.getOrders();

        if (sellOrdrsInstrument1.isEmpty()) {sellOrdrsInstrument1.push(submitOrder(OrderCommand.SELL, instrument1));}
        if (buyOrdrsInstrument1.isEmpty()){buyOrdrsInstrument1.push(submitOrder(OrderCommand.BUY, instrument1));}
        
        if (sellOrdrsInstrument2.isEmpty()) {sellOrdrsInstrument2.push(submitOrder(OrderCommand.SELL, instrument2));}
        if (buyOrdrsInstrument2.isEmpty()){buyOrdrsInstrument2.push(submitOrder(OrderCommand.BUY, instrument2));}

        
        for (IOrder order : orders) {

            if (order.getComment() == null || processedOrdersId.contains(order.getId()))
                continue;
            Set<IOrder> basket = baskets.get(order.getComment());

            if (basket == null) {
                basket = new HashSet<IOrder>();
                baskets.put(order.getComment(), basket);
//                console.getInfo().println("add basket with name:" + order.getComment());
            }

            if (!basket.contains(order)) {
                basket.add(order);
                processedOrdersId.add(order.getId());
//                console.getInfo().println("add order to basket:" + order.getComment());
            }

        }

    }

    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        for (String basketName : baskets.keySet()) {
            Set<IOrder> basket = baskets.get(basketName);
            double summProfitLoss = 0;
            boolean needToClose = false;
            for (IOrder order : basket) {

                summProfitLoss += order.getProfitLossInAccountCurrency();

//                console.getInfo().println("summProfitLoss:" + summProfitLoss);
                if (summProfitLoss >= maxProfit ) {
                    needToClose = true;
                }
            }

            if (needToClose) {

                Set<IOrder> ordersForRemoving = new HashSet<IOrder>();
                for (IOrder order : basket) {
                    IOrder.State orderState = order.getState();
                    if (orderState == IOrder.State.OPENED || orderState == IOrder.State.FILLED) {

                            order.close(); order.waitForUpdate(1000);

                            if (order.getState() != IOrder.State.CREATED) {
                                ordersForRemoving.add(order);
                            } 

                        if (!order.isLong()) {
                                if (!buyOrdrsInstrument1.isEmpty()) {buyOrdrsInstrument1.pop();}
                                if (!buyOrdrsInstrument2.isEmpty()) {buyOrdrsInstrument2.pop();}}
                        else if (order.isLong()) {
                                if (!sellOrdrsInstrument1.isEmpty()) {sellOrdrsInstrument1.pop();}
                                if (!sellOrdrsInstrument2.isEmpty()) {sellOrdrsInstrument2.pop();}}
                    }
                }
                basket.removeAll(ordersForRemoving);
 //               console.getInfo().println("Close orders in basket:" + basketName + ":" + baskets.get(basketName));

            }
        }

    }
    private IOrder submitOrder(OrderCommand orderCmd, Instrument instrument) throws JFException {

        double stopLossPrice = 0.0, takeProfitPrice = 0.0;
        if (orderCmd == OrderCommand.BUY) { string = "BUY";
        } else if (orderCmd == OrderCommand.SELL) { string = "SELL";
        }

        return engine.submitOrder(getLabel(instrument), instrument, orderCmd, amount, 0, slippage, stopLossPrice,
                takeProfitPrice,0,string);
    }
    private String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label + (counter++);
        label = label.toUpperCase();
        return label;
    }

    public IConsole getConsole() {
        return console;
    }

    public void setConsole(IConsole console) {
        this.console = console;
    }
}
