require "BuildingObjects/ISBuildingObject"

HCBarricade = ISBuildingObject:derive("HCBarricade");
HCBarricade.barricades = {};

function HCBarricade:create(x, y, z, north, sprite)
	local cell = getWorld():getCell();
	self.sq = cell:getGridSquare(x, y, z);
	self:setInfo(self.sq, north, sprite, "Barricade", self);
	
	local spriteAName = self.northSprite2;
	local xa = x;
	local ya = y;
	if north then
		ya = ya - 1;
	else
		spriteAName = self.sprite2;
		xa = xa - 1;
	end
	local squareA = getCell():getGridSquare(xa, ya, z);
	
	if squareA == nil then
		squareA = IsoGridSquare.new(getCekk(), nil, xa, xy, z);
		getCell():ConnectNewSquare(squareA, false);
	end
	
	self:setInfo(squareA, north, spriteAName, "Barricade2", self);
	
	if self.sq:getZone() then
		self.sq:getZone():setHaveConstruction(true);
	end
	if self.item == 0 then
		ISTimedActionQueue.add(ISAddBarricadeAction:new(self.character, sq, self.character:getInventory():FindAndReturn("HCLogbarrier"), sprite, 0));
	end
end

function HCBarricade:setInfo(square, north, sprite, name)
	local thumpable = IsoThumpable.new(square:getCell(), square, sprite, north, self);
	buildUtil.setInfo(thumpable, self);
	thumpable:setName(name);
	thumpable:setCanBarricade(false);
	thumpable:setIsDismantable(false);
	thumpable:setMaxHealth(600);
	thumpable:setBreakSound("breakdoor");
	thumpable:getSprite():getProperties():Set(IsoFlagType.collideN);
	thumpable:getSprite():getProperties():Set(IsoFlagType.collideW);
	thumpable:getSprite():getProperties():Set(IsoFlagType.trans);
	square:AddSpecialObject(thumpable);
	thumpable:setModData(copyTable(self.modData));
	thumpable:transmitCompleteItemToServer();
end

function HCBarricade.onDestroy(thump, character)
	self:removeFromGround(thump:getSquare(), thump:getName(), thump:getNorth());
	--1-3 log 1-2 rope
	local result = ZombRand(3);
	if result == 0 then
		thump:getSquare():AddWorldInventoryItem("Base.Log");
	elseif result == 1 then
		thump:getSquare():AddWorldInventoryItem("Base.Log");
		thump:getSquare():AddWorldInventoryItem("Base.Log");
	elseif result == 2 then
		thump:getSquare():AddWorldInventoryItem("Base.Log");
		thump:getSquare():AddWorldInventoryItem("Base.Log");
		thump:getSquare():AddWorldInventoryItem("Base.Log");
	end
	result = ZombRand(2);
	if result == 0 then
		thump:getSquare():AddWorldInventoryItem("Base.Rope");
	elseif result == 1 then
		thump:getSquare():AddWorldInventoryItem("Base.Rope");
		thump:getSquare():AddWorldInventoryItem("Base.Rope");
	end
end

function HCBarricade:removeFromGround(square, name, north)
	for i=0, square:getSpecialObjects():size() do
		local thump = square:getSpecialObjects():get(i);
		if instanceof(thump, "IsoThumpable") then
			name = thump:getName();
			square:getSquare():RemoveTileObject(thump);
			square:transmitRemoveItemFromSquare(thump);
			square:getSpecialObjects():remove(thump);
			square:getObjects():remove(thump);
		end
	end
	
	local xa = square:getX();
	local ya = square:getY();
	if name == "Barricade" then
		if north() then
			ya = ya - 1;
		else
			xa = xa - 1;
		end
	else
		if north() then
			ya = ya + 1;
		else
			xa = xa + 1;
		end
	end
	
	square = getCell():getGridSquare(xa, ya, square:getZ());
	for i=0, square:getSpecialObjects():size() do
		local thump = square:getSpecialObjects():get(i);
		if instanceof(thump, "IsoThumpable") then
			square:getSquare():RemoveTileObject(thump);
			square:transmitRemoveItemFromSquare(thump);
			square:getSpecialObjects():remove(thump);
			square:getObjects():remove(thump);
		end
	end
end

function HCBarricade:new(character, item)
	local o = {};
	setmetatable(o, self);
	self.__index = self;
	o:init();
	o:setSprite("media/textures/Object_HCSpikedbarricadeEF.png");
	o:setNorthSprite("media/textures/Object_HCSpikedbarricadeNF.png");
	o.sprite2 = "media/textures/Object_HCSpikedbarricadeEB.png";
	o.northSprite2 = "media/textures/Object_HCSpikedbarricadeNB.png";
	o.name = "Barricade";
	o.canBarricade = false;
	o.dismantable = false;
	o.blockAllTheSquare = true;
	o.canBeAlwaysPlaced = false;
	o.noNeedHammer = true;
	o.character = character;
	o.item = item;
	return o;
