local bs = AceLibrary("Babble-Spell-2.2")
--local AceAddon = AceLibrary("AceAddon-2.0")
local Tablet = AceLibrary("Tablet-2.0")
local BO = AceLibrary("Babble-Ore-2.2")
local Talismonger = AceLibrary("Talismonger-3.0")

local L = AceLibrary("AceLocale-2.2"):new("Cartographer_Mining")
L:RegisterTranslations("enUS", function() return {
	["Filter"] = true,
	["Filter out minerals"] = true,
	["Module description"] = "Mining mapnotes for Cartographer (based on PinPoint by Ammo)",
	["Select all"] = true,
	["Select none"] = true,
	["Icon alpha"] = true,
	["Alpha transparency of the icon"] = true,
	["Icon size"] = true,
	["Size of the icons on the map"] = true,
	["Show minimap icons"] = true,
	["Show mining icons on the minimap"] = true,

	["ALT_NAMES"] = true,
} end)

L:RegisterTranslations("deDE", function() return {
	["Filter"] = "Filter",
	["Filter out minerals"] = "Filtere Mineralien",
	["Module description"] = "Bergbau-Kartennotizen f\195\188r Cartographer (basierend auf PinPoint von Ammo)",
	["Select all"] = "Alle ausw\195\164hlen",
	["Select none"] = "Nichts ausw\195\164hlen",
	["Icon alpha"] = "Transparenz",
	["Alpha transparency of the icon"] = "Transparenz der Symbole.",
	["Icon size"] = "Symbolgr\195\182\195\159e",
	["Size of the icons on the map"] = "Gr\195\182\195\159e der Symbole auf der Weltkarte.",
	["Show minimap icons"] = "Minimap-Symbole anzeigen",
	["Show mining icons on the minimap"] = "Erzsymbole auf der Minimap anzeigen.",
} end)

L:RegisterTranslations("frFR", function() return {
	["Filter"] = "Filtrer",
	["Filter out minerals"] = "Filtrer les minerais",
	["Module description"] = "Notes de minage pour Cartographer (bas\195\169 sur PinPoint par Ammo)",
	["Select all"] = "Tout s\195\169lectionner",
	["Select none"] = "Ne rien s\195\169lectionner",
	["Icon alpha"] = "Transparence des ic\195\180nes",
	["Alpha transparency of the icon"] = "D\195\169termine la transparence des ic\195\180nes.",
	["Icon size"] = "Taille des ic\195\180nes",
	["Size of the icons on the map"] = "D\195\169termine la taille des ic\195\180nes sur la carte.",
	["Show minimap icons"] = "Afficher les ic\195\180nes sur la minicarte",
	["Show mining icons on the minimap"] = "Affiche les ic\195\180nes des mines sur la minicarte.",
} end)

L:RegisterTranslations("esES", function() return {
	["Filter"] = "Filtro",
	["Filter out minerals"] = "Filtrar minerales",
	["Module description"] = "Notas de mapa de Miner\195\173a para Cartographer (basado en PinPoint por Ammo)",
	["Select all"] = "Seleccionar todo",
	["Select none"] = "No seleccionar nada",
	["Icon alpha"] = "Transparencia de icono",
	["Alpha transparency of the icon"] = "Transparencia de los iconos",
	["Icon size"] = "Tama\195\177o de icono",
	["Size of the icons on the map"] = "Tama\195\177o de los iconos en el mapa",
	["Show minimap icons"] = "Mostrar iconos en minimapa",
	["Show mining icons on the minimap"] = "Muestra los iconos de miner\195\173a en el minimapa",
} end)

L:RegisterTranslations("koKR", function() return {
	["Filter"] = "항목 분류",
	["Filter out minerals"] = "채광(광맥)을 항목에 따라 분류하여 표시합니다.",
	["Module description"] = "맵노트에 채광(광맥)을 표시합니다.",
	["Select all"] = "모두 선택",
	["Select none"] = "선택 해제",
	["Icon alpha"] = "아이콘 투명도",
	["Alpha transparency of the icon"] = "아이콘의 투명도를 조절합니다.",
	["Icon size"] = "아이콘 크기",
	["Size of the icons on the map"] = "아이콘의 크기를 조절합니다.",
	["Show minimap icons"] = "미니맵 아이콘 보기",
	["Show mining icons on the minimap"] = "미니맵에 광맥 아이콘을 표시합니다.",
} end)

