Item = class("Item")

function Item:new(def, level, index)
	local item = instance(self)
	item.index = index
	item.def = def	
	item.level = level
	item:refresh_display_name()
	item.sprite = SPRITES["resource_19"]
	item.outline = SPRITES["resource_outline_19"]
	return item
end

function Item:refresh_display_name()
	local name = self.name or self.index
	local stack = self.stack
	if stack then
		name = stack.." "..name
	end
	self.display_name = name
end

function Item:is_stackable_with(item)	
	return item.index == self.index
end

function Item:set_rarity(rarity)
	self.rarity = rarity
	local rdef = RARITY_DEFS[rarity]
	self.display_rarity = rdef.name
end

function Item:set_stackable(v)
	self.stackable = v	
end

function Item:set_display_name(name)
	self.name = name
	self:refresh_display_name()
end

function Item:set_stack(stack)
	self.stack = stack
	self:refresh_display_name()
end

function Item:set_stats(stats)
	self.stats = stats	
end

function Item:get_stats()
	return self.stats
end

function Item:has_stack()
	return self.stack ~= nil
end

function Item:adjust_stack(stack)
	self:set_stack(self.stack + stack)
end

function Item:get_stack()
	return self.stack
end

function Item:set_name_color(color)
	self.name_color = color
end

function Item:get_slot_type()
	return self.def.item_slot
end

function Item:get_power_stat()
	return self.def.power_stat
end

function Item:get_attack_type()
	return self.def.attack_type
end

function Item:set_price(p)
	self.price = p
end

function Item:get_price()
	if self.price then
		return self.price*(self.stack or 1)
	end
end

function Item:get_display_slot()
	local item_slot = self:get_slot_type()
	local def = assert(ITEM_SLOTS[item_slot],item_slot)
	return def.name
end

function Item:get_display_rarity()
	return self.display_rarity
end

function Item:set_effect(eff)
	self.effect = eff
end

function Item:get_effect()
	return self.effect
end

function Item:get_core_name()
	return self.def.name
end

function Item:get_display_name()
	return self.display_name
end

function Item:get_name_display_color()
	return self.name_color
end

function Item:should_pickup_automatically()
	return self.def.auto_pickup
end

function Item:set_sprites(sprite, outline)
	self.sprite = sprite
	self.outline = outline
	if sprite <= 0 then
		debug.ptb()
	end
end

function Item:set_projectile_sprites(sprite, outline)
	self.projectile_sprite = sprite
	self.projectile_outline = outline
end

function Item:get_projectile_sprites()
	return self.projectile_sprite, self.projectile_outline
end

function Item:get_sprites()
	return self.sprite, self.outline	
end

function Item:get_tints(tint)
	return self.tint, self.outline_tint
end

function Item:set_tints(tint, outline_tint)
	self.tint = tint
	self.outline_tint = outline_tint	
end

function Item:render(x,y,scale,perspective,angle,a,r,g,b)
	local tint = self.tint or TINTS.white
	video.renderSpriteState(self.outline, x, y, scale, angle, a, 0, 0, 0)
	video.renderSpriteState(self.sprite, x, y, scale, angle, a, r*tint.r, g*tint.g, b*tint.b)
	
end

local DIFF_STRINGS = {
	{color = COLORS.diff1, name = "Epic Improvement", threshold = 5},
	{color = COLORS.diff2, name = "Great Improvement", threshold = 1},
	{color = COLORS.diff3, name = "Small Improvement", threshold = 0},
	{color = COLORS.diff4, name = "Slightly worse", threshold = -1},
	{color = COLORS.diff5, name = "Greatly worse", threshold = -5},
	{color = COLORS.diff6, name = "Unquestionably worse"},
}

local ITEM_INFO_KEYS = {
	name = function(self, tdef, hud_info)
		local name = self:get_display_name()
		if name then
			hud_info:set_key("name", name)
		end
	end,
	improvement = function(self, tdef, hud_info, compare)
		local stats = self.stats
		if stats then
			local same = true
			local total_diff = 0
			if compare and compare:get_stats() then
				local compare_stats = compare:get_stats()
				for index, value in pairs(stats) do
					total_diff = total_diff + ((value or 0)-(compare_stats[index] or 0))
				end
				if total_diff > 0 then
					for index, diff in ipairs(DIFF_STRINGS) do
						if not diff.threshold or total_diff > diff.threshold then
							local note = hud_info:set_key("note", diff.name)
							note.color = diff.color
							break
						end
					end
				end
			end
		end
	end,
	rarity = function(self, tdef, hud_info)
		local rarity = self:get_display_rarity()
		if rarity then
			hud_info:set_key("rarity", rarity)
		end
	end,
	slot = function(self, tdef, hud_info)
		local slot = self:get_display_slot()
		if slot then
			hud_info:set_key("slot", slot)
		end
	end,
	stats = function(self, tdef, hud_info, compare)
		local stats = self.stats
		if stats then
			local same = true
			local total_diff = 0
			local stats_key = tdef.stats_type or "stats"
			--print(stats_key)
			if compare and compare:get_stats() then
				local compare_stats = compare:get_stats()
				for index, value in pairs(stats) do
					if compare[index] ~= value then
						same = false
					end
				end
				for index, value in pairs(compare_stats) do
					if stats[index] ~= value then
						same = false
					end
				end
				for index, value in pairs(stats) do
					total_diff = total_diff + ((value or 0)-(compare_stats[index] or 0))
				end
				hud_info:set_key(stats_key, stats, compare_stats)
				if same then
					hud_info:set_key("note", "Identical")
				else
					for index, diff in ipairs(DIFF_STRINGS) do
						if not diff.threshold or total_diff > diff.threshold then
							local note = hud_info:set_key("note", diff.name)
							note.color = diff.color
							break
						end
					end
				end
			else
				hud_info:set_key(stats_key, stats)
			end
		end
	end,
	price = function(self, tdef, hud_info)
		local price = self:get_price()
		if price then
			hud_info:set_key("price", "Pay Gold:"..price)
		else
			hud_info:set_key("price", "FREE!")
		end
	end,
	color = function(self, tdef, hud_info)
		hud_info:set_color(self:get_name_display_color())
	end
}

local ITEM_INFO_TEMPLATES = {
	buy = {
		list = {
			"name",
			"rarity",
			"slot",
			"stats",
			"price",
			"color",
		},
		font_override = "medium",
	},
	compare = {
		list = {
			"name",
			"rarity",
			"slot",
			"stats",
			"color",
		},
	},
	info = {
		list = {
			"name",
			"rarity",
			"slot",
			"stats",
			"color",
		},
	},
	big_info = {
		list = {
			"name",
			"rarity",
			"slot",
			"stats",
			"color",
		},
		font_override = "medium",
	},
	name = {
		list = {
			"name",
			"improvement",
			"color",
		},
	}
}



function Item:apply_hud_template(hud_info, template, compare)	
	local tdef = ITEM_INFO_TEMPLATES[template]
	if tdef.font_override then
		hud_info.font = tdef.font_override
	end
	for index, value in ipairs(tdef.list) do
		local handler = ITEM_INFO_KEYS[value]
		handler(self, tdef, hud_info, compare)
	end

	return hud_info
end


function Item:get_hud(template, compare)
	local huds = self.huds
	if not huds then
		huds = {}
		self.huds = huds
	end

	local hud_info = huds[template]
	if not hud_info or hud_info.compared_to ~= compare then
		hud_info = HudInfo:new()
		hud_info.compare_to = compare

		self:apply_hud_template(hud_info, template, compare)		
		huds[template] = hud_info
	end

	return hud_info
end
