"""The sample makes Point and Figure request and waits for response and updates for 20 sec"""

import logging
import threading

import win32com.client

import CELEnvironment

#region Settings

# Replace it with enabled symbol
SYMBOL = "DD"

# Events waiting time
TIMEOUT = 20

# Logging settings: specify log level and log format here.
# Set log level to DEBUG to see more internal messages.
# See more information about logging lib usage: https://docs.python.org/3/howto/logging-cookbook.html
CELEnvironment.LOG_LEVEL = logging.INFO
# CELEnvironment.LOG_FORMAT = ...

# CELEnvironment.SinkInternal uses own LOG_LEVEL (which is inherited from the global one) and own LOG_FORMAT.
# You can redefine them as follows:
# CELEnvironment.SinkInternal.LOG_LEVEL = logging.DEBUG
# CELEnvironment.SinkInternal.LOG_FORMAT = ...

LOG = CELEnvironment.GetLogger()

#endregion


class BarsRequestSample(CELEnvironment.CELSinkBase):
    def __init__(self):
        self.eventDone = threading.Event()

    def Init(self, celEnvironment):
        self.celEnvironment = celEnvironment

    def Start(self):
        request = win32com.client.Dispatch(self.celEnvironment.cqgCEL.CreatePointAndFigureBarsRequest())
        request.Symbol = SYMBOL
        request.RangeStart = 0
        request.RangeEnd = -10
        request.BoxSize = 3
        request.BoxUnits = win32com.client.constants.pfbuTicks
        request.Reversal = 3
        request.DataSource = win32com.client.constants.pfds1Min
        request.Continuation = win32com.client.constants.tsctStandard
        request.SubscriptionLevel = win32com.client.constants.tslEachTick
        request.UpdatesEnabled = True

        self.celEnvironment.cqgCEL.RequestPointAndFigureBars(request)

        self.eventDone.wait(TIMEOUT)

    def OnDataError(self, cqgError, errorDescription):
        if cqgError is not None:
            error = win32com.client.Dispatch(cqgError)
            LOG.error("OnDataError: Code: %d Description: %s", error.Code, error.Description)
        self.eventDone.set()

    def OnPointAndFigureBarsResolved(self, cqgPointAndFigureBars, cqgError):
        if cqgError is not None:
            error = win32com.client.Dispatch(cqgError)
            LOG.error("OnPointAndFigureBarsResolved: Code: %d Description: %s", error.Code, error.Description)
            self.eventDone.set()
        else:
            bars = win32com.client.Dispatch(cqgPointAndFigureBars)
            LOG.info("OnPointAndFigureBarsResolved: Bars count: %d Bars:", bars.Count)
            for i in range(0, bars.Count):
                self._dumpBar(win32com.client.Dispatch(bars.Item(i)), i)

    def OnPointAndFigureBarsAdded(self, cqgPointAndFigureBars):
        bars = win32com.client.Dispatch(cqgPointAndFigureBars)
        LOG.info("OnPointAndFigureBarsAdded: Bars count: %d Bars:", bars.Count)
        for i in range(0, bars.Count):
            self._dumpBar(win32com.client.Dispatch(bars.Item(i)), i)

    def OnPointAndFigureBarsUpdated(self, cqgPointAndFigureBars, index):
        LOG.info("OnPointAndFigureBarsUpdated: Updated bar index %d", index)
        bars = win32com.client.Dispatch(cqgPointAndFigureBars)
        self._dumpBar(win32com.client.Dispatch(bars.Item(index)), index)

    def _dumpBar(self, bar, index):
        LOG.info(
            "   Bar index: %d Timestamp %s PFHigh %f PFLow %f Up %f ",
            index,
            bar.Timestamp,
            bar.PFHigh,
            bar.PFLow,
            bar.Up
        )


if __name__ == "__main__":
    CELEnvironment.Start(BarsRequestSample)