L:RegisterTranslations("zhTW", function() return {
	["Filter"] = "過濾",
	["Filter out minerals"] = "過濾礦石",
	["Module description"] = "Cartographer 模組，紀錄礦點位置 (靈感來自 Ammo 的 PinPoint)。",
	["Select all"] = "全部選取",
	["Select none"] = "全部取消",
	["Icon alpha"] = "圖示透明度",
	["Alpha transparency of the icon"] = "地圖上的圖示透明度",
	["Icon size"] = "圖示大小",
	["Size of the icons on the map"] = "地圖上的圖示大小",
	["Show minimap icons"] = "在小地圖上顯示",
	["Show mining icons on the minimap"] = "將礦點圖示顯示於小地圖上",

	["ALT_NAMES"] = {
		["鐵礦石"] = "Iron Deposit",
		["金礦石"] = "Gold Vein",
		["真銀礦石"] = "Truesilver Deposit",
	},
} end)

L:RegisterTranslations("zhCN", function() return {
--***************************************
-- zhCN Chinese Simplify
-- 2007/07/14 CN3羽月 雪夜之狼
-- E-Mail:xionglingfeng@Gmail.com
--***************************************
	["Filter"] = "过滤",
	["Filter out minerals"] = "过滤矿石",
	["Module description"] = "Cartographer 模块，记录点位置 (灵感来自 Ammo 的 PinPoint)。",
	["Select all"] = "全部选取",
	["Select none"] = "全部取消",
	["Icon alpha"] = "图标透明度",
	["Alpha transparency of the icon"] = "地图上的图标透明度",
	["Icon size"] = "图标大小",
	["Size of the icons on the map"] = "地图上的图标大小",
	["Show minimap icons"] = "在小地图上显示",
	["Show mining icons on the minimap"] = "将矿点图示显示在小地图上",
} end)

-- altername names to fix not 1-to-1 mapping localization issue 
local ALT_NAMES = type(L["ALT_NAMES"]) == "table" and L["ALT_NAMES"] or nil;

