require "TimedActions/ISBaseTimedAction"

ISThrowBag = ISBaseTimedAction:derive("ISThrowBag");

function ISThrowBag:getDuration()
    if self.character:isTimedActionInstant() then
        return 1
    end

    return self.throwDuration
end

function ISThrowBag:isValid()
	print("ISThrowBag:isValid()")

	if not self.targetSquare then
        print("ISThrowBag:isValid() false - no target square")
        return false
    end

    if self.item or self.item2 then
        return true
    end
	print("ISThrowBag:isValid() false")
	return false;
end

function ISThrowBag:update()
	print("ISThrowBag:update() start")

	local delta = self:getJobDelta()

    print(
        "ISThrowBag:update",
        "delta=" .. tostring(delta),
        "maxTime=" .. tostring(self.maxTime),
        "duration=" .. tostring(self:getDuration()),
        "isClient=" .. tostring(isClient()),
        "isServer=" .. tostring(isServer())
    )

    if self.item then
        self.item:setJobDelta(delta)
    end

    if self.item2 then
        self.item2:setJobDelta(delta)
    end

    if delta >= 1 then
        print("ISThrowBag:update -> FORCE COMPLETE")

        if isServer() then
            if self.netAction then
                print("ISThrowBag:update -> netAction:forceComplete()")
                self.netAction:forceComplete()
            else
                print("ISThrowBag:update -> NO netAction")
            end
        else
            print("ISThrowBag:update -> self:forceComplete()")
            self:forceComplete()
        end
    end
	print("ISThrowBag:update() end")
end

function ISThrowBag:start()
	print("ISThrowBag:start() start")
	print(
        "ISThrowBag:start()",
        "client=" .. tostring(isClient()),
        "server=" .. tostring(isServer()),
        "netAction=" .. tostring(self.netAction),
        "maxTime=" .. tostring(self.maxTime),
        "duration=" .. tostring(self:getDuration())
    )

	-- On the client, resolve the authoritative/predicted inventory
    -- reference using the item's ID.
    if isClient() then
        if self.item then
            self.item = self.character:getInventory():getItemById(self.item:getID())
        end

        if self.item2 then
            self.item2 = self.character:getInventory():getItemById(self.item2:getID())
        end
    end

    if self.item and self.item2 then
        self.item:setJobType(
            getText("ContextMenu_Throw_Both")
                .. " "
                .. self.item:getName()
                .. " and "
                .. self.item2:getName()
        )

        self.item:setJobDelta(0.0)

    elseif self.item then
        self.item:setJobType(
            getText("ContextMenu_Throw_Primary")
                .. " "
                .. self.item:getName()
        )

        self.item:setJobDelta(0.0)

    elseif self.item2 then
        self.item2:setJobType(
            getText("ContextMenu_Throw_Secondary")
                .. " "
                .. self.item2:getName()
        )

        self.item2:setJobDelta(0.0)
    end

    self.started = true
	print("ISThrowBag:start() end")
end

function ISThrowBag:stop()
	print("ISThrowBag:stop() start")

	if self.item then
        self.item:setJobDelta(0.0)
    end

    if self.item2 then
        self.item2:setJobDelta(0.0)
    end

    self.started = false

    ISBaseTimedAction.stop(self)
	print("ISThrowBag:stop() end")
end

function ISThrowBag:perform()
	print("ISThrowBag:perform() start")

	print(
        "ISThrowBag:perform() START",
        "client=" .. tostring(isClient()),
        "server=" .. tostring(isServer()),
        "netAction=" .. tostring(self.netAction)
    )

	if self.item then
        self.item:setJobDelta(0.0)
    end

    if self.item2 then
        self.item2:setJobDelta(0.0)
    end

    -- Client-side presentation only.
    self.character:getEmitter():playSound("DropBag")

    ISInventoryPage.renderDirty = true

    ISBaseTimedAction.perform(self)
	
	print("ISThrowBag:perform() end")
end

