local AceAddon = AceLibrary("AceAddon-2.0")
local Tablet = AceLibrary("Tablet-2.0")
local Tooltip = AceLibrary("Gratuity-2.0")
local BT = AceLibrary("Babble-Trainer-2.2")

local L = AceLibrary("AceLocale-2.2"):new("Cartographer_Trainers")
L:RegisterTranslations("enUS", function() return {
	["Filter"] = true,
	["Filter out trainers"] = true,
  
    ["Trainers"] = true,
    ["Module description"] = "Trainer Mapnotes for Cartographer",
  
	["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 trainer icons on the minimap"] = true,
    ["Show minimap tracking icons"] = true,
    ["Show trainer tracking icons on the minimap"] = true,
    
    ["Import"] = true,
    ["Import trainers"] = true,
    ["Rebuild"] = true,
    ["Rebuild trainers"] = true,
    
    ["Trainer"] = true,
    ["Mage Trainer"] = true,
    
    -- Filters
    ["Tailoring"] = true,
    ["Blacksmithing"] = true,
    ["Fishing"] = true,
    ["Mining"] = true,
    ["First Aid"] = true,
    ["Alchemy"] = true,
    ["Class"] = true,
    ["Herbalism"] = true,
    ["Jewelcrafting"] = true,
    ["Engineering"] = true,
    ["Leatherworking"] = true,
    ["Riding"] = true,
    ["Enchanting"] = true,
        
} end)

L:RegisterTranslations("koKR", function() return {
	["Filter"] = "항목 분류",
	["Filter out trainers"] = "상급 기술자를 항목에 따라 분류하여 표시합니다.",

    ["Trainers"] = "상급 기술자",
    ["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 trainer icons on the minimap"] = "미니맵에 기술자 아이콘을 표시합니다.",
    ["Show minimap tracking icons"] = "미니맵에 추적아이콘 보기",
    ["Show trainer tracking icons on the minimap"] = "미니맵에 기술자 추적아이콘을 표시합니다.",

    ["Import"] = "외부 데이터 입력",
    ["Import trainers"] = "기술자 정보를 입력합니다.",
    ["Rebuild"] = "재배치",
    ["Rebuild trainers"] = "기술자 정보를 재배치 합니다.",

    -- Filters
    ["Tailoring"] = "재봉술",
    ["Blacksmithing"] = "대장기술",
    ["Fishing"] = "낚시",
    ["Mining"] = "채광",
    ["First Aid"] = "응급치료",
    ["Alchemy"] = "연금술",
    ["Class"] = "직업",
    ["Herbalism"] = "약초 채집",
    ["Jewelcrafting"] = "보석세공",
    ["Engineering"] = "기계공학",
    ["Leatherworking"] = "가죽세공",
    ["Riding"] = "탑승",
    ["Enchanting"] = "마법부여",
} end)

L:RegisterTranslations("deDE", function() return {
	["Filter"] = "Filter",
	["Filter out trainers"] = "Lehrer filtern",
	
   ["Trainers"] = "Lehrer",
   ["Module description"] = "Lehrer-Kartennotizen f\195\188r Cartographer",

	["Select all"] = "Alles 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 trainer icons on the minimap"] = "Lehrer-Symbole auf der Minimap anzeigen.",
    ["Show minimap tracking icons"] = "Ortungssymbole anzeigen",
    ["Show trainer tracking icons on the minimap"] = "Lehrer-Symbole auf der Minimap schalten bei Annäherung auf Ortungskreise um.",

    ["Import"] = "Import",
    ["Import trainers"] = "Importiere Lehrerpositionen",
    ["Rebuild"] = "Rekonstruktion",
    ["Rebuild trainers"] = "Rekonstruktion der Lehrerpositionen",

    ["Trainer"] = "Lehrer",
    ["Mage Trainer"] = "Magierlehrer",

    -- Filters
    ["Tailoring"] = "Schneidern",
    ["Blacksmithing"] = "Schmiedekunst",
    ["Fishing"] = "Angeln",
    ["Mining"] = "Bergbau",
    ["First Aid"] = "Erste Hilfe",
    ["Alchemy"] = "Alchimie",
    ["Class"] = "Klasse",
    ["Herbalism"] = "Kr\195\164uterkunde",
    ["Jewelcrafting"] = "Juwelenschleifen",
    ["Engineering"] = "Ingenieurskunst",
    ["Leatherworking"] = "Lederverarbeitung",
    ["Riding"] = "Reiten",
    ["Enchanting"] = "Verzaubern",

} end)