local mod = Cartographer:NewModule("Mining", "AceConsole-2.0", "AceEvent-2.0")
local icon_path = "Interface\\AddOns\\Cartographer_Mining\\Artwork\\"
local icon_list = {
	["Copper Vein"] = "INV_Ore_Copper_01",
	["Tin Vein"] = "INV_Ore_Tin_01",
	["Iron Deposit"] = "INV_Ore_Iron_01",
	["Silver Vein"] = "INV_Stone_16",
	["Ooze Covered Silver Vein"] = "INV_Stone_16",
	["Gold Vein"] = "INV_Ore_Gold_01",
	["Ooze Covered Gold Vein"] = "INV_Ore_Gold_01",
	["Mithril Deposit"] = "INV_Ore_Mithril_02",
	["Ooze Covered Mithril Deposit"] = "INV_Ore_Mithril_02",
	["Truesilver Deposit"] = "INV_Ore_TrueSilver_01",
	["Ooze Covered Truesilver Deposit"] = "INV_Ore_TrueSilver_01",
	["Small Thorium Vein"] = "INV_Ore_Thorium_02",
	["Ooze Covered Thorium Vein"] = "INV_Ore_Thorium_02",
	["Hakkari Thorium Vein"] = "INV_Ore_RichThorium_01",
	["Rich Thorium Vein"] = "INV_Ore_RichThorium_01",
	["Ooze Covered Rich Thorium Vein"] = "INV_Ore_RichThorium_01",
	["Dark Iron Deposit"] = "INV_Ore_Mithril_01",
	["Indurium Mineral Vein"] = "INV_Ore_Mithril_01",
	["Lesser Bloodstone Deposit"] = "INV_Ore_Thorium_01",
	["Incendicite Mineral Vein"] = "INV_Ore_Thorium_01",
	["Fel Iron Deposit"] = "INV_Ore_FelIron",
	["Adamantite Deposit"] = "INV_Ore_Adamantium",
	["Rich Adamantite Deposit"] = "INV_Ore_Adamantium_01",
	["Khorium Vein"] = "INV_Ore_Khorium",
	["Nethercite Deposit"] = "INV_Ore_Ethernium_01",
}
local reverse_list = {
	["Copper"] = "Copper Vein",
	["Tin"] = "Tin Vein",
	["Iron"] = "Iron Deposit",
	["Silver"] = "Silver Vein",
	["Gold"] = "Gold Vein",
	["Mithril"] = "Mithril Deposit",
	["Truesilver"] = "Truesilver Deposit",
	["Thorium"] = "Small Thorium Vein",
	["Rich Thorium"] = "Rich Thorium Vein",
	["Dark Iron"] = "Dark Iron Deposit",
	["Indurium"] = "Indurium Mineral Vein",
	["Lesser Bloodstone"] = "Lesser Bloodstone Deposit",
	["Incendicite"] = "Incendicite Mineral Vein",
	["Fel Iron"] = "Fel Iron Deposit",
	["Adamantite"] = "Adamantite Deposit",
	["Rich Adamantite"] = "Rich Adamantite Deposit",
	["Khorium"] = "Khorium Vein",
	["Nethercite"] = "Nethercite Deposit",
}
-- List each rare nodes and the non-rare nodes they can override
local rare_spawns = {
	["Silver Vein"] = {
		"Tin Vein",
	},
	["Gold Vein"] = {
		"Mithril Deposit",
		"Iron Deposit",
	},
	["Truesilver Deposit"] = {
		"Mithril Deposit",
		"Small Thorium Vein",
		"Rich Thorium Vein",
	},
	["Dark Iron Deposit"] = {
		"Mithril Deposit",
		"Small Thorium Vein",
		"Rich Thorium Vein",
	},
	["Ooze Covered Truesilver Deposit"] = {
		"Ooze Covered Thorium Vein",
		"Ooze Covered Rich Thorium Vein",
	},
	["Ooze Covered Silver Vein"] = {
		"Ooze Covered Thorium Vein",
		"Ooze Covered Rich Thorium Vein",
	},
	["Ooze Covered Gold Vein"] = {
		"Ooze Covered Thorium Vein",
		"Ooze Covered Rich Thorium Vein",
	},
	["Rich Adamantite Deposit"] = {
		"Adamantite Deposit",
		"Khorium Vein",
	},
	["Khorium Vein"] = {
		"Adamantite Deposit",
		"Rich Adamantite Deposit",
		"Fel Iron Deposit",
	},
}
mod.icon = {}
function mod:OnInitialize()
	self.db = Cartographer:AcquireDBNamespace("Mining")
	Cartographer:RegisterDefaults("Mining", "profile", {
		filter = {
			['*'] = true,
		},
		iconAlpha = 1,
		iconScale = 1,
		minicons = true,
	})

	local aceopts = {}
	aceopts.toggle = {
		name = Cartographer.L["Enabled"],
		desc = Cartographer.L["Suspend/resume this module."],
		type  = 'toggle',
		order = -1,
		get   = function() return Cartographer:IsModuleActive(self) end,
		set   = function() Cartographer:ToggleModuleActive(self) end,
	}
	aceopts.trans = {
		name = L["Icon alpha"],
		desc = L["Alpha transparency of the icon"],
		type = 'range',
		min = 0.1,
		max = 1,
		step = 0.01,
		bigStep = 0.05,
		isPercent = true,
		get = "GetIconAlpha",
		set = "SetIconAlpha",
		order = 1
	}
	aceopts.scal = {
		name = L["Icon size"],
		desc = L["Size of the icons on the map"],
		type = 'range',
		min = 0.5,
		max = 2,
		step = 0.01,
		bigStep = 0.05,
		isPercent = true,
		get = "GetIconScale",
		set = "SetIconScale",
		order = 1
	}
	aceopts.minicons = {
		name = L["Show minimap icons"],
		desc = L["Show mining icons on the minimap"],
		type = 'toggle',
		set = "ToggleShowingMinimapIcons",
		get = "IsShowingMinimapIcons",
		order = 1,
	}

	aceopts.filter = {
		name = L["Filter"],
		desc = L["Filter out minerals"],
		type = 'group',
		args = {
			all = {
				name = L["Select all"],
				desc = L["Select all"],
				type = 'execute',
				func = function()
					for k in pairs(self.icon) do
						self:ToggleShowingMineral(k, true)
					end
				end,
				order = 1,
			},
			none = {
				name = L["Select none"],
				desc = L["Select none"],
				type = 'execute',
				func = function()
					for k in pairs(self.icon) do
						self:ToggleShowingMineral(k, false)
					end
				end,
				order = 2,
			},
			blank = {
				type = 'header',
				order = 3,
			}
		}
	}
	local function isShowingMineral(min)
		return self:IsShowingMineral(min)
	end
	local function toggleShowingMineral(min, val)
		return self:ToggleShowingMineral(min, val)
	end
	for k,v in pairs(icon_list) do
		mod.icon[k] = {
			text = BO[k],
			path = icon_path..v,
			width = 14,
			height = 14,
		}
		local k = k
		aceopts.filter.args[k] = {
			name = BO[k],
			desc = BO[k],
			type = "toggle",
			get = isShowingMineral,
			set = toggleShowingMineral,
			passValue = k,
		}
		Talismonger:TrackNode(BO[k])
	end
	
	Cartographer.options.args["Mining"] = {
		name = bs["Mining"],
		desc = L["Module description"],
		type = 'group',
		args = aceopts,
		handler = self,
	}
	Cartographer:GetModule('Professions').addons[bs["Mining"]] = self
	AceLibrary("AceConsole-2.0"):InjectAceOptionsTable(self, Cartographer.options.args["Mining"])

	if not Cartographer_MiningDB then
		Cartographer_MiningDB = {}
	else
		local db_version = Cartographer_MiningDB.version
		for _, zone in pairs(Cartographer_MiningDB) do
			if type(zone) == "table" then
				for id, data in pairs(zone) do
					if reverse_list[data] then
						zone[id] = reverse_list[data]
					end
					if BO:HasReverseTranslation(data) and reverse_list[BO.reverse[data]] then
						zone[id] = reverse_list[BO.reverse[data]]
					end
				end
			end
		end
	end
