package gethistprices;

import java.util.Calendar;
import java.util.concurrent.ConcurrentLinkedQueue;
import com.fxcore2.O2GMarketDataSnapshotResponseReader;
import com.fxcore2.O2GRequest;
import com.fxcore2.O2GRequestFactory;
import com.fxcore2.O2GResponse;
import com.fxcore2.O2GResponseReaderFactory;
import com.fxcore2.O2GResponseType;
import com.fxcore2.O2GSession;
import com.fxcore2.O2GTimeConverter;
import com.fxcore2.O2GTimeConverterTimeZone;
import com.fxcore2.O2GTimeframe;
import com.fxcore2.O2GTimeframeCollection;
import com.fxcore2.O2GTableType;

public class EventListener {
    private SimpleLog mSimpleLog;
    private ConcurrentLinkedQueue<O2GResponse> mResponseQueue;
    private O2GSession mSession;
    private EventPipe mEventPipe;

    public EventListener(SimpleLog simpleLog, ConcurrentLinkedQueue<O2GResponse> responseQueue, O2GSession session, EventPipe eventPipe) {
        mSimpleLog = simpleLog;
        mResponseQueue = responseQueue;
        mSession = session;
        mEventPipe = eventPipe;
    }

    public void waitNextEvent() {
        boolean bContinue = true;
        while (bContinue) {
            EventType eEventType = mEventPipe.waitEvent();
            if (eEventType == EventType.STATUS) {
                this.onStatusChanged();
            } else if (eEventType == EventType.CONNECTED) {
                this.onConnected();
            } else if (eEventType == EventType.RESPONSE) {
                this.onResponse();
            } else {
                // "How to login" : Logout when you are done.
                this.logout();
                bContinue = false;
            }
        }
    }

    private void onResponse() {
        while (true) {
            if (mResponseQueue.isEmpty())
                break;

            O2GResponse response = mResponseQueue.poll();
            if (response.getType() == O2GResponseType.MARKET_DATA_SNAPSHOT)
                onMarketDataSnaphsotRecieved(response);
        }
    }

    private void onConnected() {
        // Send history data.
        sendMarketDataSnapshot();
    }

    private void sendMarketDataSnapshot() {
        O2GRequestFactory factory = mSession.getRequestFactory();
        O2GTimeframeCollection timeFrames = factory.getTimeFrameCollection();
        O2GTimeframe timeFrame = timeFrames.get(Main.strTimeFrame);
        if (timeFrame == null)
        {
            mSimpleLog.log("Timeframe {0} does not exist", Main.strTimeFrame);
            return;
        }
        O2GRequest marketDataRequest = factory.createMarketDataSnapshotRequestInstrument(Main.strInstrument, timeFrame, Main.iMaxBars);
        if (marketDataRequest == null)
        {
            mSimpleLog.log("Cannot create request for market data snapshot, instrument: {0}; timeframe: {1}; max number of bars: {2}",
                       Main.strInstrument,  Main.strTimeFrame,  Main.iMaxBars );
            return;
        }
        factory.fillMarketDataSnapshotRequestTime(marketDataRequest, Main.calenFrom, Main.calenTo, false);
        mSession.sendRequest(marketDataRequest);
    }

    private void onMarketDataSnaphsotRecieved(O2GResponse response) {
        String strFrom = "now";
        if (Main.calenFrom != null)
        {
            strFrom = Main.calenFrom.getTime().toString();
        }
        String strTo = "now";
        if (Main.calenTo != null)
        {
            strTo = Main.calenTo.getTime().toString();
        }
        mSimpleLog.log("Market data snapshot for {0}, timeframe {1}, from {2}, to {3}, maximum Bars {4}", Main.strInstrument, Main.strTimeFrame, strFrom, strTo, Main.iMaxBars);
        O2GResponseReaderFactory factory = mSession.getResponseReaderFactory();
        O2GMarketDataSnapshotResponseReader marketSnapshotReader = factory.createMarketDataSnapshotReader(response);
        O2GTimeConverter converter = mSession.getTimeConverter();
        Calendar date;
        for (int i = 0; i < marketSnapshotReader.size(); i++) {
            date = marketSnapshotReader.getDate(i);
            date = converter.convert(date, O2GTimeConverterTimeZone.LOCAL);
            mSimpleLog.log("Date={0},BidOpen={1},BidHigh={2},BidLow={3},BidClose={4},AskOpen={5},AskHigh={6},AskLow={7},AskClose={8}", date.getTime(), marketSnapshotReader.getBidOpen(i), marketSnapshotReader.getBidHigh(i), marketSnapshotReader.getBidLow(i), marketSnapshotReader.getBidClose(i),
                    marketSnapshotReader.getAskOpen(i), marketSnapshotReader.getAskHigh(i), marketSnapshotReader.getAskLow(i), marketSnapshotReader.getAskClose(i));
        }
        mSimpleLog.log("Done!");
        mEventPipe.putEvent(EventType.TERMINATE);
        //Main.sc.next();
    }

    private void logout()
    {
        mSession.logout();
    }
    
    private void onStatusChanged() {
    }

}