L:RegisterTranslations("zhTW", function() return {
	["Filter"] = "篩檢",
	["Filter out trainers"] = "篩檢訓練師",
  
    ["Trainers"] = "訓練師",
    ["Module description"] = "Cartographer 訓練師地圖註記",

    ["Select all"] = "全部選擇",
    ["Select none"] = "全部取消",
    ["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 trainer icons on the minimap"] = true,
    ["Import"] = true,
    ["Import Trainers"] = true,

    ["Trainer"] = "訓練師",
} end)

L:RegisterTranslations("esES", function() return {
	["Filter"] = "Filtrar",
	["Filter out trainers"] = "Filtra instructores",
  
    ["Trainers"] = "Instructores",
    ["Module description"] = "Notas de mapa de instructores para Cartographer",
  
	["Select all"] = "Seleccionar todo",
	["Select none"] = "No seleccionar nada",

    ["Icon alpha"] = "Transparencia de icono",
    ["Alpha transparency of the icon"] = "Transparencia del icono",
    ["Icon size"] = "Tama\195\177o del 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 trainer icons on the minimap"] = "Muestra los iconos de instructores en el minimapa",
    ["Import"] = "Importar",
    ["Import Trainers"] = "Importar Instructores",

    ["Trainer"] = "Instructor",
    ["Mage Trainer"] = "Instructor de magos",
} end)

Cartographer_Trainers = Cartographer:NewModule("Trainers", "AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0")
Cartographer_Trainers.revision = tonumber(string.sub("$Revision: 30560 $", 12, -3))
Cartographer_Trainers.version = "r" .. Cartographer_Trainers.revision
Cartographer_Trainers.date = string.sub("$Date: 2007-03-19 20:44:37 -0400 (Mon, 19 Mar 2007) $", 8, 17)
Cartographer_Trainers:RegisterDB("Cartographer_TrainersDB")

Cartographer_Trainers.filters = {
    ["Tailoring"] = L["Tailoring"],
    ["Blacksmithing"] = L["Blacksmithing"],
    ["Fishing"] = L["Fishing"],
    ["Mining"] = L["Mining"],
    ["First Aid"] = L["First Aid"],
    ["Alchemy"] = L["Alchemy"],
    ["Class"] = L["Class"],
    ["Herbalism"] = L["Herbalism"],
    ["Jewelcrafting"] = L["Jewelcrafting"],
    ["Engineering"] = L["Engineering"],
    ["Leatherworking"] = L["Leatherworking"],
    ["Riding"] = L["Riding"],
    ["Enchanting"] = L["Enchanting"],
}

