require "TimedActions/ISBaseTimedAction"

Fol_Take_A_Bath_Action = ISBaseTimedAction:derive("Fol_Take_A_Bath_Action");
local tub_part = ""
local tub
local posit_correct = 0.1
local Consume_water
local Object_water
local square
local WaterSprites
local player_X
local player_Y
local old_player_X
local old_player_Y
function Fol_Take_A_Bath_Action:isValid() 
    return true;
end

local i = 0
local number_Sprite = 0

local function setPlayerXY(player, _x, _y)
    player:setX(_x)
    player:setY(_y)
    player_X = player:getX()
    player_Y = player:getY()
end

function Fol_Take_A_Bath_Action:update()
    local tub_X = tub:getSquare():getX()
    local tub_Y = tub:getSquare():getY()
    if self.character:getBodyDamage():getColdStrength() > 0 then
        self.character:getBodyDamage():setColdStrength(self.character:getBodyDamage():getColdStrength() - 0.06);
    end


    if tub_part == "Part1" then
        if player_Y - posit_correct ~= tub_Y or player_X - posit_correct ~= tub_X then
            setPlayerXY(self.character, tub_X + posit_correct, tub_Y + posit_correct)
        end
    elseif tub_part == "Part2" then
        if player_Y + 1 - posit_correct ~= tub_Y or player_X - posit_correct ~= tub_X then
            setPlayerXY(self.character, tub_X + posit_correct, tub_Y - 1 + posit_correct)
        end
    elseif tub_part == "Part3" then
        if player_Y - posit_correct ~= tub_Y or player_X - posit_correct ~= tub_X then
            setPlayerXY(self.character, tub_X + posit_correct, tub_Y + posit_correct)
        end
    elseif tub_part == "Part4" then
        if player_Y - posit_correct ~= tub_Y or player_X + 1 - posit_correct ~= tub_X then
            setPlayerXY(self.character, tub_X - 1 + posit_correct, tub_Y + posit_correct)
        end
    elseif tub_part == "Part5" or tub_part == "Part6" or tub_part == "Part7" or tub_part == "Part8" then
        if player_X + 0.3 ~= tub_X ~= tub_Y or player_Y + 0.4 then
            setPlayerXY(self.character, tub_X + 0.3, tub_Y + 0.4)
        end

        if i < 4 then
            i = i + 1
        elseif i >= 4 then
            i = 0
            number_Sprite = number_Sprite + 1
        end
        if number_Sprite > 5 then
            number_Sprite = 1
        end
        Object_water:setSprite("fol_tub_" .. tub_part .. "_" .. tostring(number_Sprite))
    end

    self.character:getBodyDamage():setBoredomLevel(self.character:getBodyDamage():getBoredomLevel() - 0.02);
    self.character:getBodyDamage():setUnhappynessLevel(self.character:getBodyDamage():getUnhappynessLevel() - 0.02);
end

function Fol_Take_A_Bath_Action:waitToStart()
    local player_X, player_Y = self.character:getX(), self.character:getY()

    old_player_X = player_X
    old_player_Y = player_Y
    return self.character:shouldBeTurning()
end

function Fol_Take_A_Bath_Action:start()
    self.character:setPrimaryHandItem(nil)
    self:setOverrideHandModels(nil, nil)
    local tub_X = tub:getSquare():getX()
    local tub_Y = tub:getSquare():getY()
    local tub_Z = tub:getSquare():getZ()
    local player_Z = self.character:getZ()

    if tub_part == "Part5" or tub_part == "Part6" or tub_part == "Part7" or tub_part == "Part8" then
        setPlayerXY(self.character, tub_X, tub_Y)
        self.character:faceLocationF(old_player_X, old_player_Y)
        square = getCell():getGridSquare(player_X, player_Y, player_Z)
        WaterSprites = "fol_tub_Part5_1"
        self:setActionAnim("fol_Bath_2")
    end

    if square ~= nil and WaterSprites ~= nil then
        Object_water = IsoObject.new(square, WaterSprites)
        Object_water:setCustomColor(1, 1, 1, 1)
        square:AddTileObject(Object_water)
    end
    self.character:getBodyDamage():setWetness(100);
end

function Fol_Take_A_Bath_Action:stop()
    if square ~= nil and WaterSprites ~= nil then
        square:RemoveTileObject(Object_water);
        square = nil
    end
    setPlayerXY(self.character, old_player_X, old_player_Y)
    ISBaseTimedAction.stop(self);
end

function Fol_Take_A_Bath_Action:perform()
    local visual = self.character:getHumanVisual()

    if self.character:getBodyDamage():getColdStrength() < 1 then
        self.character:getBodyDamage():setHasACold(false);
    end
    for i = 1, BloodBodyPartType.MAX:index() do
        local part = BloodBodyPartType.FromIndex(i - 1)
        local Blood_Value
        visual:getBlood(part)
        local Dirt_Value = visual:getDirt(part)

        visual:setBlood(part, 0)
        visual:setDirt(part, 0)
        setPlayerXY(self.character, old_player_X, old_player_Y)
        if i >= BloodBodyPartType.MAX:index() then
            break
        end
    end

    local ModDate_consume_water = Fol_Take_A_Bath_Config.ModOptions.options.ModDate_consume_water
    if ModDate_consume_water then
        if tub:hasWater() then
            local waterAvailable = tub:getWaterAmount()
            tub:setWaterAmount(waterAvailable - Consume_water)
        end
    end

    self.character:getBodyDamage():decreaseBodyWetness(self.character:getBodyDamage():getWetness() / ZombRand(0, 20));
    self.character:getBodyDamage():setBoredomLevel(self.character:getBodyDamage():getBoredomLevel() - 0.1);
    self.character:getBodyDamage():setUnhappynessLevel(self.character:getBodyDamage():getUnhappynessLevel() - 0.1);
    self.character:getStats():setEndurance(self.character:getStats():getEndurance() + self.character:getStats():getEndurance() / ZombRand(0, 5))
    self.character:resetModelNextFrame();
    if square ~= nil and WaterSprites ~= nil then
        square:RemoveTileObject(Object_water);
        square = nil
    end
    ISBaseTimedAction.perform(self);
end

function Fol_Take_A_Bath_Action:new(character, _Object, _Part, consume_water)
    Consume_water = consume_water
    tub_part = _Part
    tub = _Object
    local o = {};
    setmetatable(o, self);
    self.__index = self;
    o.character = character;
    o.maxTime = 500;
    if o.character:isTimedActionInstant() then o.maxTime = 1; end
    return o;
end