function ISThrowBag:complete()
	print("ISThrowBag:complete() start")

	print("========== ISThrowBag COMPLETE ==========")
    print("server: " .. tostring(isServer()))
    print("targetSquare: " .. tostring(self.targetSquare))

    if self.item then
        print("item: " .. tostring(self.item))
        print("item full type: " .. tostring(self.item:getFullType()))
        print("item id: " .. tostring(self.item:getID()))
        print("item container: " .. tostring(self.item:getContainer()))
        print("inventory contains: " ..
            tostring(self.character:getInventory():contains(self.item)))
        print("world item: " .. tostring(self.item:getWorldItem()))
    else
        print("ITEM IS NIL")
    end

    if self.item2 then
        print("item2: " .. tostring(self.item2))
        print("item2 full type: " .. tostring(self.item2:getFullType()))
        print("item2 id: " .. tostring(self.item2:getID()))
        print("item2 container: " .. tostring(self.item2:getContainer()))
    else
        print("ITEM2 IS NIL")
    end

    print("==========================================")

    return true
end

-- 	if not self.targetSquare then
--         print("ISThrowBag:complete() ERROR: targetSquare is nil")
--         return false
--     end

--     local inventory = self.character:getInventory()

--     if self.item then
--         print("Throwing primary: " .. self.item:getFullType())
--         print("Item container: " .. tostring(self.item:getContainer()))

--         -- Make sure the item is no longer held.
--         self.character:removeFromHands(self.item)

--         -- Create the world item while we still have the valid
--         -- server-side InventoryItem.
--         local worldItem = self.targetSquare:AddWorldInventoryItem(
--             self.item,
--             0.0,
--             0.0,
--             0.0
--         )

--         print("AddWorldInventoryItem result: " .. tostring(worldItem))

--         if worldItem then
--             local isoWorldItem = worldItem:getWorldItem()

--             print("IsoWorldInventoryItem: " .. tostring(isoWorldItem))

--             if isoWorldItem then
--                 isoWorldItem:transmitCompleteItemToClients()
--             end
--         else
--             print("ERROR: AddWorldInventoryItem returned nil")
--             return false
--         end

--         -- Now remove it from the player's inventory.
--         if inventory:contains(self.item) then
--             inventory:Remove(self.item)
--             sendRemoveItemFromContainer(inventory, self.item)
--         end

--         self.item:setJobDelta(0.0)
--     end

--     if self.item2 then
--         print("Throwing secondary: " .. self.item2:getFullType())

--         self.character:removeFromHands(self.item2)

--         local worldItem = self.targetSquare:AddWorldInventoryItem(
--             self.item2,
--             0.0,
--             0.0,
--             0.0
--         )

--         print("AddWorldInventoryItem result: " .. tostring(worldItem))

--         if worldItem then
--             local isoWorldItem = worldItem:getWorldItem()

--             print("IsoWorldItem: " .. tostring(isoWorldItem))

--             if isoWorldItem then
--                 isoWorldItem:transmitCompleteItemToClients()
--             end
--         else
--             print("ERROR: AddWorldInventoryItem returned nil")
--             return false
--         end

--         if inventory:contains(self.item2) then
--             inventory:Remove(self.item2)
--             sendRemoveItemFromContainer(inventory, self.item2)
--         end

--         self.item2:setJobDelta(0.0)
--     end

--     ISInventoryPage.renderDirty = true

-- 	print("ISThrowBag:complete() end")
-- 	return true;
-- end

function ISThrowBag:new(character, targetSquare, item, item2)
	print("ISThrowBag:new() start")

	local o = ISBaseTimedAction.new(self, character)

    o.character = character
    o.targetSquare = targetSquare
    o.item = item
    o.item2 = item2

    o.stopOnWalk = false
    o.stopOnRun = false
    o.loopedAction = false
    o.started = false

    local distanceX = math.abs(
        targetSquare:getX() - character:getX()
    )

    local distanceY = math.abs(
        targetSquare:getY() - character:getY()
    )

    local duration = 5 * (distanceX + distanceY)

    if item then
        duration = duration + item:getContentsWeight() + 1
    end

    if item2 then
        duration = duration + item2:getContentsWeight() + 1
    end

    o.throwDuration = math.max(duration, 20)

    -- IMPORTANT for B42 NetTimedAction.
    o.maxTime = o:getDuration()

    print("ISThrowBag:new() throwDuration: " .. tostring(o.throwDuration))
    print("ISThrowBag:new() maxTime: " .. tostring(o.maxTime))
    print("ISThrowBag:new() end")

	print("ISThrowBag:new() end")
	return o
end
