--[[
* The MIT License
* Copyright (C) 2014 Bacioiu "Zapa" Ciprian (bacioiu.ciprian@gmail.com).  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom th be Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--]]

building = {}

function building:_setupDataFromCsv( )
	building_data = { }
	local prePath = "Game/"

	if Game.modInUse ~= "" then
		prePath = "mods/"..Game.modInUse.."/"
	end
	building_data = loadCSVData(""..prePath.."data/building_data.csv")

	self._buildingTexture = { }

	self._usedState = {}

	self._idleState = {}

	self._hqTeam = {}

	self._capturedTeam = {}

	self._buildingData = { }

	self._captureAnimTown = { }

	self._captureAnimFactory = { }
	local stateSpeed = 0.2
	for i,v in pairs(building_data) do
		if type(v) == "table" then
			local tileSize = v.tileSize
			print("TEXTURE FILE: "..v.TextureFile.."")
			local name = "media/"..v.TextureFile..""
			self._buildingTexture[v.Type] = wanim:newDeck(name, tileSize, 1)

			if v.Type == 1 then
				local name1 = "media/"..v.CapturedAnimToPlayT1..""
				local name2 = "media/"..v.CapturedAnimToPlayT2..""
				self._captureAnimFactory[1] = wanim:newDeck(name1, v.tileSize, 6)
				self._captureAnimFactory[2] = wanim:newDeck(name2, v.tileSize, 6)
			elseif v.Type == 2 then
				local name1 = "media/"..v.CapturedAnimToPlayT1..""
				local name2 = "media/"..v.CapturedAnimToPlayT2..""
				self._captureAnimTown[1] = wanim:newDeck(name1, v.tileSize, 6)
				self._captureAnimTown[2] = wanim:newDeck(name2, v.tileSize, 6)
			end
			print("TYPE: "..v.Type.."")		
			for j, k in pairs(v) do


				if j == "T1_IDLE" then
					local valTab = parseDelimitedString(v.T1_IDLE, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._idleState[1] = stateName
					self._hqTeam[2] = stateName
				elseif j == "T2_IDLE" then
					local valTab = parseDelimitedString(v.T2_IDLE, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._idleState[2] = stateName
					self._hqTeam[3] = stateName
				elseif j == "NEUTRAL_IDLE" then
					local valTab = parseDelimitedString(v.NEUTRAL_IDLE, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._idleState[3] = stateName
					self._hqTeam[1] = stateName
				elseif j == "T1_CONQUERED" then
					local valTab = parseDelimitedString(v.T1_CONQUERED, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._capturedTeam[1] = stateName
				elseif j == "T2_CONQUERED" then
					local valTab = parseDelimitedString(v.T2_CONQUERED, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._capturedTeam[2] = stateName
				elseif j == "T1_USED" then
					local valTab = parseDelimitedString(v.T1_USED, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._usedState[1] = stateName
				elseif j == "T2_USED" then
					local valTab = parseDelimitedString(v.T2_USED, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._usedState[2] = stateName
				elseif j == "NEUTRAL_USED" then
					local valTab = parseDelimitedString(v.T1_USED, "-")
					local stateName = ""..string.upper(j)..""
					anim:createState(stateName, tonumber(valTab[1]), tonumber(valTab[2]), stateSpeed)
					self._usedState[3] = stateName
				end

			end
		end
	end

	print("Size of buildingTexture table: "..#self._buildingTexture.."")

end

function building:init(_mapFile, _isMulty)
	self:_setupDataFromCsv( )
	self._incomePlayers = { p1 = 0, p2 = 0 }

	self._incomGenAnimation = wanim:newDeck("media/incom_gen_anim.png", 64, 6)

	self._selectedBuilding = {}
	self._selectedColor = { r = 240, g = 15, b = 240, a = 1 }

	self._bldTexTable = {}
	self._bldTexTable[1] = self._bldTex
	self._bldTexTable[2] = self._bldTex2

	self._bldTable = {}

	self._hqTable = {}
	self._townTable = {}

	self._tileSize = 32
	self._offsetX = 0
	self._offsetY = 0
	
	self._hq = 1
	self._town = 2

	self._teamEdward = 0 
	self._teamOne = 1
	self._teamTwo = 2

	self._occupiedCounter = 0

	self._player = {}
	self._player[1] = player1
	self._player[2] = player2

	self._transparencyRegular = 1
	self._transparencyWhenOverlap = 0.55
	self._currentTransparency = self._transparencyRegular

	if _isMulty == nil then
		building:_addDebugBuildings(_mapFile)
	else
		building:_addDebugBuildings(_mapFile, _isMulty)
	end
end

function building:_addDebugBuildings(_mapFile, _isMulty)
	_NeutralHQ = 1073741825
	_PlayerHQ = 1073741826
	_EnemyHQ = 1073741827

	_NeutralTown = 1073741828
	_PlayerTown = 1073741829
	_EnemyTown = 1073741830

	local tb2 

	if _isMulty == nil then
		if _mapFile == "temp_test_map022701227" then 
			tb2 = table.load(pathToWrite.."player_map/".._mapFile..".mib")
		else
			interface:_setUpCategories( )
			local pathCat = interface:_returnPathCategory( )
			print("FRAKING PATH IS: "..pathCat.map.."/".._mapFile..".mib")

			tb2 = table.load(""..pathCat.map.."/".._mapFile..".mib")
		end
	else
			interface:_setUpCategories( )
			local pathCat = interface:_returnPathCategory( )

			tb2 = table.load("map/normal/".._mapFile..".mib")
	end

	for x = 1, #tb2 do
		for y = 1, #tb2[x] do
			local _tbValue = tb2[x][y]
			if _tbValue == _NeutralHQ then
				building:new(x, y, self._teamEdward, self._hq)
			elseif _tbValue == _PlayerHQ then
				building:new(x, y, self._teamOne, self._hq)
			elseif _tbValue == _EnemyHQ then
				building:new(x, y, self._teamTwo, self._hq)
			elseif _tbValue == _NeutralTown then
				building:new(x, y, self._teamEdward, self._town)
			elseif _tbValue == _PlayerTown then
				building:new(x, y, self._teamOne, self._town)
			elseif _tbValue == _EnemyTown then
				building:new(x, y, self._teamTwo, self._town)
			end
		end
	end

end

function building:_generateIncome(_turn)
	local counter = 0
	for i,v in ipairs(self._bldTable) do
		
		if v._type == 2 and v.canProduce == true then
			if unit:_returnTurn( ) == 1 and v.team == 2 then 
				player2.coins = player2.coins + v.gold + math.floor( (player2.incomeBonus / 100) )
				self._incomePlayers.p2 = self._incomePlayers.p2 + v.gold + math.floor( (player2.incomeBonus / 100) )
				local cash = weffect:new("MONEY", v.x, v.y-1, self._incomGenAnimation, 12)
				effect:setSpeed(cash, 0.07)
				counter = counter + 1
			elseif unit:_returnTurn( ) == 2 and v.team == 1 then
				player1.coins = player1.coins + v.gold + math.floor( (player1.incomeBonus / 100) )
				self._incomePlayers.p1 = v.gold + self._incomePlayers.p1 + math.floor( (player1.incomeBonus / 100) )
				local cash = weffect:new("MONEY", v.x, v.y-1, self._incomGenAnimation, 12 )
				effect:setSpeed(cash, 0.07)
				counter = counter + 1

			end
			v.canProduce = false

			if counter ~= 0 then
				if sound:isPlaying(sound.cash) == false then
					sound:play(sound.cash)
				end
			end
		end
	end
end

function building:_getLifetimeIncome( )
	return  self._incomePlayers
end

function building:new(_x, _y, _team, __type)
	local temp = {
		x = _x,
		y = _y,
		act_x = _x,
		act_y = _y,
		team = _team,
		_type =  __type, -- type 1 - HQ, type - 2 village
		canProduce = true,
		units = {}, -- going to get the unit list from else where
		gold = 15, -- produces 5 gold / turn,
		isSelected = false,
		occupied = false,
		transparency = 1,
	}

	--[[if temp._type == 1 then
		temp.img = anim:newAnim(self._hqNeutral, 8, _x*32, _y*32, 1) --image:newDeckImage(self._bldHqTex, _x*32, _y*32, _team+1) --image:newImage(self._bldTexTable[_team], _x*32, _y*32)
		--temp.roof = anim:newAnim(self._roof, 8, _x*32, _y*32, 1)
	else
		temp.img = anim:newAnim(self._bldTownTex, 4, _x*32, _y*32, _team+1) --image:newDeckImage(self._bldTownTex, _x*32, _y*32, _team+1)
		--temp.roof = anim:newAnim(self._roofTown, 8, _x*32, _y*32, _team+1)
		--anim:setState(temp.img, "BUILDING_TOWN_DIDLE")
	end--]]

	temp.img = anim:newAnim(self._buildingTexture [temp._type], 8, _x*32, _y*32, 1)
	--temp.roof = image:newDeckImage(self._roof, _x*32, _y*32, _team+1)
	anim:setState(temp.img, self._hqTeam[_team+1])
	--anim:setState(temp.roof, self._hqTeam[_team+1])
	--anim:setSpeed(temp.roof, math.random(0.6, 2))
	table.insert(self._bldTable, temp)
end

function building:_draw(i)
	local v = self._bldTable[i]

	v.act_x = v.x * self._tileSize - self._tileSize+self._offsetX - 8
	v.act_y = v.y * self._tileSize - self._tileSize+self._offsetY - 16

	--self:_adjustTransparency(i)

	if v.isSelected == true then
	--	image:setColor(v.img.img, self._selectedColor.r, self._selectedColor.g, self._selectedColor.b, self._selectedColor.a)
	--	image:setColor(v.roof.img, self._selectedColor.r, self._selectedColor.g, self._selectedColor.b, self._selectedColor.a)
	elseif v.canProduce == false and v._type == 1 then
		--image:setColor(v.img.img, 200, 200, 200, 1)
		local team = v.team
		anim:setState(v.img, self._usedState[team] )
		--image:setColor(v.roof.img, 200, 200, 200, v.transparency)
		--anim:setState(v.roof, self._usedState[team])
	elseif v.team ~= 0 then
		local team = v.team
		anim:setState(v.img, self._idleState[team] )
		--anim:setState(v.roof, self._idleState[team])
	end

	--image:updateImage(v.img, v.act_x, v.act_y)
	--if v.roof ~= nil then
		--image:updateImage(v.roof, v.act_x, v.act_y)
	--end
	anim:updateAnim(v.img, v.act_x, v.act_y)
	--anim:updateAnim(v.roof, v.act_x, v.act_y)
end

function building:_adjustTransparency(_id)
	local unitTable = unit:_returnTable( )
	local b = self._bldTable[_id]
	if b._type == self._hq then
		b.transparency = self._transparencyRegular
		for i,v in ipairs(unitTable) do
			if v.x == b.x and v.y == b.y-1 then
				b.transparency = self._transparencyWhenOverlap 

			end
		end
	end
end

function building:update( )
	self._offsetX, self._offsetY = map:returnOffset( )
	for i,v in ipairs(self._bldTable) do
		building:_draw(i)
	end
end

function building:_getAtPos(_x, _y)
	local _building = nil
	for i,v in ipairs(self._bldTable) do
		if v.x == _x and v.y == _y then
			_building = i
		end
	end
	return _building
end


function building:_addSelected(_id)
	local v = self._bldTable[_id]
	local selNum = self:_getNumSelections( )
	if v ~= nil then
		self:_clearSelected( )
		v.isSelected = true
		table.insert(self._selectedBuilding, _id)
	else
	--	print("BUILDING SELECTED IS NIL")
	end
end

function building:_getNumSelections( )
	return #self._selectedBuilding 
end

function building:_clearSelected( )
	local selNum = self:_getNumSelections( )
		if selNum > 0 then
		local v = self._bldTable[ self._selectedBuilding[1] ]
		v.isSelected = false
		table.remove(self._selectedBuilding, 1)
	end

	self._selectedBuilding = {}
end

function building:clearSelected( )
	--if unit:_getTouchState( ) == true then
	building:_clearSelected( )
	--end

end

function building:selectBuilding(_x, _y)
	
	if (unit:returnEventType( ) == true and unit:_getTouchState( ) == true) or Game.cursorEnabled == true then
		
		local _building = self:_getAtPos(_x, _y)
		local v = self._bldTable[_building]


			if v ~= nil and v.team == unit:_returnTurn( )  and v.canProduce and v._type == 1 then
				self:_addSelected(_building)
				--g:injectMouseMove(0, 0)
				interface:setBuyMenu(true, v)
				interface:_populate_buyMenu_unitsList( )
				--------------------------------
				--------------------------------
				---- SOUND HERE ----------------
				--sound:play(sound.menuSwipe)

				sound:play(sound.factorySel)
				---- SOUND HERE ----------------
				--------------------------------
				--------------------------------
				--building:createNewUnit(v)
			else
				interface:setBuyMenu(false)
			end
		unit:setEventType(false)

		return _building
	end

end

function building:createNewUnit(_building, _turn, _dp)
    local v = _building
    if v._type == 1 then
        if v.canProduce == true then

            local _unitType

            _unitType = _dp

            if _unitType ~= nil then
                local turn = unit:_returnTurn()

                local faction = self._player[_turn].team
                print("STEP ONE !!!!11111!!11!!")
                print("TURN IS: "..turn.."")

                --[[if _turn == 2 then
                	if faction == 1 then
                		faction = 2
                	elseif faction == 2 then
                		faction = 1
                	end
                end--]]
                print("FACTION IS: "..faction.."")
                print("COST SHOULD BE: "..unit_type[faction][_unitType].cost.."")
                if self._player[_turn].coins >= unit_type[faction][_unitType].cost then
                	print("STep 2222 2222")
                --------------------------------
                --------------------------------
                ---- SOUND HERE ----------------
                sound:play(sound.factoryProd)
                ---- SOUND HERE ----------------
                --------------------------------
                --------------------------------
                    unit:new(v.team, v.x, v.y, _unitType)

                    v.canProduce = false
                    self._player[_turn].coins = self._player[_turn].coins - unit_type[faction][_unitType].cost
                end
            end
        end
    end
end

function building:createUnits(_turn, _dp)
	local counter = 0
	for i,v in ipairs(self._bldTable) do
		if v.team == _turn and v._type == 1 and v.canProduce == true then
			if unit:isLocEmpty(v.x, v.y) == nil then --self:_checkIfHQSlotOccupied(v.x, v.y) == 0 then
				counter = counter + 1
				building:createNewUnit(v, _turn, _dp[counter])
			end
		end
	end
end

function building:_createUnits(_temple, _turn, _type)
	--local counter = 0
	--for i,v in ipairs(self._bldTable) do
		local v = _temple
		if v.team == _turn and v._type == 1 and v.canProduce == true then
			if unit:isLocEmpty(v.x, v.y) == nil then --self:_checkIfHQSlotOccupied(v.x, v.y) == 0 then
				--counter = counter + 1
				building:createNewUnit(v, _turn, _type)
			end
		end
	--end
end

function building:_checkIfHQSlotOccupied(_x, _y)
	local unitList = unit:_returnTable( )
	for i,v in ipairs(unitList) do
		if v.x == _x and v.y == _y then
			self._occupiedCounter = self._occupiedCounter + 1
		end
	end

	return self._occupiedCounter
end

function building:_isFactoryOccupied(_id)
	local unitList = unit:_returnTable( )
	local bld = self._bldTable[_id]
	local bool = false

	for i,v in ipairs(unitList) do
		if v.x == bld.x and v.y == bld.y then
			bool = true
		end
	end

	return bool
end

function building:_resetStats()
	for i,v in ipairs(self._bldTable) do
		v.canProduce = true
		
		self._occupiedCounter = 0
		building:_setCaptured(i)
	end
	--building:_generateIncome( )
end

function building:_getListOfOpposingHq( )
	for i,v in ipairs(self._bldTable) do
		if v.team ~= unit:_returnTurn( ) and v._type == 1 and v.occupied == false then
			table.insert(self._hqTable, v)
		end
	end

	return self._hqTable
end


function building:_getListOfTowns( )
	for i,v in ipairs(self._bldTable) do
		if v.team ~= unit:_returnTurn( ) and v._type == 2 and v.occupied == false then
			table.insert(self._townTable, v)
		end
	end

	return self._townTable
end

function building:_dropTownsAndHqTables( )
	self._townTable = {}
	self._hqTable = {}
end

function building:_dropAll( )
	for i,v in ipairs(self._bldTable) do
		image:removeProp(v.img, 1)
	end

	self._bldTable = {}
end

function building:_returnBuildingTable( )
	return self._bldTable
end

function building:_returnRandomEnemyHq( )
	local bList = {}
	for i,v in ipairs(self._bldTable) do
		if v.team ~= unit:_returnTurn( ) then
			if v._type == 1 then
				table.insert(bList, v)
			end
		end
	end

	local sz = #bList
	local rnd = 1
	if sz >= 1 then
		rnd = math.random(1, sz)
	else
		rnd = 1
	end

	return bList[rnd]
end

function building:setVictory(_player)
	for i,v in ipairs(self._bldTable) do
		v.team = _player
	end
end