/*
 * Copyright 2011 Dukascopy Bank SA. All rights reserved.
 * DUKASCOPY PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.dukascopy.api.impl.connect.sandbox;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

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.IEngine.OrderCommand;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.IOrder.State;
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;

/**
 * @author aburenin
 */
public class CustomThreadStrategy implements IStrategy {
    
    private final int controlPanelWidth = 260;
    private final int controlPanelHight = 40;
    
    private IContext context;
    private IConsole console;
    private IEngine engine;
    private IOrder order;
    
    final JButton open = new JButton("Submit Order");
    final JButton close = new JButton("Close Order");
    
    
    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onStart(com.dukascopy.api.IContext)
     */
    @Override
    public void onStart(IContext context) throws JFException {
        this.context = context;
        engine = context.getEngine();
        console = context.getConsole();
        showControlFrame();
    }

    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onTick(com.dukascopy.api.Instrument, com.dukascopy.api.ITick)
     */
    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onBar(com.dukascopy.api.Instrument, com.dukascopy.api.Period, com.dukascopy.api.IBar, com.dukascopy.api.IBar)
     */
    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onMessage(com.dukascopy.api.IMessage)
     */
    @Override
    public void onMessage(IMessage message) throws JFException {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onAccount(com.dukascopy.api.IAccount)
     */
    @Override
    public void onAccount(IAccount account) throws JFException {
        // TODO Auto-generated method stub

    }

    /* (non-Javadoc)
     * @see com.dukascopy.api.IStrategy#onStop()
     */
    @Override
    public void onStop() throws JFException {
        console.getInfo().println("Strategy stopped");
    }
    
    private void showControlFrame(){
        JFrame main = new JFrame("Strategy Control");
        
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension screenSize = tk.getScreenSize();
        int screenHeight = screenSize.height;
        int screenWidth = screenSize.width;
        main.setLocation(screenWidth / 4, screenHeight / 4);
        main.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent e) {
                context.stop();
            }
        });
        
        
        JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        controlPanel.setPreferredSize(new Dimension(controlPanelWidth, controlPanelHight));
        controlPanel.setMinimumSize(new Dimension(controlPanelWidth, controlPanelHight));
        controlPanel.setMaximumSize(new Dimension(controlPanelWidth, controlPanelHight));
        
        open.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                console.getOut().println("Submit order ...");
                Future<IOrder> future =  context.executeTask(new SubmitOrderCall());
                try {
                    order = future.get();
                    order.waitForUpdate(State.FILLED, State.CANCELED);
                    console.getOut().println("Order submitted: " + order);
                    updateControl(false);
                } catch (Exception exc) {
                    console.getErr().println("Submit order error: " + exc);
                    context.stop();
                }
            }
        });
        
        
        close.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                if (order != null && order.getState() == State.FILLED){
                    Future<Void> future =  context.executeTask(new CloseOrderCall());
                    try {
                        future.get();
                        order.waitForUpdate(State.CLOSED, State.CANCELED);
                        console.getOut().println("order closed");
                        updateControl(true);
                    } catch (Exception exc) {
                        console.getErr().println("Close order error: " + exc);
                        context.stop();
                    }
                }
            }
        });
        
        updateControl(true);
        
        controlPanel.add(open);
        controlPanel.add(close);
        main.getContentPane().add(controlPanel);
        main.pack();
        main.setVisible(true);
    }
    
    private void updateControl(boolean submitEnable){
        open.setEnabled(submitEnable);
        close.setEnabled(!submitEnable);
    }
    
    
    private class SubmitOrderCall implements Callable<IOrder> {
        /* (non-Javadoc)
         * @see java.util.concurrent.Callable#call()
         */
        @Override
        public IOrder call() throws Exception {
            return engine.submitOrder("o1", Instrument.EURUSD, OrderCommand.BUY, 0.001);
        }
    }
    
    private class CloseOrderCall implements Callable<Void> {
        /* (non-Javadoc)
         * @see java.util.concurrent.Callable#call()
         */
        @Override
        public Void call() throws Exception {
            order.close();
            return null;
        }
    }
}
