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 BTS = AceLibrary("Babble-Tradeskill-2.2")
local BI = LibStub("LibBabble-Inventory-3.0"):GetLookupTable()
local BCT = LibStub("LibBabble-CreatureType-3.0"):GetLookupTable()

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,

	["Cartographer Trainer: Start rebuild."] = true,
	["Cartographer Trainer: Rebuild complete."] = true,

	-- Filters
	["Class"] = 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
	["Class"] = "직업",
} 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",

	["Cartographer Trainer: Start rebuild."] = "Cartographer Trainer: Starte Importieren.",
	["Cartographer Trainer: Rebuild complete."] = "Cartographer Trainer: Importieren abgeschlossen.",

	-- Filters
	["Class"] = "Klasse",

} end)

L:RegisterTranslations("zhTW", function() return {
	["Filter"] = "過濾",
	["Filter out trainers"] = "過濾訓練師",

	["Trainers"] = "訓練師",
	["Module description"] = "Cartographer 模組，紀錄訓練師位置。",

	["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"] = "重建插件預設訓練師資料",

	["Trainer"] = "訓練師",

	["Cartographer Trainer: Start rebuild."] = "Cartographer Trainer: 開始重建插件預設訓練師資料。",
	["Cartographer Trainer: Rebuild complete."] = "Cartographer Trainer: 完成重建插件預設訓練師資料。",

	-- Filters
	["Class"] = "職業導師",
} end)


L:RegisterTranslations("zhCN", function() return {
--Chinese Simplify Translated by 雪夜之狼@CN3 Feathermoon
	["Filter"] = "过滤",
	["Filter out trainers"] = "过滤训练师",

	["Trainers"] = "训练师",
	["Module description"] = "Cartographer 模块，记录训练师位置。",

	["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"] = "在小地图上显示训练师追踪图标",

	["Rebuild"] = "重建",
	["Rebuild trainers"] = "重建插件默认训练师资料",

	["Trainer"] = "训练师",

	["Cartographer Trainer: Start rebuild."] = "Cartographer Trainer: 开始重建插件预设训练师资料。",
	["Cartographer Trainer: Rebuild complete."] = "Cartographer Trainer: 完成重建插件预设训练师资料。",

	-- Filters
	["Class"] = "职业训练师",

} 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ño del icono",
	["Size of the icons on the map"] = "Tamaño 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",
	["Show minimap tracking icons"] = "Mostrar iconos en minimapa",
	["Show trainer tracking icons on the minimap"] = "Muestra los iconos de instructores en el minimapa",

--    ["Import"] = "Importar",
--    ["Import trainers"] = "Importar instructores",
	["Rebuild"] = "Reconstruir",
	["Rebuild trainers"] = "Reconstruir instructores",

	["Trainer"] = "Instructor",

	["Cartographer Trainer: Start rebuild."] = "Cartographer Instructores: Reconstrucción iniciada.",
	["Cartographer Trainer: Rebuild complete."] = "Cartographer Instructores: Reconstrucción completada.",

	-- Filters
	["Class"] = "Clase",
} end)

Cartographer_Trainers = Cartographer:NewModule("Trainers", "AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0")
Cartographer_Trainers.revision = tonumber(string.sub("$Revision: 72986 $", 12, -3))
Cartographer_Trainers.version = "r" .. Cartographer_Trainers.revision
Cartographer_Trainers.date = string.sub("$Date: 2008-05-07 12:34:37 -0400 (Wed, 07 May 2008) $", 8, 17)
Cartographer_Trainers:RegisterDB("Cartographer_TrainersDB")

Cartographer_Trainers.filters = {
    ["Tailoring"]	= GetSpellInfo(3908),
    ["Blacksmithing"]	= GetSpellInfo(2018),
    ["Fishing"] 	= GetSpellInfo(7620),
    ["Mining"] 		= GetSpellInfo(2575),
    ["First Aid"] 	= GetSpellInfo(3273),
    ["Alchemy"] 	= GetSpellInfo(2259),
    ["Cooking"] 	= GetSpellInfo(2550),
    ["Class"] 		= L["Class"],
    ["Pet"] 		= BI["Pet"],
    ["Demon"] 		= BCT["Demon"],
    ["Herbalism"] 	= GetSpellInfo(9134),
    ["Jewelcrafting"] 	= GetSpellInfo(25229),
    ["Engineering"] 	= GetSpellInfo(4036),
    ["Leatherworking"] 	= GetSpellInfo(2108),
    ["Riding"] 		= BTS["Riding"],
    ["Enchanting"] 	= GetSpellInfo(7411),
    ["Skinning"] 	= GetSpellInfo(8613),
}

