local Rx = require 'Rx'

local Disposable = Rx.Disposable

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

local singleAssignmentDisposablePrototype = {

    Disposable,
        -- superclass

    _current = false,
        -- (Disposable) current item to dispose
}

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

function singleAssignmentDisposablePrototype:__init(disposable)

    if disposable and not Disposable:isClassOf(disposable) then
        error(string.format("Rx.SingleAssignmentDisposable: item (%s) is not a Disposable",
                tostring(disposable)), 3)
    end

    self._current = disposable

    return function()

        if self._current then
            local old = self._current
            self._current = nil
            old:dispose()
        end

    end

end

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

function singleAssignmentDisposablePrototype:getDisposable()

    return self._current

end

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

function singleAssignmentDisposablePrototype:setDisposable(disposable)

    if self._current then
        error('Rx.SingleAssignmentDisposable: Disposable has already been assigned', 2)
    end

    if disposable and not Disposable:isClassOf(disposable) then
        error(string.format("Rx.SingleAssignmentDisposable: item (%s) is not a Disposable",
              tostring(disposable)), 2)
    end

    if self:isDisposed() then

        if disposable then
            disposable:dispose()
        end

    else

        self._current = disposable

    end

end

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

return Rx.Class('Rx.SingleAssignmentDisposable', singleAssignmentDisposablePrototype)