end

function HCBarricade:render(x, y, z, square)
	ISBuildingObject.render(self, x, y, z, square);
	
	local spriteAName = self.northSprite2;
	local spriteAFree = true;
	
	local xa, ya, za = self:getSquare2Pos(square, self.north);
	if not self.north then
		spriteAName = self.sprite2;
	end
	local squareA = getCell():getGridSquare(xa, ya, za);
	
--[[	if not SquareA or not self.isValid(squareA) then
		spriteAFree = false;
	end
	]]--
	local spriteA = IsoSprite.new();
	spriteA:LoadFramesNoDirPageSimple(spriteAName);
	
	if self:isValid(square) then
		spriteA:RenderGhostTile(xa, ya, za);
	else
		spriteA:RenderGhostTileRed(xa, ya, za);
	end
end

function HCBarricade:isValid(square)
	local valid = self:isSquareFree(square);
	if valid and not self.character:getInventory():contains("HCLogbarrier") then
		valid = false;
	end	
	local x, y, z = self:getSquare2Pos(square, self.north);
	local square2 = getCell():getGridSquare(x, y, z);
	if valid and not (square2 and self:isSquareFree(square2) and not square:isSomethingTo(square2)) then
		valid = false;
	end
	return valid;
end

function HCBarricade:isSquareFree(square)
	if not square or not buildUtil.canBePlace(self, square) then return false end
	if square:getMovingObjects():size() > 0 then return false end
	if square:getStaticMovingObjects():size() > 0 then return false end
	for i=0, square:getObjects():size()-1 do
		local object = square:getObjects():get(i);
		if object:getSprite() and not object:getSprite():getProperties():Is(IsoFlagType.solidfloor) then
			if object:getType() == IsoObjectType.tree or object:getType() == IsoObjectType.wall then
				return false;
			end
			return not square:isSolidTrans();
		end
	end
	return true;
end

function HCBarricade:getSquare2Pos(square, north)
	local x = square:getX();
	local y = square:getY();
	local z = square:getZ();
	if north then
		y = y - 1;
	else
		x = x - 1;
	end
	return x, y, z;
end

function HCBarricade.isBarricade(obj)
	return obj ~= nil and obj:getName() == "Barricade" or obj:getName() == "Barricade2"
end

function HCBarricade.LoadGridsquare(square)
	if isClient() then return end
	for i=0,square:getSpecialObjects():size()-1 do
		local obj = square:getSpecialObjects():get(i);
		if HCBarricade.isBarricade(obj) then
			HCBarricade.loadBarricade(obj);
			break;
		end
	end
end

function HCBarricade.loadGridSquareJavaHook(sq, obj)
	if isClient() then return end
	HCBarricade.loadBarricade(obj);
end

function HCBarricade.loadBarricade(bc)
	if not bc or not bc:getSquare() then return end
	local square = bc:getSquare();
	local barricade = nil;
	for i,v in ipairs(HCBarricade.barricades) do
		if v.x == square:getX() and v.y == square:getY() and v.z == square:getZ() then
			barricade = v;
			break;
		end
	end
	if not barricade then
		barricade = {};
		barricade.x = square:getX();
		barricade.y = square:getY();
		barricade.z = square:getZ();
		table.insert(HCBarricade.barricades, barricade);
	end
	if bc:getNorth() then
		bc:setSprite("media/textures/Object_HCSpikedbarricadeNF.png");
		if bc:getName() == "Barricade2" then
			bc:setSprite("media/textures/Object_HCSpikedbarricadeNB.png")
		end
	else
		bc:setSprite("media/textures/Object_HCSpikedbarricadeEF.png");
		if bc:getName() == "Barricade2" then
			bc:setSprite("media/textures/Object_HCSpikedbarricadeEB.png")
		end
	end
	bc:getSprite():getProperties():Set(IsoFlagType.collideN);
	bc:getSprite():getProperties():Set(IsoFlagType.collideW);
	bc:getSprite():getProperties():Set(IsoFlagType.trans);
	bc:transmitUpdatedSpriteToClients();
end

function HCBarricade.OnObjectAdded(obj)
	if isClient() then return end
	if HCBarricade.isBarricade(obj) then
		HCBarricade.loadBarricade(obj);
	end
end

Events.LoadGridsquare.Add(HCBarricade.LoadGridsquare);
Events.OnObjectAdded.Add(HCBarricade.OnObjectAdded);
Events.OnDestroyIsoThumpable.Add(HCBarricade.onDestroy);