Cartographer_Trainers.lookups = {
    ["filters"] = {
	[BT["Armor Crafter"]] 			= GetSpellInfo(2018),
	[BT["Artisan Alchemist"]] 		= GetSpellInfo(2259),
	[BT["Artisan Blacksmith"]] 		= GetSpellInfo(2018),
	[BT["Artisan Enchanter"]] 		= GetSpellInfo(7411),
	[BT["Artisan Engineer"]] 		= GetSpellInfo(4036),
	[BT["Artisan Leatherworker"]] 		= GetSpellInfo(2108),
	[BT["Artisan Tailor"]] 			= GetSpellInfo(3908),
	[BT["Bael'dun Chief Engineer"]] 	= GetSpellInfo(4036),
	[BT["Bat Handler"]] 			= BI["Pet"],
	[BT["Blacksmith"]] 			= GetSpellInfo(2018),
        [BT["Chief Engineer"]] 			= GetSpellInfo(4036),
        [BT["Cooking Trainer"]] 		= GetSpellInfo(2550),
	[BT["Demon Trainer"]] 			= BCT["Demon"],
        [BT["Druid Trainer"]] 			= L["Class"],
        [BT["Engineer"]] 			= GetSpellInfo(4036),
	[BT["Engineering Trainer"]] 		= GetSpellInfo(4036),
        [BT["Expert Alchemist"]] 		= GetSpellInfo(2259),
        [BT["Expert Blacksmith"]] 		= GetSpellInfo(2018),
        [BT["Expert Enchanter"]] 		= GetSpellInfo(7411),
        [BT["Expert Engineer"]] 		= GetSpellInfo(4036),
	[BT["Expert Jewelcrafter"]] 		= GetSpellInfo(25229),
        [BT["Expert Leatherworker"]] 		= GetSpellInfo(2108),
        [BT["Expert Tailor"]] 			= GetSpellInfo(3908),
        [BT["Explorers' League"]] 		= GetSpellInfo(2575),
	[BT["First Aid Trainer"]] 		= GetSpellInfo(3273),
        [BT["Fishing Trainer"]] 		= GetSpellInfo(7620),
	[BT["Goblin Engineering Trainer"]] 	= GetSpellInfo(4036),
        [BT["Grand Master Alchemist"]] 		= GetSpellInfo(2259),
        [BT["Grand Master Blacksmith"]] 	= GetSpellInfo(2018),
        [BT["Grand Master Enchanter"]] 		= GetSpellInfo(7411),
        [BT["Grand Master Engineer"]] 		= GetSpellInfo(4036),
        [BT["Grand Master Jewelcrafter"]] 	= GetSpellInfo(25229),
        [BT["Grand Master Leatherworker"]] 	= GetSpellInfo(2108),
	[BT["Grand Master Skinner"]] 		= GetSpellInfo(8613),
        [BT["Grand Master Tailor"]] 		= GetSpellInfo(3908),
        [BT["Head Eco-Dome Engineer"]] 		= GetSpellInfo(4036),
        [BT["Herbalism Trainer"]] 		= GetSpellInfo(9134),
        [BT["Horse Riding Instructor"]] 	= BTS["Riding"],
        [BT["Hunter Trainer"]] 			= L["Class"],
        [BT["Journeyman Alchemist"]] 		= GetSpellInfo(2259),
        [BT["Journeyman Alchemist Trainer"]] 	= GetSpellInfo(2259),
        [BT["Journeyman Blacksmith"]] 		= GetSpellInfo(2018),
        [BT["Journeyman Enchanter"]] 		= GetSpellInfo(7411),
        [BT["Journeyman Engineer"]] 		= GetSpellInfo(4036),
        [BT["Journeyman Jewelcrafter"]] 	= GetSpellInfo(25229),
        [BT["Journeyman Leatherworker"]] 	= GetSpellInfo(2108),
        [BT["Journeyman Tailor"]] 		= GetSpellInfo(3908),
        [BT["Kodo Riding Instructor"]] 		= BTS["Riding"],
        [BT["Leatherworking Trainer"]]		= GetSpellInfo(2108),
        [BT["Mage Trainer"]] 			= L["Class"],
        [BT["Master Alchemist"]] 		= GetSpellInfo(2259),
        [BT["Master Blacksmith"]] 		= GetSpellInfo(2018),
        [BT["Master Dragonscale Leatherworker"]] = GetSpellInfo(2108),
        [BT["Master Elemental Leatherworker"]] 	= GetSpellInfo(2108),
        [BT["Master Enchanter"]] 		= GetSpellInfo(7411),
        [BT["Master Engineer"]] 		= GetSpellInfo(4036),
        [BT["Master Gnome Engineer"]] 		= GetSpellInfo(4036),
        [BT["Master Goblin Engineer"]] 		= GetSpellInfo(4036),
        [BT["Master Jewelcrafter"]] 		= GetSpellInfo(25229),
        [BT["Master Leatherworking Trainer"]] 	= GetSpellInfo(2108),
        [BT["Master Leatherworker"]] 		= GetSpellInfo(2108),
        [BT["Master Shadoweave Tailor"]] 	= GetSpellInfo(3908),
        [BT["Master Tailor"]] 			= GetSpellInfo(3908),
        [BT["Master Tribal Leatherworker"]] 	= GetSpellInfo(2108),
        [BT["Mining Trainer"]] 			= GetSpellInfo(2575),
	[BT["Nightsaber Riding Instructor"]] 	= BTS["Riding"],
	[BT["Owl Trainer"]] 			= BI["Pet"],
        [BT["Paladin Trainer"]] 		= L["Class"],
	[BT["Pet Trainer"]] 			= BI["Pet"],
        [BT["Portal Trainer"]] 			= L["Class"],
        [BT["Priest Trainer"]] 			= L["Class"],
        [BT["Ram Riding Instructor"]] 		= BTS["Riding"],
	[BT["Raptor Handler"]] 			= BI["Pet"],
        [BT["Raptor Riding Trainer"]] 		= BTS["Riding"],
        [BT["Riding Instructor"]] 		= BTS["Riding"],
	[BT["Rogue Trainer"]] 			= L["Class"],
	[BT["Royal Apothecary Society"]] 	= GetSpellInfo(3273),
	[BT["Saber Handler"]] 			= BI["Pet"],
        [BT["Shaman Trainer"]] 			= L["Class"],
	[BT["Skinner"]] 			= GetSpellInfo(8613),
	[BT["Skinning Trainer"]] 		= GetSpellInfo(8613),
        [BT["Speciality Engineer"]]		= GetSpellInfo(4036),
        [BT["Superior Leatherworker"]] 		= GetSpellInfo(2108),
        [BT["Transportation Engineer"]] 	= GetSpellInfo(4036),
        [BT["Trauma Surgeon"]] 			= GetSpellInfo(3273),
        [BT["Tribal Leatherworking Trainer"]] 	= GetSpellInfo(2108),
        [BT["Unbalanced Engineer"]] 		= GetSpellInfo(4036),
        [BT["Undead Horse Riding Instructor"]] 	= BTS["Riding"],
	[BT["Warlock Trainer"]] 		= L["Class"],
        [BT["Warrior Trainer"]] 		= L["Class"],
	[BT["Weapon Master"]] 			= GetSpellInfo(2018),
        [BT["Wolf Riding Instructor"]] 		= BTS["Riding"],
    },
}

Cartographer_Trainers.icons = {
	["Trainer"] = {
		text = L["Trainer"],
		path = "Interface\\AddOns\\Cartographer_Trainers\\Artwork\\INV_Misc_Book_03",
		width = 14,
		height = 14
	},
	["Mage Trainer"] = {
	        text = BT["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 = 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.alpha = {
		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,
        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.01,
		bigStep = 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(L['Trainers'], self.db.faction.notes, self)
	else
		Cartographer:ToggleModuleActive(self, false)
	end

    -- if SchoolNotes then
	if (School) and (School:IsModuleActive(SchoolNotes)) 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(L['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"] = L["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), L["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, L["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(L["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 = L["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), L["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, L["Trainers"], note)
                        end
                    end
                end
            end
        end
        self.db.faction.trainers = result
        DEFAULT_CHAT_FRAME:AddMessage(L["Cartographer Trainer: Rebuild complete."])
    end
end