end

function mod:OnEnable()
	if Cartographer_Notes then
		if not self.iconsregistered then
			for k,v in pairs(self.icon) do
				Cartographer_Notes:RegisterIcon(k, v)
			end
			self.iconsregistered = true
		end

		Cartographer_Notes:RegisterNotesDatabase('Mining', Cartographer_MiningDB, self)
	else
		Cartographer:ToggleModuleActive(self, false)
	end
	self:RegisterEvent("Talismonger_Node")
end

function mod:OnDisable()
	self:UnregisterAllEvents()
	if Cartographer_Notes then
		Cartographer_Notes:UnregisterNotesDatabase('Mining')
	end
end

local function compare(found, note)
	if type(found) == "table" then
		for i, v in ipairs(found) do
			if v == note then return true end
		end
	else
		return found == note
	end
end

function mod:SetNote(zone, x, y, what)
	if x == 0 and y == 0 then return end
	local mine = BO:HasReverseTranslation(what) and BO:GetReverseTranslation(what) or what
	local original = mine
	if rare_spawns[mine] then mine = rare_spawns[mine] end
	for zone, x_p, y_p, icon, creator, data in Cartographer_Notes:IterateNearbyNotes(zone, x, y, 10, "Mining", nil, true) do
		if compare(mine, icon) or icon == original or rare_spawns[icon] then
			Cartographer_Notes:DeleteNote(zone, x_p, y_p)
		end
	end
	local mineToAdd = type(mine) == "table" and mine[1] or mine
	Cartographer_Notes:SetNote(zone, x, y, mineToAdd, "Mining")
	return true
end
mod.OnNoteReceive = mod.SetNote

function mod:OnNoteTooltipRequest(zone, id, mineral, minimap)
	if not BO:HasTranslation(mineral) then
		if reverse_list[mineral] then
			mineral = reverse_list[mineral]
		end
	end
	Tablet:SetTitle(BO[mineral])
	Tablet:SetTitleColor(0, 0.8, 0)
	if Cartographer_Notes:IsShowingCreator() and not minimap then
		Tablet:AddCategory(
			'columns', 2,
			'hideBlankLine', true
		):AddLine(
			'text', Cartographer_Notes.L["Created by"],
			'text2', bs["Mining"]
		)
	end
end

function mod:RegisterOre(what)
	if what and what:len() > 0 then
		local x, y = GetPlayerMapPosition("player")
		
		-- fix not 1-to-1 mapping localization issue
		if ALT_NAMES and ALT_NAMES[what] then
			what = ALT_NAMES[what];
		else
			what = BO.reverse[what];
		end
		
		self:SetNote(GetRealZoneText(), x, y, what)
	end
end

function mod:Talismonger_Node(spell,what)
	if spell == "Mining" then
		self:RegisterOre(what)
	end
end

function mod:IsNoteHidden(zone, id, mineral)
	return not self.db.profile.filter[mineral]
end

function mod:IsShowingMineral(mineral)
	return self.db.profile.filter[mineral]
end

function mod:ToggleShowingMineral(mineral, value)
	if value == nil then
		value = not self.db.profile.filter[mineral]
	end
	self.db.profile.filter[mineral] = value

	Cartographer_Notes:RefreshMap()
end
function mod:GetIconScale()
	return self.db.profile.iconScale
end

function mod:SetIconScale(value)
	self.db.profile.iconScale = value
	Cartographer_Notes:RefreshMap()
end
function mod:GetIconAlpha()
	return self.db.profile.iconAlpha
end

function mod:SetIconAlpha(value)
	self.db.profile.iconAlpha = value
	Cartographer_Notes:RefreshMap()
end

function mod:GetNoteTransparency(zone,id,data)
	return self.db.profile.iconAlpha
end
function mod:GetNoteScaling(zone,id,data)
	return self.db.profile.iconScale
end
function mod:IsShowingMinimapIcons()
	return self.db.profile.minicons
end
function mod:ToggleShowingMinimapIcons()
	self.db.profile.minicons = not self.db.profile.minicons
end
function mod:IsMiniNoteHidden(zone,id,data)
	return not self.db.profile.minicons
end

