local Rx = require 'Rx'

local sItemCount = 0

--------------------------------------------------------------------------------

local scheduledItemPrototype = {

    _scheduler = false,
    _state = false,
    _action = false,
    _dueTime = false,
    _tieBreaker = false,
    _disposable = false,

}

--------------------------------------------------------------------------------

function scheduledItemPrototype:__init(scheduler, state, action, dueTime, comparer)

    self._scheduler = scheduler
    self._state = state
    self._action = action
    self._dueTime = dueTime
    self._disposable = Rx.SingleAssignmentDisposable()
    sItemCount = sItemCount + 1
    self._tieBreaker = sItemCount

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:invoke()

    local success, disposableOrError = pcall(self.invokeCore, self)
    if success and disposableOrError then
        self._disposable:setDisposable(disposableOrError)
    else
        self._disposable:dispose()
    end

    if not success then
        error(disposableOrError)
    end

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:__eq(other)

    return false

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:__le(other)

    return self < other

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:__lt(other)

    return self._dueTime < other._dueTime
        or (self._dueTime == other._dueTime
            and self._tieBreaker < other._tieBreaker)

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:isCancelled()

    return self._disposable:isDisposed()

end

--------------------------------------------------------------------------------

function scheduledItemPrototype:invokeCore()

    return self._action(self._scheduler, self._state)
        -- RxLua intentionally doesn't run disposable._fixup on the result as
        -- a performance optimization, see invoke() above.

end

--------------------------------------------------------------------------------

return Rx.Class('Rx.internals.ScheduledItem', scheduledItemPrototype)