Cartographer_Trainers.lookups = {
    ["filters"] = {
        ["Chief Engineer"] = "Engineering",
        ["Bael'dun Chief Engineer"] = "Engineering",
        ["Raptor Riding Trainer"] = "Riding",
        ["Horse Riding Instructor"] = "Riding",
        ["Leatherworking Trainer"] = "Leatherworking",
        ["Master Jewelcrafter"] = "Jewelcrafting",
        ["Artisan Enchanter"] = "Enchanting",
        ["Unbalanced Engineer"] = "Engineering",
        ["Journeyman Jewelcrafter"] = "Jewelcrafting",
        ["Expert Tailor"] = "Tailoring",
        ["Expert Blacksmith"] = "Blacksmithing",
        ["Artisan Blacksmith"] = "Blacksmithing",
        ["Expert Alchemist"] = "Alchemy",
        ["Master Gnome Engineer"] = "Engineering",
        ["Druid Trainer"] = "Class",
        ["Journeyman Engineer"] = "Engineering",
        ["Superior Leatherworker"] = "Leatherworking",
        ["Journeyman Tailor"] = "Tailoring",
        ["Journeyman Leatherworker"] = "Leatherworking",
        ["Grand Master Alchemist"] = "Alchemy",
        ["Grand Master Leatherworker"] = "Leatherworking",
        ["Portal Trainer"] = "Class",
        ["Grand Master Enchanter"] = "Enchanting",
        ["Grand Master Blacksmith"] = "Blacksmithing",
        ["Engineer"] = "Engineering",
        ["Riding Instructor"] = "Riding",
        ["Priest Trainer"] = "Class",
        ["Journeyman Alchemist Trainer"] = "Alchemy",
        ["Kodo Riding Instructor"] = "Riding",
        ["Artisan Engineer"] = "Engineering",
        ["Master Dragonscale Leatherworker"] = "Leatherworking",
        ["Herbalism Trainer"] = "Herbalism",
        ["Blacksmith"] = "Blacksmithing",
        ["Paladin Trainer"] = "Class",
        ["Master Engineer"] = "Engineering",
        ["Fishing Trainer"] = "Fishing",
        ["Transportation Engineer"] = "Engineering",
        ["Master Elemental Leatherworker"] = "Leatherworking",
        ["Mage Trainer"] = "Class",
        ["Artisan Tailor"] = "Tailoring",
        ["Explorers' League"] = "Mining",
        ["Grand Master Tailor"] = "Tailoring",
        ["Master Leatherworker"] = "Leatherworking",
        ["Master Tailor"] = "Tailoring",
        ["Trauma Surgeon"] = "First Aid",
        ["Master Blacksmith"] = "Blacksmithing",
        ["Journeyman Blacksmith"] = "Blacksmithing",
        ["Undead Horse Riding Instructor"] = "Riding",
        ["Wolf Riding Instructor"] = "Riding",
        ["Tribal Leatherworking Trainer"] = "Leatherworking",
        ["Master Leatherworking Trainer"] = "Leatherworking",
        ["Speciality Engineer"] = "Engineering",
        ["Warrior Trainer"] = "Class",
        ["Master Tribal Leatherworker"] = "Leatherworking",
        ["Artisan Alchemist"] = "Alchemy",
        ["Journeyman Enchanter"] = "Enchanting",
        ["Grand Master Engineer"] = "Engineering",
        ["Artisan Leatherworker"] = "Leatherworking",
        ["Expert Enchanter"] = "Enchanting",
        ["Master Enchanter"] = "Enchanting",
        ["Master Alchemist"] = "Alchemy",
        ["Master Goblin Engineer"] = "Engineering",
        ["Head Eco-Dome Engineer"] = "Engineering",
        ["Hunter Trainer"] = "Class",
        ["Expert Engineer"] = "Engineering",
        ["Expert Leatherworker"] = "Leatherworking",
        ["Journeyman Alchemist"] = "Alchemy",
        ["Shaman Trainer"] = "Class",
        ["Ram Riding Instructor"] = "Riding",
        ["Master Shadoweave Tailor"] = "Tailoring",
        ["Grand Master Jewelcrafter"] = "Jewelcrafting",
        ["Mining Trainer"] = "Mining",
    },
}

Cartographer_Trainers.icons = {
	["Trainer"] = {
		text = L["Trainer"],
		path = "Interface\\AddOns\\Cartographer_Trainers\\Artwork\\INV_Misc_Book_03",
		width = 14,
		height = 14
	},
    ["Mage Trainer"] = {
        text = L["Mage Trainer"],
        path = "Interface\\AddOns\\Cartographer_Trainers\\Artwork\\INV_Misc_Book_03",
        width = 14,
        height = 14,
    },    
}

Cartographer_Trainers.trainers = {}

Cartographer_Trainers.noteDefaults = {
	titleCol = Cartographer_Notes.getColorID(0, 0.8, 0)
}

Cartographer_Trainers.noteLocaleHandler = BT

