local Tablet = AceLibrary("Tablet-2.0")
local BZ = AceLibrary("Babble-Zone-2.2")
local Tourist = AceLibrary("Tourist-2.0")
local L = AceLibrary("AceLocale-2.2"):new("Cartographer_Fishing")
local BF = AceLibrary("Babble-Fish-2.2")
local Talismonger = AceLibrary("Talismonger-3.0")

L:RegisterTranslations("enUS", function() return {
	["Filter"] = true,
	["Filter out fish"] = true,
	["Module description"] = "Fishing mapnotes for Cartographer (inspired by FishingBuddy, Gatherer and Cartographer_Herbalism)",
	["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 Tastyfish"] = true,
	["Show only tastyfish nodes during the fishing extraveganza"] = true,
	["Show minimap icons"] = true,
	["Show fishing icons on the minimap"] = true,
} end)

L:RegisterTranslations("deDE", function() return {
	["Filter"] = "Filter",
	["Filter out fish"] = "Fische filtern",
	["Module description"] = "Angeln-Kartennotizen f\195\188r Cartographer (inspiriert von FishingBuddy, Gatherer und Cartographer_Herbalism)",
	["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öße",
	["Size of the icons on the map"] = "Gr\195\182\195\159e der Symbole auf der Weltkarte",
	["Show Tastyfish"] = "Leckerfisch anzeigen",
	["Show only tastyfish nodes during the fishing extraveganza"] = "Während des Angelwettbewerbs nur Leckerfischschwärme anzeigen.",
	["Show minimap icons"] = "Minimap-Symbole anzeigen",
	["Show fishing icons on the minimap"] = "Fischsymbole auf der Minimap anzeigen.",
} end)

L:RegisterTranslations("frFR", function() return {
	["Filter"] = "Filtrer",
	["Filter out fish"] = "Détermine les types de bancs à afficher.",
	["Module description"] = "Notes de pêche pour Cartographer (inspiré de FishingBuddy, Gatherer et Cartographer_Herbalism).",
	["Select all"] = "Tout sélectionner",
	["Select none"] = "Ne rien sélectionner",
	["Icon alpha"] = "Transparence des icônes",
	["Alpha transparency of the icon"] = "Détermine la transparence des icônes.",
	["Icon size"] = "Taille des icônes",
	["Size of the icons on the map"] = "Détermine la taille des icônes sur la carte.",
	["Show Tastyfish"] = "Afficher les courbines",
	["Show only tastyfish nodes during the fishing extraveganza"] = "Affiche uniquement les bancs de courbines pendant le concours de pêche.",
	["Show minimap icons"] = "Afficher les icônes sur la minicarte",
	["Show fishing icons on the minimap"] = "Affiche les icônes des bancs sur la minicarte.",
} end)

L:RegisterTranslations("koKR", function() return {
	["Filter"] = "필터링",
	["Filter out fish"] = "낚시를 항목에 따라 분류하여 표시합니다.",
	["Module description"] = "낚시 노드를 월드맵에 표시합니다.",
	["Select all"] = "모두 선택",
	["Select none"] = "선택 해제",
	["Icon alpha"] = "아이콘 투명도",
	["Alpha transparency of the icon"] = "아이콘의 투명도를 조절합니다.",
	["Icon size"] = "아이콘 크기",
	["Size of the icons on the map"] = "아이콘의 크기를 조절합니다.",
	["Show Tastyfish"] = "맛둥어 보이기",
	["Show only tastyfish nodes during the fishing extraveganza"] = "낚시대회 시간에만 맛둥어 기록을 보입니다.",
	["Show minimap icons"] = "미니맵 아이콘 보기",
	["Show fishing icons on the minimap"] = "낚시 노드를 미니맵에 표시합니다.",
} end)

L:RegisterTranslations("zhTW", function() return {
	["Filter"] = "過濾",
	["Filter out fish"] = "過濾魚類",
	["Module description"] = "Cartographer 模組，紀錄魚群位置 (靈感來自 FishingBuddy，Gatherer 和 Cartographer_Herbalism)。",
	["Select all"] = "全部選擇",
	["Select none"] = "全部取消",
	["Icon alpha"] = "圖示透明度",
	["Alpha transparency of the icon"] = "地圖上的圖示透明度",
	["Icon size"] = "圖示大小",
	["Size of the icons on the map"] = "地圖上的圖示大小",
	["Show Tastyfish"] = "顯示斑點可口魚",
	["Show only tastyfish nodes during the fishing extraveganza"] = "在釣魚比賽時只顯示斑點可口魚魚群",
	["Show minimap icons"] = "迷你地圖圖示",
	["Show fishing icons on the minimap"] = "將魚群圖示顯示於迷你地圖上",
} end)

L:RegisterTranslations("zhCN", function() return {
	["Filter"] = "筛选",
	["Filter out fish"] = "钓鱼筛选",
  	["Module description"] = "Cartographer 钓鱼模块，记录鱼群位置",
	["Select all"] = "全部选择",
	["Select none"] = "全部取消",
	["Icon alpha"] = "图标透明度",
	["Alpha transparency of the icon"] = "设定图标的透明度",
	["Icon size"] = "图标大小",
	["Size of the icons on the map"] = "地图上图标的大小",
	["Show Tastyfish"] = "显示斑点可口鱼",
	["Show only tastyfish nodes during the fishing extraveganza"] = "在钓鱼比赛时只显示斑点可口鱼鱼群",
	["Show minimap icons"] = "显示小地图图标",
	["Show fishing icons on the minimap"] = "在小地图上显示鱼群图标",
} end)

L:RegisterTranslations("esES", function() return {
	["Filter"] = "Filtro",
	["Filter out fish"] = "Filtra el pescado",
	["Module description"] = "Notas de Pesca en el Mapa para Cartographer (inspirado por FishingBuddy, Gatherer y Cartographer_Herbalism)",
	["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ño de icono",
	["Size of the icons on the map"] = "Tamaño de los iconos en el mapa",
	["Show Tastyfish"] = "Mostrar Pezrico moteado",
	["Show only tastyfish nodes during the fishing extraveganza"] = "Muestra solo los nodos de Pezrico moteado durante el concurso de pesca",
	["Show minimap icons"] = "Mostrar iconos en MiniMapa",
	["Show fishing icons on the minimap"] = "Muestra los iconos de pesca en el MiniMapa",
} end)

Cartographer_Fishing = Cartographer:NewModule("Fishing", "AceConsole-2.0", "AceEvent-2.0")

local fishSpell = GetSpellInfo(7620)

local icon_path = "Interface\\Addons\\Cartographer_Fishing\\Artwork\\"
local icon_list = {
	["Floating Wreckage"] = "Treasure",
	["Patch of Elemental Water"] = "WaterPatch",
	["Floating Debris"] = "Debris",
	["Oil Spill"] = "OilSpill",
	["Firefin Snapper School"] = "Firefin",
	["Greater Sagefish School"] = "GreatesageFish",
	["Oily Blackmouth School"] = "OilyBlackmouth",
	["Sagefish School"] = "Sagefish",
	["School of Deviate Fish"] = "Net",
	["School of Tastyfish"] = "FishHook",
	["Stonescale Eel Swarm"] = "Eel",
	["Muddy Churning Water"] = "Net",
	["Pure Water"] = "PureWater",
	["Highland Mixed School"] = "CrawDad",
	["Bluefish School"] = "BlueFish",
	["Feltail School"] = "FelTail",
	["Mudfish School"] = "Mudfish",
	["School of Darter"] = "Darter",
	["Sporefish School"] = "Sporefish",
	["Steam Pump Flotsam"] = "SteamPump",
}
local fish_list = {
	"Spotted Sunfish",
	"Lightning Eel",
	"Plated Armorfish",
	"Darkshore Grouper",
	"Stonescale Eel",
	"Oily Blackmouth",
	"Firefin Snapper",
	"Oil Covered Fish",
	"Sickly Looking Fish",
	"Raw Brilliant Smallfish",
	"Raw Bristle Whisker Catfish",
	"Raw Glossy Mightfish",
	"Raw Greater Sagefish",
	"Raw Loch Frenzy",
	"Raw Longjaw Mud Snapper",
	"Raw Mithril Head Trout",
	"Raw Nightfin Snapper",
	"Raw Rainbow Fin Albacore",
	"Raw Redgill",
	"Raw Rockscale Cod",
	"Raw Sagefish",
	"Raw Slitherskin Mackerel",
	"Raw Spotted Yellowtail",
	"Raw Summer Bass",
	"Raw Sunscale Salmon",
	"Raw Whitescale Salmon",
	"Darkclaw Lobster",
	"Deviate Fish",
	"Large Raw Mightfish",
	"Winter Squid",
	"Felblood Snapper",
	"Figluster's Mudfish",
	"Furious Crawdad",
	"Golden Darter",
	"Icefin Bluefish",
	"Spotted Feltail",
	"Zangarian Sporefish",
}
Cartographer_Fishing.icon = {}
Cartographer_Fishing.isFishing = false

function Cartographer_Fishing:OnInitialize()
	self.db = Cartographer:AcquireDBNamespace("Fishing")
	Cartographer:RegisterDefaults("Fishing", "profile", {
		filter = {
			['*'] = true,
		},
		iconAlpha = 1,
		iconScale = 1,
		showContest = false,
		minicons = true,
	})

	local aceopts = {}
	aceopts.trans = {
		name = L["Icon alpha"],
		desc = L["Alpha transparency of the icon"],
		type = 'range',
		min = 0.1,
		max = 1,
		step = 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.05,
		isPercent = true,
		get = "GetIconScale",
		set = "SetIconScale",
		order = 1
	}
	aceopts.minicons = {
		name = L["Show minimap icons"],
		desc = L["Show fishing icons on the minimap"],
		type = 'toggle',
		set = "ToggleShowingMinimapIcons",
		get = "IsShowingMinimapIcons",
		order = 1,
	}
	aceopts.contest = {
		name = L["Show Tastyfish"],
		desc = L["Show only tastyfish nodes during the fishing extraveganza"],
		type = 'toggle',
		order = 300,
		get = 'GetShowWhenContest',
		set = 'ToggleShowWhenContest',
	}
	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.filter = {
		name = L["Filter"],
		desc = L["Filter out fish"],
		type = 'group',
		args = {
			all = {
				name = L["Select all"],
				desc = L["Select all"],
				type = 'execute',
				func = function()
					for k in pairs(self.icon) do
						self:ToggleShowingFish(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:ToggleShowingFish(k, false)
					end
				end,
				order = 2,
			},
			blank = {
				type = 'header',
				order = 3,
			}
		}
	}
	for k,v in pairs(icon_list) do
		local k = k
		self.icon[k] = {
			text = BF[k],
			path = icon_path..v,
			width = 12,
			height = 12,
		}
		aceopts.filter.args[k] = {
			name = BF[k],
			desc = BF[k],
			type = 'toggle',
			get = function()
				return self:IsShowingFish(k)
			end,
			set = function(value)
				return self:ToggleShowingFish(k, value)
			end,
		}
		Talismonger:TrackNode(BF[k])
	end
	for _,v in ipairs(fish_list) do
		Talismonger:TrackLoot(BF[v])
	end
	Cartographer.options.args["Fishing"] = {
		name = fishSpell,
	    	desc = L["Module description"],
		type = 'group',
		args = aceopts,
		handler = self,
	}
	AceLibrary("AceConsole-2.0"):InjectAceOptionsTable(self, Cartographer.options.args["Fishing"])
	Cartographer:GetModule('Professions').addons[fishSpell] = self

	if not Cartographer_FishingDB then
		Cartographer_FishingDB = {}
		Cartographer_FishingDB.nodes = {}
		Cartographer_FishingDB.fish = {}
	end
	if not Cartographer_FishingDB.nodes then
		Cartographer_FishingDB.nodes = {}
	end
	if not Cartographer_FishingDB.fish then
		Cartographer_FishingDB.fish = {}
	else -- fix unlocalizaed names
		for _,zone in pairs(Cartographer_FishingDB.fish) do
			if type(zone) == "table" then
				for id,fish in ipairs(zone) do
					if BF:HasReverseTranslation(fish) then
						local newName = BF.reverse[fish]
						zone[id] = newName
					end
				end
			end
		end
	end
end

function Cartographer_Fishing:IsTracking(zone,id,data)
	return true
end
function Cartographer_Fishing: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('Fishing', Cartographer_FishingDB.nodes, self)
	else
		Cartographer:ToggleModuleActive(self, false)
	end
	-- Add the fish
	self:RegisterEvent("Talismonger_Node")
	self:RegisterEvent("Talismonger_Radical")
end

function Cartographer_Fishing:OnDisable()
	self:UnregisterAllEvents()
	if Cartographer_Notes then
		Cartographer_Notes:UnregisterNotesDatabase('Fishing')
	end
end

function Cartographer_Fishing:Talismonger_Node(spell,node)
	if (spell == "Fishing" or spell == fishSpell )and BF:HasReverseTranslation(node) then
		self:SetNote(node)
	end
end

function Cartographer_Fishing:SetNote(what)
	local x, y = GetPlayerMapPosition("player")
	if x == 0 and y == 0 then return end
	if not BF:HasReverseTranslation(what) then
		return
	end
	what = BF.reverse[what]
	local zone = GetRealZoneText()
	-- cursor direction
	local currentYardWidth, currentYardHeight = Tourist:GetZoneYardSize(GetRealZoneText())
	x,y = self:GetFishingNodeLocation(x,y,currentYardWidth,currentYardHeight)
	-- calculated a trget 30 yards out (max fish range)
	for zone, x_p, y_p, icon, creator, data in Cartographer_Notes:IterateNearbyNotes(zone, x, y, 30, "Fishing", nil, true) do
		if icon == what then
			Cartographer_Notes:DeleteNote(zone, x_p, y_p)
		end
	end
	Cartographer_Notes:SetNote(zone, x, y, what, "Fishing")
end

function Cartographer_Fishing:OnNoteTooltipRequest(zone, id, fish, minimap)
	if BF:HasTranslation(fish) then
		Tablet:SetTitle(BF[fish])
	else
		Table:SetTitle(fish)
	end
	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', fishSpell
		)
	end
end

local function getArrowModel(...)
	if(GetCVar("rotateMinimap") == "1") then return -MiniMapCompassRing:GetFacing()	end
	for i=select("#",...),1,-1 do
		local model=select(i,...)
		if model:IsObjectType("Model") and not model:GetName() then	return model and model:GetFacing() end
	end
	return nil
end

function Cartographer_Fishing:GetFishingNodeLocation(x,y,yardWidth,yardHeight)
	local facing = getArrowModel(Minimap:GetChildren())
	if not facing then	-- happens when minimap rotation is on
		ChatFrame1:AddMessage("Cartographer_Fishing: Warning: Can't figure out which way you are facing. Placing note right under your feet.")
		return x,y
	else
		local rad = facing + math.pi
		x,y = x * yardWidth, y * yardHeight
		x,y = x+math.sin(rad)*20, y+math.cos(rad)*20	-- cast length is 10-20, this was 30. let's call it 20.
		x,y = x/yardWidth,y/yardHeight
		return x,y
	end
end
function Cartographer_Fishing:Talismonger_Radical(spell, loot, count)
	if spell == "Fishing" then
		if BF:HasReverseTranslation(loot) and fish_list[BF.reverse[loot]] then
			local zone = GetRealZoneText()
			zone =  BZ.reverse[zone]
			if not Cartographer_FishingDB.fish[zone] then
				Cartographer_FishingDB.fish[zone] = {}
			end
			local stable = Cartographer_FishingDB.fish[zone]
			table.insert(stable,BF.reverse[loot])
			self:TriggerEvent("CartographerFishing_CaughtFish", zone, x, y, BF.reverse[loot],"Fishing")
		end
	end
end

local lasthour=-1
local wday=-1

function Cartographer_Fishing:IsContestTime()
	local hours,minutes = GetGameTime();
	if hours~=lasthour then
		lasthour=hours
		local temp = date("*t", time())
		wday=temp.wday
	end
	return (wday == 0) and (hours >= 14 or hours <= 16)
end

local iscontesttime=Cartographer_Fishing:IsContestTime()

AceLibrary("AceEvent-2.0"):ScheduleRepeatingEvent(function()
	iscontesttime=Cartographer_Fishing:IsContestTime()
end, 15)

function Cartographer_Fishing:IsNoteHidden(zone, id, fish)
	if iscontesttime and self.db.profile.showContest and fish ~= "School of Tastyfish" then
		return false
	end
	return not self.db.profile.filter[fish]
end

function Cartographer_Fishing:IsShowingFish(fish)
	return self.db.profile.filter[fish]
end

function Cartographer_Fishing:ToggleShowingFish(fish, value)
	if value == nil then
		value = not self.db.profile.filter[fish]
	end
	self.db.profile.filter[fish] = value
	Cartographer_Notes:RefreshMap()
end

function Cartographer_Fishing:ToggleShowWhenContest()
	self.db.profile.showContest = not self.db.profile.showContest
end
function Cartographer_Fishing:GetShowWhenContest()
	return self.db.profile.showContest
end

function Cartographer_Fishing:GetIconScale()
	return self.db.profile.iconScale
end

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

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

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