package jforex;

import java.util.*;

import com.dukascopy.api.*;
import java.awt.*;
import java.awt.event.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.swing.*;
import java.text.*;

/**
* Created by: R.Nebor
* Date: February 19, 2010
* Time: 06:30:00 PM
* Modified by: simplex
* Date: Semptember 22, 2010
* Time: 06:00:00 PM
* Modified by: Roadrunner
* Date: February 16, 2011
* Time: 13:00:00 PM
*       renamed from Spread to TickLineLabel
*       remaining time formatted in [hh:]mm:ss
*       added: optional display of total of pips and Earnings of open positions (tick the "Show P/L" parameter to show)
* Modified by: Roadrunner
* Date: April 08, 2011
* Time: 17:30:00 PM
*       replaced spreadColor by enum LabelColor to be able to display userdefined colorlist in the param dialog
*       in order to switch color dynamically during the run, in the workspace frame select "Parameters" from strategy context menu
*/

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

    private Font ourFont;
    @Configurable("Pip distance") public double nbPipsDistance = 1.5;
    @Configurable("Candle Distance") public int nbPeriodDistance = 2;
    @Configurable("Show P/L") public boolean nbShowPL = false;
    @Configurable("Font Size") public int fontSize = 13;
    @Configurable("Instrument") public Instrument instrument = Instrument.GBPJPY;
    @Configurable("Font Name") public String fontName = "ARIAL";
    @Configurable("Color")  public LabelColor labelColor = LabelColor.BLUE;
    
    public enum LabelColor
    {
        //this is just a sample list of colors defined using different method. Please add your favorite colors to the list :) :
        BLACK (Color.BLACK),
        WHITE (Color.WHITE),
        RED (Color.RED), 
        BLUE (Color.BLUE), 
        GREEN (Color.GREEN.darker()), 
        ORANGE (Color.ORANGE.darker()),
        YELLOW (Color.ORANGE),
        MAGENTA (new Color(255, 0, 255));
        
        private final Color col;
        LabelColor(Color _color)
        {
            this.col = _color;
        }
        private Color getColor()
        { 
            return this.col;
        }
    }
    
    
    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.account = context.getAccount();

        ourFont = Font.decode( fontName + "-PLAIN-" + fontSize);
    }
    

    public void onTick(final Instrument instrument, final ITick tick) throws JFException {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                
                public void run() {
                    try {
                        
                        Set<IChart> setOfCharts = context.getCharts(instrument);
                        for (IChart currentChart: setOfCharts){
          
                            if(currentChart == null)
                            return;
                            
                            Period chartPeriod=currentChart.getSelectedPeriod();
                            long currentTime=tick.getTime();
                            long barStart;
                            long nextBarStart;   
                            long timeDif; 
                            String sRemainingTime = "";
                            
                            if(currentChart.getSelectedPeriod() != Period.TICK)
                            {
                                barStart = history.getBarStart(chartPeriod, currentTime);
                                nextBarStart = history.getNextBarStart(chartPeriod, currentTime);   
                                timeDif=nextBarStart-currentTime;
                                sRemainingTime = getFormattedTime(((nextBarStart-barStart)-(currentTime-barStart)));
                            }
                            drawTickLineLabel(instrument, tick, sRemainingTime, currentChart);
                        }
                        
                        
                        return;
                    }
                    catch (Exception e) {
                        context.getConsole().getOut().println(e);
                    }                                       
                }
            });     
        } 
        catch (Exception e) {
            context.getConsole().getOut().println(e);
        }                  
    }
    
    

    public void onAccount(IAccount _account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }
    
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
    }    

    public void drawTickLineLabel(Instrument inst, ITick tick, String sTime, IChart chart) {  
        BigDecimal spread = BigDecimal.valueOf(tick.getAsk()).subtract(BigDecimal.valueOf(tick.getBid())).multiply(BigDecimal.valueOf(10).pow(inst.getPipScale())).setScale(1, BigDecimal.ROUND_HALF_EVEN);
        IChartObject cot = (IChartObject) chart.get("spread_txt");

        
        String sTickLabel = sTime + " [" + spread.toString() + "p" + getPLLabel(inst) + "]";
        
        if ( cot != null )
          cot.move(tick.getTime() + nbPeriodDistance * chart.getSelectedPeriod().getInterval() , tick.getBid() + nbPipsDistance * inst.getPipValue());
        else
          cot = chart.draw( "spread_txt", IChart.Type.TEXT , tick.getTime() + nbPeriodDistance * chart.getSelectedPeriod().getInterval(), tick.getBid() + nbPipsDistance  * inst.getPipValue());

        cot.setText(sTickLabel, ourFont);
        cot.setColor(labelColor.getColor());
        return;
    }
    
    public String getFormattedTime(long _lRemainingTime) throws JFException {
        String sFormattedTime; 
        String sFormat = "HH:mm:ss";
        SimpleDateFormat fTime;
        if(_lRemainingTime >= 3600000L)
        {
            fTime = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH);
        }
        else
        {
            fTime = new SimpleDateFormat("mm:ss", Locale.ENGLISH);
        }
        sFormattedTime = fTime.format(_lRemainingTime);    
        return sFormattedTime;
    }    
    
    public String getPLLabel(Instrument inst)
    {
        StringBuilder sbPL = new StringBuilder();
        if (nbShowPL)
        {
            double dFilledTradesPL = 0.0;
            double dFilledTradesPips = 0.0;
            try
            {
                for (IOrder order: engine.getOrders(inst))
                {
                    if (order.getState() == IOrder.State.FILLED)
                    {
                        dFilledTradesPL += order.getProfitLossInAccountCurrency();
                        dFilledTradesPips += order.getProfitLossInPips();
                    }
                }
                if (dFilledTradesPL != 0.0)
                {
                    NumberFormat fUSNumber = NumberFormat.getIntegerInstance(Locale.US);
                    sbPL.append("] [PL=" + new DecimalFormat("#0.0").format(dFilledTradesPips) + "p  ");
                    if (Math.abs(dFilledTradesPL) < 1000.0)
                         sbPL.append( new DecimalFormat("#0.0").format(dFilledTradesPL));
                    else
                        sbPL.append(NumberFormat.getIntegerInstance(Locale.US).format(dFilledTradesPL));
                        
                   sbPL.append(account.getCurrency().getSymbol());
                }
    
            }
            catch (Exception e)
            {
                console.getOut().println(e.getMessage());
             }
        }
        
        return sbPL.toString();
    }


}