function Cartographer_Trainers:OnInitialize()
	self:RegisterDefaults("profile", {
		filters = {
			['*'] = true,
		},
        iconAlpha = 1,
		iconScale = 1,
        minimapIcons = true,
        minimapTracking = true,
        noteRadius = 15,        
	})
    
    self:RegisterDefaults("faction", {
        trainers = {
            ['*'] = {
                ['*'] = {},
            },
        },
    })

	local aceopts = {}
	aceopts.toggle = {
		name = AceLibrary("AceLocale-2.2"):new("Cartographer")["Enabled"],
		desc = AceLibrary("AceLocale-2.2"):new("Cartographer")["Suspend/resume this module."],
		type  = 'toggle',
		order = -1,
		get   = function() return Cartographer:IsModuleActive(self) end,
		set   = function() Cartographer:ToggleModuleActive(self) end,
	}
    
	aceopts.alpha = {
		name = L["Icon alpha"],
		desc = L["Alpha transparency of the icon"],
		type = 'range',
		min = 0.1,
		max = 1,
		step = 0.05,
		isPercent = true,
        set = function(v)
            self.db.profile.iconAlpha = v
            Cartographer_Notes:RefreshMap()
        end,
        get = function() return self.db.profile.iconAlpha end,
		order = 1
	}
	aceopts.scale = {
		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,
        set = function(v) 
            self.db.profile.iconScale = v
            Cartographer_Notes:RefreshMap()
        end,
        get = function() return self.db.profile.iconScale end,
		order = 2
	}    
    aceopts.minimapicons = {
		name = L["Show minimap icons"],
		desc = L["Show trainer icons on the minimap"],
		type = 'toggle',
        set = function()
            self.db.profile.minimapIcons = not self.db.profile.minimapIcons
            Cartographer_Notes:RefreshMap()
        end,
        get = function() return self.db.profile.minimapIcons end,
		order = 3,
	}
    
    aceopts.minimaptracking = {
        name = L["Show minimap tracking icons"],
        desc = L["Show trainer tracking icons on the minimap"],
        type = 'toggle',
        set = function() 
            self.db.profile.minimapTracking = not self.db.profile.minimapTracking
            Cartographer_Notes:RefreshMap()
        end,
        get = function() return self.db.profile.minimapTracking end,
        order = 4,
        hidden = function() return not self.db.profile.minimapIcons end,
    }   

	aceopts.filter = {
		name = L["Filter"],
		desc = L["Filter out trainers"],
		type = 'group',
		args = {
			all = {
				name = L["Select all"],
				desc = L["Select all"],
				type = 'execute',
				func = function()
					for k in pairs(self.filters) do
						self:ToggleShowingTrainers(k, true)
					end
				end,
				order = 1,
			},
			none = {
				name = L["Select none"],
				desc = L["Select none"],
				type = 'execute',
				func = function()
					for k in pairs(self.filters) do
						self:ToggleShowingTrainers(k, false)
					end
				end,
				order = 2,
			},
			blank = {
				type = 'header',
				order = 3,
			}
		},
        order = 4,
	}
    
    aceopts.rebuild = {
        name = L["Rebuild"],
        desc = L["Rebuild trainers"],
        type = 'execute',
        func = "RebuildTrainers",
        order = 6,
    }   

   	Cartographer.options.args.Trainers = {
		name = L["Trainers"],
		desc = L["Module description"],
		type = 'group',
		args = aceopts,
		handler = self,
	}
	-- AceLibrary("AceConsole-2.0"):InjectAceOptionsTable(self, Cartographer.options.args.Trainers)

	for k,v in pairs(self.filters) do
		local k = k
		aceopts.filter.args[k] = {
			name = v,
			desc = v,
			type = 'toggle',
			get = function()
				return self:IsShowingTrainers(k)
			end,
			set = function(value)
				return self:ToggleShowingTrainers(k, value)
			end,
		}
	end    
    
    if (not self.db.faction.notes) then self.db.faction.notes = {} end
    -- if (not self.trainers) and (self.db.server.trainers ~= nil) then self.trainers = self.db.server.trainers end
end

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

		Cartographer_Notes:RegisterNotesDatabase('Trainers', self.db.faction.notes, self)
	else
		Cartographer:ToggleModuleActive(self, false)
	end
    
    -- if (School) or (TrainerFu) then
    if (SchoolNotes) or (TrainerFu_TrainerNotes) then
        Cartographer:ToggleModuleActive(self, false)
    end
    
    if (Cartographer:IsModuleActive(self)) then
        self:RegisterEvent("TRAINER_SHOW", function() self:RegisterTrainer(UnitName("NPC")) end, 2)
    end
end

function Cartographer_Trainers:OnDisable()
	self:UnregisterAllEvents()

	if Cartographer_Notes then
		Cartographer_Notes:UnregisterNotesDatabase('Trainers')
	end
end

function Cartographer_Trainers:SetNote(trainer)
    if (type(trainer) == "string") then trainer = {["name"] = trainer} end
    if (type(trainer) ~= "table") then return end
    
    if (not trainer.x) or (not trainer.y) then trainer.x, trainer.y = GetPlayerMapPosition("player") end
    if (trainer.x == 0) and (trainer.y == 0) then return end
    
    if (not trainer.zone) then trainer.zone = GetRealZoneText() end
    
    local note = {
        ["title"] = trainer.name,
        ["icon"] = "Trainer",
        ["info"] = "Trainer",
    }
    
    if (trainer.type) then
        if (self.icons[trainer.type]) then note.icon = trainer.type
        elseif (self.icons[self.lookups.filters[trainer.type]]) then note.icon = self.lookups.filters[trainer.type] end
        note.info = trainer.type
    end
    
	for zone, x_p, y_p, icon, creator, data in Cartographer_Notes:IterateNearbyNotes(trainer.zone, trainer.x, trainer.y, (self.db.profile.noteRadius or 15), "Trainers", nil, true) do
		if data.title == note.title then
			Cartographer_Notes:DeleteNote(zone, x_p, y_p)
		end
	end
    
    -- DEFAULT_CHAT_FRAME:AddMessage(string.format("note.title: %s\nnote.info: %s", note.title, note.info))
	Cartographer_Notes:SetNote(trainer.zone, trainer.x, trainer.y, note.icon, "Trainers", note)
end

function Cartographer_Trainers:RegisterTrainer(trainer)
    if (not trainer) then return end
    if (type(trainer) ~= "string") then return end

    local zone = GetRealZoneText()
    local x,y = GetPlayerMapPosition("player")
   
    local entry = self.db.faction.trainers[zone][trainer]
    if (not entry.name) then entry.name = trainer end
    if (not entry.zone) then entry.zone = zone end
    if (not entry.x) then entry.x = x end
    if (not entry.y) then entry.y = y end
    if (not entry.type) then
        Tooltip:SetUnit("npc")
        local result = Tooltip:GetLine(2)
        if (result) then entry.type = result end
    end
    if (not entry.faction) then entry.faction = UnitFactionGroup("player") end
    self.db.faction.trainers[zone][trainer] = entry
    
    self:SetNote(entry)
end


function Cartographer_Trainers:IsNoteHidden(zone, id, trainer)
	if type(trainer) == "table" then
        return not self.db.profile.filters[self.lookups.filters[trainer.info]]
	else
		return not self.db.profile.filters[self.lookups.filters[trainer]]
	end
end

function Cartographer_Trainers:IsShowingTrainers(trainertype)
	return self.db.profile.filters[trainertype]
end

function Cartographer_Trainers:ToggleShowingTrainers(trainertype, value)
	if value == nil then
		value = not self.db.profile.filters[trainertype]
	end
	self.db.profile.filters[trainertype] = value

	Cartographer_Notes:RefreshMap()
end

function Cartographer_Trainers:IsTracking(zone,id,data)
    return true
end

function Cartographer_Trainers:IsShowingMinimapIcons()
	return self.db.profile.minimapIcons
end

function Cartographer_Trainers:ToggleShowingMinimapIcons()
	self.db.profile.minimapIcons = not self.db.profile.minimapIcons
end

function Cartographer_Trainers:IsTracking(zone,id,data)
    return self.db.profile.minimapTracking
end

function Cartographer_Trainers:IsMiniNoteHidden(zone,id,data)
	return not self.db.profile.minimapIcons
end

function Cartographer_Trainers:GetNoteTransparency(zone,id,data)
	return self.db.profile.iconAlpha
end

function Cartographer_Trainers:GetNoteScaling(zone,id,data)
	return self.db.profile.iconScale
end

function Cartographer_Trainers:RebuildTrainers()
    local result = self.db.faction.trainers
    
    if (self.module_import) then
        for k,v in pairs(self:ImportTrainers()) do
            if (v ~= nil) then
                if (not result[k]) then result[k] = {} end
                for vk,vv in pairs(v) do
                    if (vv ~= nil) then
                        result[k][vk] = vv
                    end
                end
            end
        end
    end
            
    if (result) then
        DEFAULT_CHAT_FRAME:AddMessage("Cartographer Trainer: Start rebuild.")
        for k,v in pairs(result) do
            if (v ~= nil) then
                for kv, vv in pairs(v) do
                    if (vv ~= nil) then
                        local entry = vv
                        if (not entry.name) then entry.name = kv end
                        entry.zone = k
                        
                        if (entry.x ~= 0) and (entry.y ~= 0) then
                            local note = {}
                            note.title = entry.name
                            note.icon = "Trainer"
                            note.info = "Trainer"
                            
                            if (entry.type) then
                                if (self.filters[self.lookups.filters[entry.type]] and self.icons[entry.type]) then note.icon = entry.type end
                                note.info = entry.type
                            end
                            
                            for zone, x_p, y_p, icon, creator, data in Cartographer_Notes:IterateNearbyNotes(entry.zone, entry.x, entry.y, (self.db.profile.noteRadius or 15), "Trainers", nil, true) do
                                if data.title == note.title then
                                    Cartographer_Notes:DeleteNote(zone, x_p, y_p)
                                end
                            end
                            
                            Cartographer_Notes:SetNote(entry.zone, entry.x, entry.y, note.icon, "Trainers", note)                            
                        end
                    end
                end
            end
        end
        self.db.faction.trainers = result
        DEFAULT_CHAT_FRAME:AddMessage("Cartographer Trainer: Rebuild complete.")
    end
end