--------------------------------------------------------
-- Namespaces## Version: 2.6.8 ## Author: Discord: Cam#7332
--------------------------------------------------------
local MCLL = {}
if GetLocale() == "zhCN" then
    MCLL["Addons"] = "|cff69ccf0[藏品]|r坐骑收集"
    MCLL["lnuizuoqi"] = "收集者的悬赏"
    MCLL["Achievement"] = "成就"
    MCLL["Adventures"] = "冒险"
    MCLL["Ahead of the Curve"] = "引领潮流"
    MCLL["Alchemy"] = "炼金术"
    MCLL["Alliance"] = "联盟"
    MCLL["Allied Races"] = "同盟种族"
    MCLL["Archeology"] = "考古学"
    MCLL["Arena Mounts"] = "角斗士坐骑"
    MCLL["Argent Tournament"] = "银色锦标赛"
    MCLL["Assault: Uldum"] = "突袭：奥丹姆"
    MCLL["Assault: Vale of Eternal Blossoms"] = "突袭: 锦绣谷"
    MCLL["Azeroth Choppers"] = "艾泽拉斯机车"
    MCLL["BFA"] = "争霸艾泽拉斯"
    MCLL["BMAH"] = "黑市拍卖行"
    MCLL["Battle for Azeroth"] = "争霸艾泽拉斯"
    MCLL["Blacksmith"] = "锻造"
    MCLL["Blizzard Store"] = "游戏商城"
    MCLL["Blood Elf"] = "血精灵"
    MCLL["Brawler's Guild"] = "搏击俱乐部"
    MCLL["BrewFest"] = "美酒节"
    MCLL["Brewfest"] = "美酒节"
    MCLL["CATA"] = "大地的裂变"
    MCLL["Cataclysm"] = "大地的裂变"
    MCLL["Cenarion Expedition"] = "塞纳里奥远征队"
    MCLL["Challenge Mode"] = "黄金挑战"
    MCLL["Class"] = "职业"
    MCLL["Classic"] = "经典旧世"
    MCLL["Collector's Edition"] = "典藏版"
    MCLL["Covenant Feature"] = "盟约特色"
    MCLL["Daily Activities"] = "日常活动"
    MCLL["Dark Iron Dwarf"] = "黑铁矮人"
    MCLL["Darkmoon Faire"] = "暗月马戏团"
    MCLL["Delves"] = "安德麦财阀"
    MCLL["Demon Hunter"] = "恶魔猎手"
    MCLL["Diablo IV"] = "暗黑破坏神IV"
    MCLL["Dracthyr"] = "龙希尔"
    MCLL["Draenei"] = "德莱尼"
    MCLL["Dragon Riding"] = "驭龙术"
    MCLL["Dragonflight"] = "巨龙时代"
    MCLL["Dubloons"] = "达布隆币"
    MCLL["Dungeon"] = "地下城"
    MCLL["Dungeon Drop"] = "地下城掉落"
    MCLL["Dwarf"] = "矮人"
    MCLL["Engineering"] = "工程学"
    MCLL["Exalted Reputations"] = "声望崇拜"
    MCLL["Fishing"] = "钓鱼"
    MCLL["Fishing Shack"] = "要塞渔夫小屋"
    MCLL["Garrison"] = "要塞"
    MCLL["Gladiator"] = "角斗士"
    MCLL["Gnome"] = "侏儒"
    MCLL["Goblin"] = "地精"
    MCLL["Golden Lotus"] = "金莲教"
    MCLL["Guild Vendor"] = "公会商人"
    MCLL["Halaa"] = "哈兰"
    MCLL["Hallow's End"] = "万圣节"
    MCLL["Hearthstone"] = "炉石传说"
    MCLL["Heirlooms"] = "传家宝"
    MCLL["Honor"] = "荣誉"
    MCLL["Horde"] = "部落"
    MCLL["Human"] = "人类"
    MCLL["Island Expedition"] = "海岛探险"
    MCLL["Jewelcrafting"] = "珠宝加工"
    MCLL["Kun-Lai Vendor"] = "昆莱山商人"
    MCLL["Kurenai/The Mag'har"] = "库雷尼/玛格汉"
    MCLL["Kyrian"] = "格里恩"
    MCLL["LEGION"] = "军团再临"
    MCLL["Leatherworking"] = "制皮"
    MCLL["Legion"] = "军团再临"
    MCLL["Love is in the Air"] = "情人节"
    MCLL["Lunar Festival"] = "春节"
    MCLL["MOP"] = "熊猫人之谜"
    MCLL["Mark of Honor"] = "荣耀印记"
    MCLL["Maw Assaults"] = "噬渊突袭"
    MCLL["Medals"] = "服役勋章"
    MCLL["Missions"] = "任务"
    MCLL["Mists of Pandaria"] = "熊猫人之谜"
    MCLL["Mount Collection"] = "坐骑收藏"
    MCLL["Mythic +"] = "史诗钥石+"
    MCLL["Necrolords"] = "通灵领主"
    MCLL["Netherwing"] = "灵翼之龙"
    MCLL["Night Elf"] = "暗夜精灵"
    MCLL["Night Fae"] = "法夜"
    MCLL["Noblegarden"] = "复活节"
    MCLL["Old Anniversary Mounts"] = "旧版庆典坐骑"
    MCLL["Old Promotion Mounts"] = "旧版促销坐骑"
    MCLL["Oozing Necroray Egg"] = "渗出粘液的通灵鳐之卵"
    MCLL["Orc"] = "兽人"
    MCLL["Order of the Cloud Serpent"] = "云端翔龙骑士团"
    MCLL["Original Epic Mounts"] = "旧版史诗坐骑"
    MCLL["Other"] = "其他"
    MCLL["Overview"] = "概览"
    MCLL["PVP"] = "PVP"
    MCLL["Paladin"] = "圣骑士"
    MCLL["Pandaren"] = "熊猫人"
    MCLL["Paragon Reputation"] = "巅峰声望"
    MCLL["Pinned"] = "标记"
    MCLL["Plunderstorm"] = "霸业风暴"
    MCLL["Pre-Launch Event"] = "前夕事件"
    MCLL["Primal Eggs"] = "原始恐龙蛋"
    MCLL["Product Promotion"] = "产品推广"
    MCLL["Profession"] = "专业技能"
    MCLL["Professions"] = "专业技能"
    MCLL["Promotion"] = "促销"
    MCLL["Protoform Synthesis"] = "原生体合成"
    MCLL["Quest"] = "任务"
    MCLL["Raid"] = "团队副本"
    MCLL["Raid Drop"] = "团队副本掉落"
    MCLL["Rare Drops"] = "稀有掉落"
    MCLL["Rare Spawn"] = "稀有掉落"
    MCLL["Recruit-A-Friend"] = "战友招募"
    MCLL["Remix MOP"] = "幻境新生: 潘达利亚"
    MCLL["Renown"] = "名望"
    MCLL["Reputation"] = "声望"
    MCLL["Riddle"] = "解密"
    MCLL["Riddles"] = "解密"
    MCLL["SL"] = "暗影国度"
    MCLL["Scroll of Resurrection"] = "复活卷轴"
    MCLL["Secret"] = "解密"
    MCLL["Sha'tari Skyguard"] = "沙塔尔天空卫队"
    MCLL["Shado-Pan"] = "影踪派"
    MCLL["Shadowlands"] = "暗影国度"
    MCLL["Siren Island"] = "海妖岛"
    MCLL["Stables"] = "要塞兽栏"
    MCLL["TBC"] = "燃烧的远征"
    MCLL["Tailoring"] = "裁缝"
    MCLL["Talon's Vengeance"] = "复仇之爪"
    MCLL["Tauren"] = "牛头人"
    MCLL["The Burning Crusade"] = "燃烧的远征"
    MCLL["The Tillers"] = "阡陌客"
    MCLL["The War Within"] = "地心之战"
    MCLL["Timeless Isle"] = "永恒岛"
    MCLL["Timewalking"] = "时空漫游"
    MCLL["Timewalking Alterac Valley"] = "时空漫游: 奥特兰克山谷"
    MCLL["Tinkering"] = "制作"
    MCLL["Torghast"] = "托加斯特"
    MCLL["Tormentors"] = "折磨者"
    MCLL["Toy"] = "玩具"
    MCLL["Trading Card Game"] = "集换卡牌游戏"
    MCLL["Trading Post"] = "商栈"
    MCLL["Treasures"] = "宝藏"
    MCLL["Troll"] = "巨魔"
    MCLL["Undead"] = "亡灵"
    MCLL["Undermine"] = "安德麦"
    MCLL["Unobtainable"] = "绝版"
    MCLL["Unobtainable Raid Mounts"] = "绝版团本坐骑"
    MCLL["Vanilla"] = "经典旧世"
    MCLL["Vendor"] = "商人"
    MCLL["Venthyr"] = "温西尔"
    MCLL["Vicious Saddle"] = "邪气鞍座"
    MCLL["Visions"] = "惊魂幻象"
    MCLL["WOD"] = "德拉诺之王"
    MCLL["WOTLK"] = "巫妖王之怒"
    MCLL["Warcraft III Reforged"] = "魔兽争霸III：重制版"
    MCLL["Warfront: Arathi"] = "战争前线: 阿拉希"
    MCLL["Warfront: Darkshore"] = "战争前线：黑海岸"
    MCLL["Warlock"] = "术士"
    MCLL["Warlords of Draenor"] = "德拉诺之王"
    MCLL["Winter Veil"] = "冬幕节"
    MCLL["WoW Anniversary Mounts"] = "魔兽世界周年庆"
    MCLL["WoW Classic"] = "魔兽世界: 经典怀旧服"
    MCLL["Worgen"] = "狼人"
    MCLL["World Boss"] = "世界首领"
    MCLL["World Events"] = "世界事件"
    MCLL["WorldEvents"] = "世界事件"
    MCLL["Wrath of the Lich King"] = "巫妖王之怒"
    MCLL["Zone"] = "区域"
    MCLL["Incursion"] = "突袭"
    MCLL["Horrific Visions"] = "恐怖幻象"
    MCLL["Ashran"] = "阿什兰"
    MCLL["Mists of Pandaria Remix"] = "熊猫人之谜重置版"
    
    ------ setting panel ------
    MCLL["Ctrl + Right Click to pin uncollected mounts"] = "Ctrl + 右键 标记/取消标记坐骑"
    MCLL["Mount Collection Log Settings"] = "Mount Collection Log 设置"
    MCLL["Main Window Options"] = "主界面选项"
    MCLL["Main Window Opacity"] = "主界面透明度"
    MCLL["Changes the opacity of the main window"] = "更改主界面透明度"
    MCLL["Reset Opacity"] = "重置透明度"
    MCLL["Reset to default opacity"] = "重置为默认透明度"
    MCLL["Progress Bar Settings"] = "进度条设置"
    MCLL["Statusbar Texture"] = "进度条材质"
    MCLL["Set the statusbar texture."] = "设置进度条材质."
    MCLL["Reset Texture"] = "重置材质"
    MCLL["Reset to default texture"] = "重置为默认材质"
    MCLL["Progress Bar (<33%)"] = "进度条 (<33%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 33%"] = "设置进度条颜色 (收集进度<33%)"
    MCLL["Progress Bar (<66%)"] = "进度条 (<66%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 66%"] = "设置进度条颜色 (收集进度<66%)"
    MCLL["Progress Bar (<100%)"] = "进度条 (<100%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 100%"] = "设置进度条颜色 (收集进度<100%)"
    MCLL["Progress Bar (100%)"] = "进度条 (=100%)"
    MCLL["Set the progress bar colors to be shown when all mounts are collected"] = "设置进度条颜色 (收集所有坐骑)"
    MCLL["Reset Colors"] = "重置颜色"
    MCLL["Reset to default colors"] = "重置为默认颜色"
    MCLL["Unobtainable Settings"] = "绝版设置"
    MCLL["Hide Unobtainable from overview"] = "隐藏绝版"
    MCLL["Hide Unobtainable mounts from the overview."] = "在总览中隐藏绝版坐骑"
    MCLL["Show Minimap Icon"] = "显示小地图按钮"
    MCLL["Toggle the display of the Minimap Icon."] = "切换显示小地图按钮"
    MCLL["Reset Settings"] = "重置设置"
    MCLL["Reset to default settings"] = "重置为默认设置"
    MCLL["Hide Collected Mounts"] = "隐藏已收集的坐骑"
    MCLL["If enabled, collected mounts will not be shown in the list at all. Requires UI reload."] = "启用后，已收集的坐骑将不会显示在列表中。需要重载界面。"
    MCLL["Changing this setting requires a UI reload. Reload now?"] = "更改此设置需要重载界面。现在重载吗？"
    MCLL["YES"] = "是"
    MCLL["NO"] = "否"
    MCLL["Layout Settings"] = "布局设置"
    MCLL["Mounts Per Row"] = "每行坐骑数"
    MCLL["Set the number of mounts to display per row in the mount grid. Requires UI reload."] = "设置坐骑网格中每行显示的坐骑数量。需要重载界面。"
    MCLL["Use Blizzard Theme"] = "使用暴雪主题"
    MCLL["If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."] = "启用后，插件将使用暴雪默认的界面主题。需要重载界面。"
    MCLL["Search Results"] = "搜索结果"
    MCLL["Search mounts..."] = "搜索坐骑..."
    MCLL["Mount Collection Log"] = "坐骑收集日志"
    MCLL["Clear Search"] = "清除搜索"
    MCLL["Pin Instructions Text"] = "|cffFF8800|TInterface\\GossipFrame\\AvailableQuestIcon:0:0:0:0:32:32:0:32:0:32|t Ctrl + 右键|r 收藏/取消收藏坐骑"
    MCLL["Sections"] = "分类"
elseif GetLocale() == "zhTW" then
    MCLL["Addons"] = "|cff69ccf0[藏品]|r坐骑收集"
    MCLL["Achievement"] = "成就"
    MCLL["Adventures"] = "冒險"
    MCLL["Ahead of the Curve"] = "領先群雄"
    MCLL["Alchemy"] = "鍊金術"
    MCLL["Alliance"] = "聯盟"
    MCLL["Allied Races"] = "同盟種族"
    MCLL["Archeology"] = "考古學"
    MCLL["Arena Mounts"] = "競技場坐騎"
    MCLL["Argent Tournament"] = "銀白聯賽"
    MCLL["Assault: Uldum"] = "突襲：奧丹姆"
    MCLL["Assault: Vale of Eternal Blossoms"] = "突襲：恆春谷"
    MCLL["Azeroth Choppers"] = "艾澤拉斯重機"
    MCLL["BFA"] = "決戰艾澤拉斯"
    MCLL["BMAH"] = "黑市拍賣場"
    MCLL["Battle for Azeroth"] = "決戰艾澤拉斯"
    MCLL["Blacksmith"] = "鍛造"
    MCLL["Blizzard Store"] = "暴雪商店"
    MCLL["Blood Elf"] = "血精靈"
    MCLL["Brawler's Guild"] = "鬥陣俱樂部"
    MCLL["BrewFest"] = "啤酒節"
    MCLL["Brewfest"] = "啤酒節"
    MCLL["CATA"] = "大地的裂變"
    MCLL["Cataclysm"] = "大地的裂變"
    MCLL["Cenarion Expedition"] = "塞納里奧遠征隊"
    MCLL["Challenge Mode"] = "挑戰模式"
    MCLL["Class"] = "職業"
    MCLL["Classic"] = "經典舊世"
    MCLL["Collector's Edition"] = "典藏版"
    MCLL["Covenant Feature"] = "誓盟特色"
    MCLL["Daily Activities"] = "日常活動"
    MCLL["Dark Iron Dwarf"] = "黑鐵矮人"
    MCLL["Darkmoon Faire"] = "暗月馬戲團"
    MCLL["Delves"] = "地心探險"
    MCLL["Demon Hunter"] = "惡魔獵人"
    MCLL["Diablo IV"] = "暗黑破壞神IV"
    MCLL["Dracthyr"] = "半龍人"
    MCLL["Draenei"] = "德萊尼"
    MCLL["Dragon Riding"] = "飛龍騎術"
    MCLL["Dragonflight"] = "巨龍崛起"
    MCLL["Dubloons"] = "海員古幣"
    MCLL["Dungeon"] = "地城"
    MCLL["Dungeon Drop"] = "地城掉落"
    MCLL["Dwarf"] = "矮人"
    MCLL["Engineering"] = "工程學"
    MCLL["Exalted Reputations"] = "崇拜聲望"
    MCLL["Fishing"] = "釣魚"
    MCLL["Fishing Shack"] = "釣魚小屋"
    MCLL["Garrison"] = "要塞"
    MCLL["Gladiator"] = "角鬥士"
    MCLL["Gnome"] = "侏儒"
    MCLL["Goblin"] = "哥布林"
    MCLL["Golden Lotus"] = "金蓮會"
    MCLL["Guild Vendor"] = "公會商人"
    MCLL["Halaa"] = "哈剌"
    MCLL["Hallow's End"] = "萬鬼節"
    MCLL["Hearthstone"] = "爐石戰記"
    MCLL["Heirlooms"] = "傳家寶"
    MCLL["Honor"] = "榮譽"
    MCLL["Horde"] = "部落"
    MCLL["Human"] = "人類"
    MCLL["Island Expedition"] = "海嶼遠征"
    MCLL["Jewelcrafting"] = "珠寶設計"
    MCLL["Kun-Lai Vendor"] = "崑萊峰商人"
    MCLL["Kurenai/The Mag'har"] = "卡爾奈/瑪格哈"
    MCLL["Kyrian"] = "琪瑞安"
    MCLL["LEGION"] = "軍臨天下"
    MCLL["Leatherworking"] = "製皮"
    MCLL["Legion"] = "軍臨天下"
    MCLL["Love is in the Air"] = "愛就在身邊"
    MCLL["Lunar Festival"] = "農曆新年"
    MCLL["MOP"] = "潘達利亞之謎"
    MCLL["Mark of Honor"] = "榮譽印記"
    MCLL["Maw Assaults"] = "淵喉突襲"
    MCLL["Medals"] = "服役勳章"
    MCLL["Missions"] = "任務"
    MCLL["Mists of Pandaria"] = "潘達利亞之謎"
    MCLL["Mount Collection"] = "坐騎收藏"
    MCLL["Mythic +"] = "傳奇+"
    MCLL["Necrolords"] = "死靈領主"
    MCLL["Netherwing"] = "虛空之翼"
    MCLL["Night Elf"] = "夜精靈"
    MCLL["Night Fae"] = "暗夜妖精"
    MCLL["Noblegarden"] = "貴族花園"
    MCLL["Old Anniversary Mounts"] = "舊版周年坐騎"
    MCLL["Old Promotion Mounts"] = "舊版促銷坐騎"
    MCLL["Oozing Necroray Egg"] = "黏黏的死靈魟魚卵"
    MCLL["Orc"] = "獸人"
    MCLL["Order of the Cloud Serpent"] = "雲蛟衛"
    MCLL["Original Epic Mounts"] = "舊版史詩坐騎"
    MCLL["Other"] = "其他"
    MCLL["Overview"] = "總覽"
    MCLL["PVP"] = "PvP"
    MCLL["Paladin"] = "聖騎士"
    MCLL["Pandaren"] = "熊貓人"
    MCLL["Paragon Reputation"] = "巔峰聲望"
    MCLL["Pinned"] = "標記"
    MCLL["Plunderstorm"] = "掠鴉行動"
    MCLL["Pre-Launch Event"] = "前夕事件"
    MCLL["Primal Eggs"] = "原始蛋"
    MCLL["Product Promotion"] = "產品推廣"
    MCLL["Profession"] = "專業技能"
    MCLL["Professions"] = "專業技能"
    MCLL["Promotion"] = "促銷"
    MCLL["Protoform Synthesis"] = "原型合成"
    MCLL["Quest"] = "任務"
    MCLL["Raid"] = "團隊副本"
    MCLL["Raid Drop"] = "團隊副本掉落"
    MCLL["Rare Drops"] = "稀有掉落"
    MCLL["Rare Spawn"] = "稀有怪"
    MCLL["Recruit-A-Friend"] = "招募好友"
    MCLL["Remix MOP"] = "潘達利亞：幻境新生"
    MCLL["Renown"] = "名望"
    MCLL["Reputation"] = "聲望"
    MCLL["Riddle"] = "謎題"
    MCLL["Riddles"] = "謎題"
    MCLL["SL"] = "暗影之境"
    MCLL["Scroll of Resurrection"] = "復活卷軸"
    MCLL["Secret"] = "祕密"
    MCLL["Sha'tari Skyguard"] = "薩塔禦天者"
    MCLL["Shado-Pan"] = "影潘"
    MCLL["Shadowlands"] = "暗影之境"
    MCLL["Siren Island"] = "海妖島"
    MCLL["Stables"] = "獸欄"
    MCLL["TBC"] = "燃燒的遠征"
    MCLL["Tailoring"] = "裁縫"
    MCLL["Talon's Vengeance"] = "復仇之爪"
    MCLL["Tauren"] = "牛頭人"
    MCLL["The Burning Crusade"] = "燃燒的遠征"
    MCLL["The Tillers"] = "耕者工會"
    MCLL["The War Within"] = "地心之戰"
    MCLL["Timeless Isle"] = "永恆島"
    MCLL["Timewalking"] = "時光漫遊"
    MCLL["Timewalking Alterac Valley"] = "時光漫遊：奧特蘭克山谷"
    MCLL["Tinkering"] = "廢料場工程"
    MCLL["Torghast"] = "托迦司"
    MCLL["Tormentors"] = "折磨者"
    MCLL["Toy"] = "玩具"
    MCLL["Trading Card Game"] = "集換式卡牌遊戲"
    MCLL["Trading Post"] = "商棧"
    MCLL["Treasures"] = "寶藏"
    MCLL["Troll"] = "食人妖"
    MCLL["Undead"] = "不死族"
    MCLL["Undermine"] = "幽坑城"
    MCLL["Unobtainable"] = "絕版"
    MCLL["Unobtainable Raid Mounts"] = "絕版團隊副本坐騎"
    MCLL["Vanilla"] = "經典舊世"
    MCLL["Vendor"] = "商人"
    MCLL["Venthyr"] = "汎希爾"
    MCLL["Vicious Saddle"] = "邪惡戰騎"
    MCLL["Visions"] = "恐怖幻象"
    MCLL["WOD"] = "德拉諾之霸"
    MCLL["WOTLK"] = "巫妖王之怒"
    MCLL["Warcraft III Reforged"] = "魔獸爭霸III：重製版"
    MCLL["Warfront: Arathi"] = "戰爭前線：阿拉希"
    MCLL["Warfront: Darkshore"] = "戰爭前線：黑海岸"
    MCLL["Warlock"] = "術士"
    MCLL["Warlords of Draenor"] = "德拉諾之霸"
    MCLL["Winter Veil"] = "冬幕節"
    MCLL["WoW Anniversary Mounts"] = "魔獸世界周年慶"
    MCLL["WoW Classic"] = "魔獸世界：經典版"
    MCLL["Worgen"] = "狼人"
    MCLL["World Boss"] = "世界首領"
    MCLL["World Events"] = "世界事件"
    MCLL["WorldEvents"] = "世界事件"
    MCLL["Wrath of the Lich King"] = "巫妖王之怒"
    MCLL["Zone"] = "區域"
    MCLL["Incursion"] = "突襲"
    MCLL["Horrific Visions"] = "恐怖幻象"
    MCLL["Ashran"] = "阿斯蘭"
    MCLL["Mists of Pandaria Remix"] = "潘達利亞之謎重制版"

    ------ setting panel ------
    MCLL["Ctrl + Right Click to pin uncollected mounts"] = "Ctrl + 右鍵 標記未收藏的坐騎"
    MCLL["Mount Collection Log Settings"] = "坐騎收集日誌設定"
    MCLL["Main Window Options"] = "主視窗選項"
    MCLL["Main Window Opacity"] = "主視窗透明度"
    MCLL["Changes the opacity of the main window"] = "更改主視窗透明度"
    MCLL["Reset Opacity"] = "重設透明度"
    MCLL["Reset to default opacity"] = "重設為預設透明度"
    MCLL["Progress Bar Settings"] = "進度條設定"
    MCLL["Statusbar Texture"] = "進度條材質"
    MCLL["Set the statusbar texture."] = "設定進度條材質。"
    MCLL["Reset Texture"] = "重設材質"
    MCLL["Reset to default texture"] = "重設為預設材質"
    MCLL["Progress Bar (<33%)"] = "進度條 (<33%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 33%"] = "設定進度條顏色（收集進度<33%）"
    MCLL["Progress Bar (<66%)"] = "進度條 (<66%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 66%"] = "設定進度條顏色（收集進度<66%）"
    MCLL["Progress Bar (<100%)"] = "進度條 (<100%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 100%"] = "設定進度條顏色（收集進度<100%）"
    MCLL["Progress Bar (100%)"] = "進度條 (=100%)"
    MCLL["Set the progress bar colors to be shown when all mounts are collected"] = "設定進度條顏色（收集所有坐騎）"
    MCLL["Reset Colors"] = "重設顏色"
    MCLL["Reset to default colors"] = "重設為預設顏色"
    MCLL["Unobtainable Settings"] = "絕版設定"
    MCLL["Hide Unobtainable from overview"] = "總覽中隱藏絕版"
    MCLL["Hide Unobtainable mounts from the overview."] = "在總覽中隱藏絕版坐騎"
    MCLL["Show Minimap Icon"] = "顯示小地圖按鈕"
    MCLL["Toggle the display of the Minimap Icon."] = "切換顯示小地圖按鈕"
    MCLL["Reset Settings"] = "重設設定"
    MCLL["Reset to default settings"] = "重設為預設設定"
    MCLL["Hide Collected Mounts"] = "隱藏已收集的坐騎"
    MCLL["If enabled, collected mounts will not be shown in the list at all. Requires UI reload."] = "啟用後，已收集的坐騎將不會顯示在列表中。需要重新載入介面。"
    MCLL["Changing this setting requires a UI reload. Reload now?"] = "更改此設定需要重新載入介面。現在重新載入嗎？"
    MCLL["YES"] = "是"
    MCLL["NO"] = "否"
    MCLL["Layout Settings"] = "佈局設定"
    MCLL["Mounts Per Row"] = "每行坐騎數"
    MCLL["Set the number of mounts to display per row in the mount grid. Requires UI reload."] = "設定坐騎網格中每行顯示的坐騎數量。需要重新載入介面。"
    MCLL["Use Blizzard Theme"] = "使用暴雪主題"
    MCLL["If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."] = "啟用後，插件將使用暴雪預設的介面主題。需要重新載入介面。"
    MCLL["Search Results"] = "搜尋結果"
    MCLL["Search mounts..."] = "搜尋坐騎..."
    MCLL["Mount Collection Log"] = "坐騎收集日誌"
    MCLL["Clear Search"] = "清除搜尋"
    MCLL["Use Blizzard Theme"] = "使用暴雪主題"
    MCLL["If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."] = "啟用後，附加元件將使用暴雪的預設UI主題。需要重新載入介面。"
    MCLL["Sections"] = "分類"
    MCLL["MCL | Mount Collection Log"] = "MCL | 坐騎收集日誌"
    MCLL["|cff00CCFFMount Collection Log Commands:\n|cffFF0000Show:|cffFFFFFF Shows your mount collection log\n|cffFF0000Icon:|cffFFFFFF Toggles the minimap icon\n|cffFF0000Config:|cffFFFFFF Opens the settings\n|cffFF0000Help:|cffFFFFFF Shows commands"] = "|cff00CCFF坐騎收集日誌指令:\n|cffFF0000Show:|cffFFFFFF 顯示你的坐騎收集日誌\n|cffFF0000Icon:|cffFFFFFF 切換小地圖按鈕\n|cffFF0000Config:|cffFFFFFF 開啟設定選項\n|cffFF0000Help:|cffFFFFFF 顯示指令"
    MCLL["Pin Instructions Text"] = "|cffFF8800|TInterface\\GossipFrame\\AvailableQuestIcon:0:0:0:0:32:32:0:32:0:32|t Ctrl + 右鍵|r 收藏未獲得的坐騎"
else
    MCLL["Addons"] = "Mount Collection log"
    MCLL["Achievement"] = "Achievement"
    MCLL["Adventures"] = "Adventures"
    MCLL["Ahead of the Curve"] = "Ahead of the Curve"
    MCLL["Alchemy"] = "Alchemy"
    MCLL["Alliance"] = "Alliance"
    MCLL["Allied Races"] = "Allied Races"
    MCLL["Archeology"] = "Archeology"
    MCLL["Arena Mounts"] = "Arena Mounts"
    MCLL["Argent Tournament"] = "Argent Tournament"
    MCLL["Assault: Uldum"] = "Assault: Uldum"
    MCLL["Assault: Vale of Eternal Blossoms"] = "Assault: Vale of Eternal Blossoms"
    MCLL["Azeroth Choppers"] = "Azeroth Choppers"
    MCLL["BFA"] = "BFA"
    MCLL["BMAH"] = "BMAH"
    MCLL["Battle for Azeroth"] = "Battle for Azeroth"
    MCLL["Blacksmith"] = "Blacksmith"
    MCLL["Blizzard Store"] = "Blizzard Store"
    MCLL["Blood Elf"] = "Blood Elf"
    MCLL["Brawler's Guild"] = "Brawler's Guild"
    MCLL["BrewFest"] = "BrewFest"
    MCLL["Brewfest"] = "Brewfest"
    MCLL["CATA"] = "CATA"
    MCLL["Cataclysm"] = "Cataclysm"
    MCLL["Cenarion Expedition"] = "Cenarion Expedition"
    MCLL["Challenge Mode"] = "Challenge Mode"
    MCLL["Class"] = "Class"
    MCLL["Classic"] = "Classic"
    MCLL["Collector's Edition"] = "Collector's Edition"
    MCLL["Covenant Feature"] = "Covenant Feature"
    MCLL["Daily Activities"] = "Daily Activities"
    MCLL["Dark Iron Dwarf"] = "Dark Iron Dwarf"
    MCLL["Darkmoon Faire"] = "Darkmoon Faire"
    MCLL["Delves"] = "Delves"
    MCLL["Demon Hunter"] = "Demon Hunter"
    MCLL["Diablo IV"] = "Diablo IV"
    MCLL["Dracthyr"] = "Dracthyr"
    MCLL["Draenei"] = "Draenei"
    MCLL["Dragon Riding"] = "Dragon Riding"
    MCLL["Dragonflight"] = "Dragonflight"
    MCLL["Dubloons"] = "Dubloons"
    MCLL["Dungeon"] = "Dungeon"
    MCLL["Dungeon Drop"] = "Dungeon Drop"
    MCLL["Dwarf"] = "Dwarf"
    MCLL["Engineering"] = "Engineering"
    MCLL["Exalted Reputations"] = "Exalted Reputations"
    MCLL["Fishing"] = "Fishing"
    MCLL["Fishing Shack"] = "Fishing Shack"
    MCLL["Garrison"] = "Garrison"
    MCLL["Gladiator"] = "Gladiator"
    MCLL["Gnome"] = "Gnome"
    MCLL["Goblin"] = "Goblin"
    MCLL["Golden Lotus"] = "Golden Lotus"
    MCLL["Guild Vendor"] = "Guild Vendor"
    MCLL["Halaa"] = "Halaa"
    MCLL["Hallow's End"] = "Hallow's End"
    MCLL["Hearthstone"] = "Hearthstone"
    MCLL["Heirlooms"] = "Heirlooms"
    MCLL["Honor"] = "Honor"
    MCLL["Horde"] = "Horde"
    MCLL["Human"] = "Human"
    MCLL["Island Expedition"] = "Island Expedition"
    MCLL["Jewelcrafting"] = "Jewelcrafting"
    MCLL["Kun-Lai Vendor"] = "Kun-Lai Vendor"
    MCLL["Kurenai/The Mag'har"] = "Kurenai/The Mag'har"
    MCLL["Kyrian"] = "Kyrian"
    MCLL["LEGION"] = "LEGION"
    MCLL["Leatherworking"] = "Leatherworking"
    MCLL["Legion"] = "Legion"
    MCLL["Love is in the Air"] = "Love is in the Air"
    MCLL["Lunar Festival"] = "Lunar Festival"
    MCLL["MOP"] = "MOP"
    MCLL["Mark of Honor"] = "Mark of Honor"
    MCLL["Maw Assaults"] = "Maw Assaults"
    MCLL["Medals"] = "Medals"
    MCLL["Missions"] = "Missions"
    MCLL["Mists of Pandaria"] = "Mists of Pandaria"
    MCLL["Mount Collection"] = "Mount Collection"
    MCLL["Mythic +"] = "Mythic +"
    MCLL["Necrolords"] = "Necrolords"
    MCLL["Netherwing"] = "Netherwing"
    MCLL["Night Elf"] = "Night Elf"
    MCLL["Night Fae"] = "Night Fae"
    MCLL["Noblegarden"] = "Noblegarden"
    MCLL["Old Anniversary Mounts"] = "Old Anniversary Mounts"
    MCLL["Old Promotion Mounts"] = "Old Promotion Mounts"
    MCLL["Oozing Necroray Egg"] = "Oozing Necroray Egg"
    MCLL["Orc"] = "Orc"
    MCLL["Order of the Cloud Serpent"] = "Order of the Cloud Serpent"
    MCLL["Original Epic Mounts"] = "Original Epic Mounts"
    MCLL["Other"] = "Other"
    MCLL["Overview"] = "Overview"
    MCLL["PVP"] = "PVP"
    MCLL["Paladin"] = "Paladin"
    MCLL["Pandaren"] = "Pandaren"
    MCLL["Paragon Reputation"] = "Paragon Reputation"
    MCLL["Pinned"] = "Pinned"
    MCLL["Plunderstorm"] = "Plunderstorm"
    MCLL["Pre-Launch Event"] = "Pre-Launch Event"
    MCLL["Primal Eggs"] = "Primal Eggs"
    MCLL["Product Promotion"] = "Product Promotion"
    MCLL["Profession"] = "Profession"
    MCLL["Professions"] = "Professions"
    MCLL["Promotion"] = "Promotion"
    MCLL["Protoform Synthesis"] = "Protoform Synthesis"
    MCLL["Quest"] = "Quest"
    MCLL["Raid"] = "Raid"
    MCLL["Raid Drop"] = "Raid Drop"
    MCLL["Rare Drops"] = "Rare Drops"
    MCLL["Rare Spawn"] = "Rare Spawn"
    MCLL["Recruit-A-Friend"] = "Recruit-A-Friend"
    MCLL["Remix MOP"] = "Remix MOP"
    MCLL["Renown"] = "Renown"
    MCLL["Reputation"] = "Reputation"
    MCLL["Riddle"] = "Riddle"
    MCLL["Riddles"] = "Riddles"
    MCLL["SL"] = "SL"
    MCLL["Scroll of Resurrection"] = "Scroll of Resurrection"
    MCLL["Secret"] = "Secret"
    MCLL["Sha'tari Skyguard"] = "Sha'tari Skyguard"
    MCLL["Shado-Pan"] = "Shado-Pan"
    MCLL["Shadowlands"] = "Shadowlands"
    MCLL["Siren Island"] = "Siren Island"
    MCLL["Stables"] = "Stables"
    MCLL["TBC"] = "TBC"
    MCLL["Tailoring"] = "Tailoring"
    MCLL["Talon's Vengeance"] = "Talon's Vengeance"
    MCLL["Tauren"] = "Tauren"
    MCLL["The Burning Crusade"] = "The Burning Crusade"
    MCLL["The Tillers"] = "The Tillers"
    MCLL["The War Within"] = "The War Within"
    MCLL["Timeless Isle"] = "Timeless Isle"
    MCLL["Timewalking"] = "Timewalking"
    MCLL["Timewalking Alterac Valley"] = "Timewalking Alterac Valley"
    MCLL["Tinkering"] = "Tinkering"
    MCLL["Torghast"] = "Torghast"
    MCLL["Tormentors"] = "Tormentors"
    MCLL["Toy"] = "Toy"
    MCLL["Trading Card Game"] = "Trading Card Game"
    MCLL["Trading Post"] = "Trading Post"
    MCLL["Treasures"] = "Treasures"
    MCLL["Troll"] = "Troll"
    MCLL["Undead"] = "Undead"
    MCLL["Undermine"] = "Undermine"
    MCLL["Unobtainable"] = "Unobtainable"
    MCLL["Unobtainable Raid Mounts"] = "Unobtainable Raid Mounts"
    MCLL["Vanilla"] = "Vanilla"
    MCLL["Vendor"] = "Vendor"
    MCLL["Venthyr"] = "Venthyr"
    MCLL["Vicious Saddle"] = "Vicious Saddle"
    MCLL["Visions"] = "Visions"
    MCLL["WOD"] = "WOD"
    MCLL["WOTLK"] = "WOTLK"
    MCLL["Warcraft III Reforged"] = "Warcraft III Reforged"
    MCLL["Warfront: Arathi"] = "Warfront: Arathi"
    MCLL["Warfront: Darkshore"] = "Warfront: Darkshore"
    MCLL["Warlock"] = "Warlock"
    MCLL["Warlords of Draenor"] = "Warlords of Draenor"
    MCLL["Winter Veil"] = "Winter Veil"
    MCLL["WoW Anniversary Mounts"] = "WoW Anniversary Mounts"
    MCLL["WoW Classic"] = "WoW Classic"
    MCLL["Worgen"] = "Worgen"
    MCLL["World Boss"] = "World Boss"
    MCLL["World Events"] = "World Events"
    MCLL["WorldEvents"] = "WorldEvents"
    MCLL["Wrath of the Lich King"] = "Wrath of the Lich King"
    MCLL["Zone"] = "Zone"
    MCLL["Incursion"] = "Incursion"
    MCLL["Horrific Visions"] = "Horrific Visions"
    MCLL["Ashran"] = "Ashran"
    MCLL["Mists of Pandaria Remix"] = "Mists of Pandaria Remix"

    ------ setting panel ------
    MCLL["Ctrl + Right Click to pin uncollected mounts"] = "Ctrl + Right Click to pin/unpin mounts"
    MCLL["Mount Collection Log Settings"] = "Mount Collection Log Settings"
    MCLL["Main Window Options"] = "Main Window Options"
    MCLL["Main Window Opacity"] = "Main Window Opacity"
    MCLL["Changes the opacity of the main window"] = "Changes the opacity of the main window"
    MCLL["Reset Opacity"] = "Reset Opacity"
    MCLL["Reset to default opacity"] = "Reset to default opacity"
    MCLL["Progress Bar Settings"] = "Progress Bar Settings"
    MCLL["Statusbar Texture"] = "Statusbar Texture"
    MCLL["Set the statusbar texture."] = "Set the statusbar texture."
    MCLL["Reset Texture"] = "Reset Texture"
    MCLL["Reset to default texture"] = "Reset to default texture"
    MCLL["Progress Bar (<33%)"] = "Progress Bar (<33%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 33%"] = "Set the progress bar colors to be shown when the percentage collected is below 33%"
    MCLL["Progress Bar (<66%)"] = "Progress Bar (<66%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 66%"] = "Set the progress bar colors to be shown when the percentage collected is below 66%"
    MCLL["Progress Bar (<100%)"] = "Progress Bar (<100%)"
    MCLL["Set the progress bar colors to be shown when the percentage collected is below 100%"] = "Set the progress bar colors to be shown when the percentage collected is below 100%"
    MCLL["Progress Bar (100%)"] = "Progress Bar (100%)"
    MCLL["Set the progress bar colors to be shown when all mounts are collected"] = "Set the progress bar colors to be shown when all mounts are collected"
    MCLL["Reset Colors"] = "Reset Colors"
    MCLL["Reset to default colors"] = "Reset to default colors"
    MCLL["Layout Settings"] = "Layout Settings"
    MCLL["Mounts Per Row"] = "Mounts Per Row"
    MCLL["Set the number of mounts to display per row in the mount grid. Requires UI reload."] = "Set the number of mounts to display per row in the mount grid. Requires UI reload."
    MCLL["Unobtainable Settings"] = "Unobtainable Settings"
    MCLL["Hide Unobtainable from overview"] = "Hide Unobtainable from overview"
    MCLL["Hide Unobtainable mounts from the overview."] = "Hide Unobtainable mounts from the overview."
    MCLL["Show Minimap Icon"] = "Show Minimap Icon"
    MCLL["Toggle the display of the Minimap Icon."] = "Toggle the display of the Minimap Icon."
    MCLL["Reset Settings"] = "Reset Settings"
    MCLL["Reset to default settings"] = "Reset to default settings"
    MCLL["Hide Collected Mounts"] = "Hide Collected Mounts"
    MCLL["If enabled, collected mounts will not be shown in the list at all. Requires UI reload."] = "If enabled, collected mounts will not be shown in the list at all. Requires UI reload."
    MCLL["Changing this setting requires a UI reload. Reload now?"] = "Changing this setting requires a UI reload. Reload now?"
    MCLL["YES"] = "Yes"
    MCLL["NO"] = "No"
    MCLL["Use Blizzard Theme"] = "Use Blizzard Theme"
    MCLL["If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."] = "If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."
    MCLL["Search Results"] = "Search Results"
    MCLL["Search mounts..."] = "Search mounts..."
    MCLL["Mount Collection Log"] = "Mount Collection Log"
    MCLL["Clear Search"] = "Clear Search"
    MCLL["Sections"] = "Sections"
    MCLL["MCL | Mount Collection Log"] = "MCL | Mount Collection Log"
    MCLL["|cff00CCFFMount Collection Log Commands:\n|cffFF0000Show:|cffFFFFFF Shows your mount collection log\n|cffFF0000Icon:|cffFFFFFF Toggles the minimap icon\n|cffFF0000Config:|cffFFFFFF Opens the settings\n|cffFF0000Cleanup:|cffFFFFFF Cleans up invalid pinned mounts\n|cffFF0000Help:|cffFFFFFF Shows commands"] = "|cff00CCFFMount Collection Log Commands:\n|cffFF0000Show:|cffFFFFFF Shows your mount collection log\n|cffFF0000Icon:|cffFFFFFF Toggles the minimap icon\n|cffFF0000Config:|cffFFFFFF Opens the settings\n|cffFF0000Cleanup:|cffFFFFFF Cleans up invalid pinned mounts\n|cffFF0000Help:|cffFFFFFF Shows commands"
    MCLL["How to Use Pinned Mounts"] = "How to Use Pinned Mounts"
    MCLL["Pin Instructions"] = "• Right-click any mount icon to pin/unpin it\n• Pinned mounts will appear in this tab for quick access\n• Use pinned mounts to track your favorites or goals\n• Pin icon appears on mount when pinned\n• Pinned mounts are saved across sessions"
    MCLL["Pin Instructions Text"] = "|cffFF8800|TInterface\\GossipFrame\\AvailableQuestIcon:0:0:0:0:32:32:0:32:0:32|t Ctrl + Right Click|r to pin/unpin mounts"
end

local MCLcore = {}

MCLcore.sectionNames = {}
MCLcore.mountList = {}

MCLcore.mountList[1] = {
	name = "SL",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {186654, 186637, 184183, 182596, 186653, 184166, 186655, 187673, "m1549", "m1576", 217612},
		},
		Vendor = {
			name = "Vendor",
			mounts = {180748},
			mountID = {}
		},
		Treasures = {
			name = "Treasures",
			mounts = {180731, 180772, 190766},
			mountID = {}
		},
		Adventures = {
			name = "Adventures",
			mounts = {183052, 183617, 183615, 183618},
			mountID = {}
		},
		Riddles = {
			name = "Riddles",
			mounts = {184168,186713},
			mountID = {}
		},
		Tormentors = {
			name = "Tormentors",
			mounts = {185973},
			mountID = {}
		},
		MawAssaults = {
			name = "Maw Assaults",
			mounts = {185996, 186000, 186103},
			mountID = {}
		},
		Reputation = {
			name = "Reputation",
			mounts = {180729, 182082, 183518, 183740, 186647, 186648, 187629, 187640},
			mountID = {}
		},
		ParagonReputation = {
			name = "Paragon Reputation",
			mounts = {182081, 183800, 186649, 186644, 186657, 186641},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {181819, 186638, "m1445"},
			mountID = {1445}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {186656, 186642, 190768},
			mountID = {}
		},
		Zone = {
			name = "Zone",
			mounts = {181818},
			mountID = {}
		},
		DailyActivities = {
			name = "Daily Activities",
			mounts = {182614, 182589, 186643, 186651, 186646, 188808},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {180728, 180727, 180725, 182650, 180773, 182085, 184062, 182084, 182079, 180582, 183741, 184167, 187183, 186652 ,186645, 186659, 187676, 190765},
			mountID = {}
		},
		OozingNecrorayEgg = {
			name = "Oozing Necroray Egg",
			mounts = {184160, 184161, 184162},
			mountID = {}
		},
		CovenantFeature = {
			name = "Covenant Feature",
			mounts = {180726, 181316, 181300, 181317},
			mountID = {}
		},
		NightFae = {
			name = "Night Fae",
			mounts = {180263, 180721, 183053, 180722, 180413, 180415, 180414, 180723, 183801, 180724, 180730, 186493, 186494, 186495, 186492},
			mountID = {}
		},
		Kyrian = {
			name = "Kyrian",
			mounts = {180761, 180762, 180763, 180764, 180765, 180766, 180767, 180768, 186482, 186485, 186480, 186483},
			mountID = {}
		},
		Necrolords = {
			name = "Necrolords",
			mounts = {182078, 182077, 181822, 182076, 182075, 181821, 181815, 182074, 181820, 182080, 186487, 186488, 186490, 186489},
			mountID = {}
		},
		Venthyr = {
			name = "Venthyr",
			mounts = {182954, 180581, 180948, 183715, 180945, 182209, 182332, 183798, 180461, 186476, 186478, 186477, 186479},
			mountID = {}				
		},
		ProtoformSynthesis = {
			name = "Protoform Synthesis",
			mounts = {187632, 187670, 187663, 187665, 187630, 187631, 187638, 187664, 187677, 187683, 190580, 187679, 187667, 187639, 188809, 187668, 188810, 187672, 187669, 187641, 187678, 187671, 187660, 187666},
			mountID = {}
		},
		Torghast = {
			name = "Torghast",
			mounts = {188700, 188696, 188736},
			mountID = {}
		}
	}
}
MCLcore.mountList[2] = {
	name = "BFA",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {168056, 168055, 169162, 163577, 169194, 168329, 161215, 163216, 166539, 167171, 174861, 174654, 235515},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {163183, 166442, 166443, 163589, 169203, 169202, 174770},
			mountID = {}
		},
		Quest = {
			name = "Quest",
			mounts = {159146, 168827, 168408, 169199, 174859, 174771, 169200, 170069},
			mountID = {}
		},
		Medals = {
			name = "Medals",
			mounts = {166464, 166436, 166469, 166465, 166463},
			mountID = {}
		},
		AlliedRaces = {
			name = "Allied Races",
			mounts = {155662, 156487, 161330, 157870, 174066, 156486, 155656, 161331, 164762, 174067, 223572},
			mountID = {}
		},
		Reputation = {
			name = "Reputation",
			mounts = {161773, 161774, 161665, 161666, 161667, 161664, 167167, 167170, 168829, 174754, 161911, 161912, 161910, 161879, 161909, 161908},
			mountID = {}
		},
		Riddle = {
			name = "Riddle",
			mounts = {156798},
			mountID = {}
		},
		Tinkering = {
			name = "Tinkering",
			mounts = {167751},
			mountID = {}
		},
		Zone = {
			name = "Zone",
			mounts = {163576, 163574, 163575, 163573},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {161479, 166433, 169201, 168370, 168823, 169163, 174860},
			mountID = {}
		},
		WorldBoss = {
			name = "World Boss",
			mounts = {174842},
			mountID = {}
		},
		WarfrontArathi = {
			name = "Warfront: Arathi",
			mounts = {163579, 163578, 163644, 163645, 163706, 163646},
			mountID = {}
		},
		WarfrontDarkshore = {
			name = "Warfront: Darkshore",
			mounts = {166438, 166434, 166435, 166432},
			mountID = {}
		},
		AssaultVale = {
			name = "Assault: Vale of Eternal Blossoms",
			mounts = {173887, 174752, 174841, 174840, 174649},
			mountID = {}
		},
		AssaultUldum = {
			name = "Assault: Uldum",
			mounts = {174769, 174641, 174753},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {159921, 160829, 159842, 168826, 168830},
			mountID = {}
		},	
		RaidDrop = {
			name = "Raid Drop",
			mounts = {166518, 166705, 174872},
			mountID = {}
		},	
		IslandExpedition = {
			name = "Island Expedition",
			mounts = {163584, 163585, 163583, 163586, 163582, 166470, 166468, 166467, 166466},
			mountID = {}
		},	
		Dubloons = {
			name = "Dubloons",
			mounts = {166471, 166745},
			mountID = {}
		},
		Visions = {
			name = "Visions",
			mounts = {174653},
			mountID = {}
		},
		ParagonReputation = {
			name = "Paragon Reputation",
			mounts = {169198},
			mountID = {}
		}
	}
}
MCLcore.mountList[3] = {
	name = "LEGION",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {141216, 138387, 141217, 143864, 152815, 153041, 129280},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {138811, 141713, 137570},
			mountID = {}
		},
		Quest = {
			name = "Quest",
			mounts = {137573, 142436, 137577, 137578, 137579, 137580},
			mountID = {}
		},
		Riddle = {
			name = "Riddle",
			mounts = {138201, 147835, 151623},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {138258, 152814, 152844, 152842, 152840, 152841, 152843, 152904, 152905, 152903, 152790},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {142236, 142552},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {137574, 143643, 152816, 137575, 152789},
			mountID = {}
		},
		Class = {
			name = "Class",
			mounts = {142231, 143502, 143503, 143505, 143504, 143493, 143492, 143490, 143491, 142225, 142232, 143489, 142227, 142228, 142226, 142233, 143637, "m868", "m860", "m861", "m898"},
			mountID = {868, 860, 861, 898}
		},
		ParagonReputation = {
			name = "Paragon Reputation",
			mounts = {147806, 147804, 147807, 147805, 143764, 153042, 153044, 153043},
			mountID = {}
		},
		Reputation = {
			name = "Reputation",
			mounts = {152788, 152797, 152793, 152795, 152794, 152796, 152791},
			mountID = {}
		}
	}																										
}
MCLcore.mountList[4] = {
	name = "WOD",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {116670, 116383, 127140, 128706},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {116664, 116785, 116772, 116672, 116768, 116671, 128480, 128526, 123974, 116667, 116655},
			mountID = {}
		},
		Garrison = {
			name = "Garrison",
			mounts = {116779, 116673, 116786, 116663},
			mountID = {}
		},
		Missions = {
			name = "Missions",
			mounts = {116769, 128311},
			mountID = {}
		},
		Stables = {
			name = "Stables",
			mounts = {116784, 116662, 116676, 116675, 116774, 116656, 116668, 116781},
			mountID = {}
		},
		TradingPost = {
			name = "Trading Post",
			mounts = {116782, 116665},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {116674, 116659, 116661, 116792, 116767, 116773, 116794, 121815, 116780, 116669, 116658},
			mountID = {}
		},
		WorldBoss = {
			name = "World Boss",
			mounts = {116771},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {116660, 123890},
			mountID = {}
		},
		FishingShack = {
			name = "Fishing Shack",
			mounts = {87791},
			mountID = {}
		}		
	}		
}
MCLcore.mountList[5] = {
	name = "MOP",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {87769, 87773, 81559, 93662, 104208, 89785},
			mountID = {}
		},
		GoldenLotus = {
			name = "Golden Lotus",
			mounts = {87781, 87782, 87783},
			mountID = {}
		},
		CloudSerpent = {
			name = "Order of the Cloud Serpent",
			mounts = {85430, 85429, 79802},
			mountID = {}
		},
		ShadoPan = {
			name = "Shado-Pan",
			mounts = {89305, 89306, 89307},
			mountID = {}
		},
		KunLai = {
			name = "Kun-Lai Vendor",
			mounts = {87788, 87789, 84101},
			mountID = {}
		},
		TheTillers = {
			name = "The Tillers",
			mounts = {89362, 89390, 89391},
			mountID = {}
		},
		PrimalEggs = {
			name = "Primal Eggs",
			mounts = {94291, 94292, 94293},
			mountID = {}
		},
		Quest = {
			name = "Quest",
			mounts = {93386, 87768, 94290, 93385},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {87777, 93666, 95059, 104253},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {90655, 94229, 94230, 94231, 104269},
			mountID = {}
		},
		WorldBoss = {
			name = "World Boss",
			mounts = {94228, 87771, 89783, 95057},
			mountID = {}
		},
		Reputation = {
			name = "Reputation",
			mounts = {93169, 95565, 81354, 89304, 85262, 89363, 87774, 93168, 95564},
			mountID = {}
		}
	}																																
}
MCLcore.mountList[6] = {
	name = "CATA",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {62900, 62901, 69213, 69230, 77068},
			mountID = {}
		},
		Quest = {
			name = "Quest",
			mounts = {54465},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {65356, 64999, 63044, 63045, 64998},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {69747, 63040, 63043, 68823, 68824},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {77067, 77069, 78919, 63041, 69224, 71665},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {67151, 63042, 63046},
			mountID = {}
		}		
	}										
}
MCLcore.mountList[7] = {
	name = "WOTLK",
	categories = {
		Achievement = {
			name = "Achievement",
			mounts = {44160, 45801, 45802, 51954, 51955},
			mountID = {}
		},
		Quest = {
			name = "Quest",
			mounts = {43962, 52200},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {44690, 44231, 44234, 44226, 44689, 44230, 44235, 44225},
			mountID = {}
		},
		ArgentTournament = {
			name = "Argent Tournament",
			mounts = {46814, 45592, 45593, 45595, 45596, 45597, 46743, 46746, 46749, 46750, 46751, 46816, 47180, 45725, 45125, 45586, 45589, 45590, 45591, 46744, 46745, 46747, 46748, 46752, 46815, 46813},
			mountID = {}
		},
		Reputation = {
			name = "Reputation",
			mounts = {44080, 44086, 43955, 44707, 43958, 43961},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {43951, 44151},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {43952, 43953, 43954, 43986, 49636, 43959, 45693, 50818, 44083,206585},
			mountID = {}
		},
		RareSpawn = {
			name = "Rare Spawn",
			mounts = {44168},
			mountID = {}
		}			
	}																		
}
MCLcore.mountList[8] = {
	name = "TBC",
	categories = {
		CenarionExpedition = {
			name = "Cenarion Expedition",
			mounts = {33999},
			mountID = {}
		},
		Kurenai = {
			name = "Kurenai/The Mag'har",
			mounts = {29227, 29231, 29229, 29230, 31830, 31832, 31834, 31836},
			mountID = {}
		},
		Netherwing = {
			name = "Netherwing",
			mounts = {32858, 32859, 32857, 32860, 32861, 32862},
			mountID = {}
		},
		Shatari = {
			name = "Sha'tari Skyguard",
			mounts = {32319, 32314, 32316, 32317, 32318},
			mountID = {}
		},
		Vendor = {
			name = "Vendor",
			mounts = {25473, 25527, 25528, 25529, 25470, 25471, 25472, 25477, 25531, 25532, 25533, 25474, 25475, 25476},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {32768, 35513},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {32458, 30480},
			mountID = {}
		}
	}
}
MCLcore.mountList[9] = {
	name = "Classic",
	categories = {	
		Reputation = {
			name = "Reputation",
			mounts = {13086, 46102},
			mountID = {}
		},
		DungeonDrop = {
			name = "Dungeon Drop",
			mounts = {13335},
			mountID = {}
		},
		RaidDrop = {
			name = "Raid Drop",
			mounts = {21218, 21321, 21323, 21324},
			mountID = {}
		}
	}						
}
MCLcore.mountList[10] = {
	name = "Alliance",
	categories = {	
		Human = {
			name = "Human",
			mounts = {18776, 18777, 18778, 5655, 2411, 2414, 5656},
			mountID = {}
		},
		NightElf = {
			name = "Night Elf",
			mounts = {18766, 18767, 18902, 8629, 8631, 8632, 47100},
			mountID = {}
		},
		Dwarf = {
			name = "Dwarf",
			mounts = {18785, 18786, 18787, 5864, 5872, 5873},
			mountID = {}
		},
		DarkIronDwarf = {
			name = "Dark Iron Dwarf",
			mounts = {191123},
			mountID = {}
		},
		Gnome = {
			name = "Gnome",
			mounts = {18772, 18773, 18774, 8563, 8595, 13322, 13321},
			mountID = {}
		},
		Draenei = {
			name = "Draenei",
			mounts = {29745, 29746, 29747, 28481, 29743, 29744},
			mountID = {}
		},
		Worgen = {
			name = "Worgen",
			mounts = {73839, 73838},
			mountID = {}
		},
		Pandaren = {
			name = "Pandaren",
			mounts = {91010, 91012, 91011, 91013, 91014, 91015, 91004, 91008, 91009, 91005, 91006, 91007},
			mountID = {}
		},
		Dracthyr = {
			name = "Dracthyr",
			mounts = {201720, 201702, 201719, 201704, 198809, 198811, 198810, 198808},
			mountID = {},
		}		
	}				
}
MCLcore.mountList[11] = {
	name = "Horde",
	categories = {	
		Orc = {
			name = "Orc",
			mounts = {18796, 18798, 18797, 46099, 5668, 5665, 1132},
			mountID = {}
		},
		Undead = {
			name = "Undead",
			mounts = {13334, 18791, 13331, 13332, 13333, 46308, 47101},
			mountID = {}
		},
		Tauren = {
			name = "Tauren",
			mounts = {18793, 18794, 18795, 15277, 15290, 46100},
			mountID = {}
		},
		Troll = {
			name = "Troll",
			mounts = {18788, 18789, 18790, 8588, 8591, 8592},
			mountID = {}
		},
		Bloodelf = {
			name = "Blood Elf",
			mounts = {28936, 29223, 29224, 28927, 29220, 29221, 29222},
			mountID = {}
		},
		Goblin = {
			name = "Goblin",
			mounts = {62462, 62461},
			mountID = {}
		},			
		Pandaren = {
			name = "Pandaren",
			mounts = {91010, 91012, 91011, 91013, 91014, 91015, 91004, 91008, 91009, 91005, 91006, 91007},
			mountID = {}
		},
		Dracthyr = {
			name = "Dracthyr",
			mounts = {201720, 201702, 201719, 201704, 198809, 198811, 198810, 198808},
			mountID = {},
		}
	}
}
MCLcore.mountList[12] = {
	name = "Professions",
	categories = {	
		Alchemy = {
			name = "Alchemy",
			mounts = {65891},
			mountID = {}
		},
		Archeology = {
			name = "Archeology",
			mounts = {60954, 64883, 131734},
			mountID = {}
		},
		Engineering = {
			name = "Engineering",
			mounts = {34060, 41508, 34061, 44413, 87250, 87251, 95416, 161134, 153594, 221967},
			mountID = {}
		},
		Fishing = {
			name = "Fishing",
			mounts = {46109, 23720, 152912, 163131},
			mountID = {}
		},
		Jewelcrafting = {
			name = "Jewelcrafting",
			mounts = {83088, 83087, 83090, 83089, 82453, 235712},
			mountID = {}
		},
		Tailoring = {
			name = "Tailoring",
			mounts = {44554, 54797, 44558, 115363},
			mountID = {}
		},
		Leatherworking = {
			name = "Leatherworking",
			mounts = {108883, 129962},
			mountID = {}
		},
		Blacksmith = {
			name = "Blacksmith",
			mounts = {137686},
			mountID = {}
		}
	}
}
MCLcore.mountList[13] = {
	name = "PVP",
	categories = {	
		Achievement = {
			name = "Achievement",
			mounts = {44223, 44224},
			mountID = {}
		},
		MarkHonor = {
			name = "Mark of Honor",
			mounts = {19030, 29465, 29467, 29468, 29471, 35906, 43956, 29466, 29469, 29470, 29472, 19029, 34129, 44077},
			mountID = {}
		},
		Honor = {
			name = "Honor",
			mounts = {140228, 140233, 140408, 140232, 140230, 140407, 164250},
			mountID = {}
		},
		ViciousSaddle = {
			name = "Vicious Saddle",
			mounts = {102533, 70910, 116778, 124540, 140348, 140354, 143649, 142235, 142437, 152869, 163124, 165020, 163121, 173713, 184013,184014, 186179, 70909, 102514, 116777, 124089, 140353, 140350, 143648, 142234, 142237, 152870, 163123, 163122, 173714, 186178, 187681, 187680, 187642, 187644, 201788, 201789, 205245, 205246, 210070, 210069, 213439, 213440,223511,221813,229989,229988, 165019},
			mountID = {}
		},
		Gladiator = {
			name = "Gladiator",
			mounts = {229987},
			mountID = {}
		},
		Halaa = {
			name = "Halaa",
			mounts = {28915, 29228},
			mountID = {}
		},
		Ashran = {
			name = "Ashran",
			mounts = {116776, 116775}
		},
		TimelessIsle = {
			name = "Timeless Isle",
			mounts = {103638},
			mountID = {}
		},
		TalonsVengeance = {
			name = "Talon's Vengeance",
			mounts = {142369},
			mountID = {}
		}
	}
}
MCLcore.mountList[14] = {
	name = "WorldEvents",
	categories = {	
		Achievement = {
			name = "Achievement",
			mounts = {44177},
			mountID = {}
		},
		Brewfest = {
			name = "Brewfest",
			mounts = {33977, 37828},
			mountID = {}
		},
		HallowsEnd = {
			name = "Hallow's End",
			mounts = {37012},
			mountID = {}
		},
		LoveAir = {
			name = "Love is in the Air",
			mounts = {72146, 50250, 210973, 232926},
			mountID = {}
		},
		NobleGarden = {
			name = "Noblegarden",
			mounts = {72145, 212599},
			mountID = {}
		},
		WinterVeil = {
			name = "Winter Veil",
			mounts = {128671},
			mountID = {}
		},
		DarkmoonFaire = {
			name = "Darkmoon Faire",
			mounts = {72140, 73766, 142398, 153485},
			mountID = {}
		},
		TimeWalking = {
			name = "Timewalking",
			mounts = {129923, 129922, 87775, 167894, 167895, 133543, 188674, 187595, 231374, 224398, 224399,234730,232624,205208,234721,234716,234740,238739,245694,245695},
			mountID = {}
		},
		Lunar = {
			name = "Lunar Festival",
			mounts = {232901},
			mountID = {}
		},
		lnuizuoqi = {
			name = "lnuizuoqi",
			mounts = {13335, 32768, 35513, 30480, 32458, 44151, 43952, 43953, 44083, 45693, 49636, 50818, 63040, 63043, 68823, 68824, 63041, 69224, 71665, 77067, 77069, 78919, 87777, 93666, 95059, 104253, 116660, 123890, 142236, 137575, 137574, 143643, 152789, 152816, 159842, 159921, 160829, 168826, 166518,166705, 174872, 181819, 186638, 186642, 186656, 190768},
			mountID = {}
		}
	}
}
MCLcore.mountList[15] = {
	name = "Promotion",
	categories = {	
		BlizzardStore = {
			name = "Blizzard Store",
			mounts = {54811, 69846, 78924, 97989, 107951, 112326, 122469, 147901, 156564, 160589, 166775, 166774, 166776, "m1266", "m1267", "m1290", "m1346", "m1291", "m1456", "m1330", "m1531", "m1581", "m1312", "m1662", "m1594", "m1583", "m1797", 203727, "m1795", "m1692", 212229, 228751, 229128, 219450, 224574, "m2237", 229418, 230184, 230200, 230201, 230185, 227362, 235344, 231297, 233285, 233284, 233282, 233283, 233286, 238943,238994, 238966, 221270, 190581, 212228, 225250, 206167},
			mountID = {1266, 1267, 1290, 1346, 1291, 1456, 1330, 1531, 1581}
		},
		CollectorsEdition = {
			name = "Collector's Edition",
			mounts = {85870, 109013, 128425, 153539, 153540, "m1289", "m1556", "m1792"},
			mountID = {1289, 1556}
		},
		WowClassic = {
			name = "WoW Classic",
			mounts = {"m1444", "m1602", "m1812", 235287, 210008},
			mountID = {1444, 1602}
		},
		anniversary = {
			name = "WoW Anniversary Mounts",
			mounts = {172022, 186469, 208572, 228760, 229348, 223459, 223471},
			mountID = {}
		},
		Hearthstone = {
			name = "Hearthstone",
			mounts = {98618, "m1513", 163186, 212522},
			mountID = {1513}
		},
		MopRemix = {
			name = "Mists of Pandaria Remix",
			mounts = {235286},
			mountID = {}
		},
		WarcraftIII = {
			name = "Warcraft III Reforged",
			mounts = {164571},
			mountID = {}
		},
		DiabloIV = {
			name = "Diablo IV",
			mounts = {"m1596", 246264, 191114},
			mountID = {}
		},		
		RAF = {
			name = "Recruit-A-Friend",
			mounts = {173297, 173299, 204091},
			mountID = {}
		},
		AzerothChoppers = {
			name = "Azeroth Choppers",
			mounts = {116789},
			mountID = {}
		},
		TCG = {
			name = "Trading Card Game",
			mounts = {49283, 49284, 49285, 49286, 49282, 49290, 54069, 54068, 68008, 69228, 68825, 71718, 72582, 72575, 79771, 93671, 74269},
			mountID = {}
		},
		AV = {
			name = "Timewalking Alterac Valley",
			mounts = {172023, 172022},
			mountID = {}
		},
		PlunderStorm = {
			name="Plunderstorm",
			mounts = {233241,233240,233243,233242},
		},
		ProductPromotion = {
			name="Product Promotion",
			mounts = {"m1947", "m1946", 211087}
		}
	}	
}
MCLcore.mountList[16] = {
	name = "Other",
	categories = {	
		GuildVendor = {
			name = "Guild Vendor",
			mounts = {63125, 62298, 67107, 85666, 116666},
			mountID = {}
		},
		BMAH = {
			name = "BMAH",
			mounts = {19872, 19902, 44175, 163042, 211084},
			mountID = {}
		},
		MountCollection = {
			name = "Mount Collection",
			mounts = {44178, 44843, 44842, 98104, 91802, 98259, 69226, 87776, 137614, 163981, 118676, 198654},
			mountID = {}
		},
		ExaltedReputations = {
			name = "Exalted Reputations",
			mounts = {163982},
			mountID = {}
		},
		Toy = {
			name = "Toy",
			mounts = {140500},
			mountID = {}
		},
		Heirlooms = {
			name = "Heirlooms",
			mounts = {120968, 122703},
			mountID = {}
		},
		Paladin = {
			name="Paladin",
			mounts = {47179, "m2233", "m41", "m84", "m149", "m150", "m350", "m351", "m367", "m368", "m1046", "m1047", "m1568",191566},
			mountID = {}
		},
		Warlock = {
			name="Warlock",
			mounts = {"m17", "m83"},
			mountID = {17, 83},
		},
		DemonHunter = {
			name="Demon Hunter",
			mounts = {"m780"},
		},
		TradingPost = {
			name = "Trading Post",
			mounts = {190231, 190168, 190539, 190767, 190613, 206156, 137576, 208598, 211074, 210919, 212227, 212630, 212920, 192766, 226041, 226040, 226044, 226042, 226506, 223449, 223469, 187674, 233019,233020,233023,233354,212631, 223285, 221814, 207821, 190169, 189978, 206976, 206027, "m1595", 235646, 235650, 235555, 235556, 235554, 235657, 235557, 235658, 235659, 235662,238967,238897,238941,236415,238902,238901,238968,238900, 243593, 243597, 243594, 243590, 243572, 243591, 243592, 245936, 243596, 76755, 207964, 207963, 190636, 210141, 137615, 229951, 54860},
		},		
	}
}
MCLcore.mountList[17] = {
	name = "Unobtainable",
	categories = {	
		MythicPlus = {
			name = "Mythic +",
			mounts = {182717, 187525, 174836, 187682, 192557, 199412, 204798, 209060, 213438, 226357},
			mountID = {}
		},
		ScrollOfResurrection = {
			name = "Scroll of Resurrection",
			mounts = {76902, 76889},
			mountID = {}
		},
		ChallengeMode = {
			name = "Challenge Mode",
			mounts = {89154, 90710, 90711, 90712, 116791},
			mountID = {}
		},
		RAF = {
			name = "Recruit-A-Friend",
			mounts = {83086, 106246, 118515, 37719, "m382"},
			mountID = {}
		},
		AOTC = {
			name = "Ahead of the Curve",
			mounts = {104246, 128422, 152901, 174862, 190771},
			mountID = {}
		},
		Brawl = {
			name = "Brawler's Guild",
			mounts = {142403, 98405, 166724},
			mountID = {}
		},
		Arena = {
			name = "Arena Mounts",
			mounts = {30609, 34092, 37676, 43516, 46708, 46171, 47840, 50435, 71339, 71954, 85785, 95041, 104325, 104326, 104327, 128277, 128281, 128282, 141843, 141844, 141845, 141846, 141847, 141848, 153493, 156879, 156880, 156881, 156884, 183937, 186177, 189507, 191290, 202086, 205233, 210345, "m1822", 223586, 210077},
			mountID = {}
		},
		DCAzerothChopper = {
			name = "Azeroth Choppers",
			mounts = {116788},
			mountID = {}
		},
		OriginalEpic = {
			name = "Original Epic Mounts",
			mounts = {13328, 13329, 13327, 13326, 12354, 12353, 12302, 12303, 12351, 12330, 15292, 15293, 13317, 8586},
			mountID = {}
		},
		Promotion = {
			name = "Old Promotion Mounts",
			mounts = {95341, 112327, 92724, 143631, 163127, 43599, 151618, "m1458", 151617},
			mountID = {}
		},	
		RaidMounts = {
			name = "Unobtainable Raid Mounts",
			mounts = {49098, 49096, 49046, 49044, 44164, 33809, 21176, "m937"},
			mountID = {937}
		},
		BrewFest = {
			name = "BrewFest",
			mounts = {33976},
			mountID = {}
		},
		Anniversary = {
			name="Old Anniversary Mounts",
			mounts = {172012, 115484, "m1424"},
			mountID = {}
		},
		PreLaunchEvent = {
			name = "Pre-Launch Event",
			mounts = {163127, 163128, 217987, 217985},
			mountID = {}
		},
		RemixMOP = {
			name="Remix MOP",
			mounts = {220766,220768,213582,213576,213584,213595,87784,213602,213603,213605,213606,213607,213604,213608,213609,213628,213627,87786,87787,84753,213626,213624,213625,213623,213622,213621,218111,213600,213601,213598,213597,213596, 224374},	
		}
	}
}
MCLcore.mountList[18] = {
	name = "Dragonflight",
	categories = {
		DragonRiding = {
			name = "Dragon Riding",
			mounts = {194034, 194705, 194521, 194549, 204361, 210412}
		},
		Achievement = {
			name = "Achievement",
			mounts = {192806, 192791, 192784, 205205, 208152, 210060, 192774, 210142, "m1614", 198822, 192792, 192788, 211862, 192765, "m1733", 217340},
		},
		Treasures = {
			name = "Treasures",
			mounts = {201440, 198825, 192777, 192779,205204, 210059},
		},
		Quest = {
			name = "Quest",
			mounts = {192799, 198870, 206567, 206566, "m1545", 210774, 211873},
		},
		Reputation = {		
			name = "Renown",
			mounts = {192762, 198872, 192761, 192764, 200118, 201426, 201425, 205155, 205209, 205207, 210969, 210833, 210831, 210946, 210948, 210945, 209951, 209949},
		},
		Zone = {
			name = "Zone",
			mounts = {192601, 198873, 198871, 192775, 201454, 192800, 204382, 192785, 192790, 192772, 191838, 205203, 205197,210775, 210769, 210058, 210057, 209947, 209950, 212645, "m1638", 192807, 198824},
		},
		Secret = {
			name = "Secret",
			mounts = {192786, 210022}
		},
		Vendor = {
			name = "Vendor",
			mounts = {206673, 206680, 206676, 206678, 206674, 206679, 206675, 192796}
		},
		Raid = {
			name = "Raid",
			mounts = {"m1818", 210061}
		},
	}
}
MCLcore.mountList[19] = {
	name = "The War Within",
	categories = {
		RareDrops = {
			name = "Rare Drops",
			mounts = {223315,223270,223501},
		},
		Raid = {
			name = "Raid",
			mounts = {224147,224151, 236960, 235626, 229945, 229924, 229940},
		},
		Dungeon = {
			name = "Dungeon",
			mounts = {221765,225548},
		},
		Achievement = {
			name = "Achievement",
			mounts = {223266,224415,223267,223286,223158, "m2190", 231173, 235549, 237141},
		},
		Quest = {
			name = "Quest",
			mounts = {219391,224150, 246237},
		},
		Reputation = {
			name = "Reputation",
			mounts = {223571,221753,223505,222989,223317,223314,223274,223264,223276,223278,223279,238829,229936,229944,229935},
		},
		Vendor = {
			name = "Vendor",
			mounts = {223153},
		},
		Zone = {
			name = "Zone",
			mounts = {223269, 223318},
		},
		SirenIsland = {
			name = "Siren Island",
			mounts = {232639, 233058, 233489, 232991}
		},
		UnderMine = {
			name = "Undermine",
			mounts = {229974, 229953, 229955,  229954, 229941, 229952, 229949, 229947, 233064, "m2295", "m2289", "m2274", 229943}
		},
		Incursion = {
			name = "Incursion",
			mounts = {239563, 239020}
		},
		HorrificVisions = {
			name = "Horrific Visions",
			mounts = {235711,235709,235705,235700,235706,235707,211089,223265}
		},
		Delves = {
			name = "Delves",
			mounts = {229956,229948,229946,229950}
		}	
	}
}
MCLcore.sectionNames[11] = {
	name = "Vanilla",
	mounts = MCLcore.mountList[9],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\classic.blp",
	isExpansion = true,
}
MCLcore.sectionNames[10] = {
	name = "The Burning Crusade",
	mounts = MCLcore.mountList[8],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\bc.blp",
	isExpansion = true,
}
MCLcore.sectionNames[9] = {
	name = "Wrath of the Lich King",
	mounts = MCLcore.mountList[7],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\wrath.blp",
	isExpansion = true,
}
MCLcore.sectionNames[8] = {
	name = "Cataclysm",
	mounts = MCLcore.mountList[6],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\cata.blp",
	isExpansion = true,
}
MCLcore.sectionNames[7] = {
	name = "Mists of Pandaria",
	mounts = MCLcore.mountList[5],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\mists.blp",
	isExpansion = true,
}
MCLcore.sectionNames[6] = {
	name = "Warlords of Draenor",
	mounts = MCLcore.mountList[4],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\wod.blp",
	isExpansion = true,
}
MCLcore.sectionNames[5] = {
	name = "Legion",
	mounts = MCLcore.mountList[3],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\legion.blp",
	isExpansion = true,
}
MCLcore.sectionNames[4] = {
	name = "Battle for Azeroth",
	mounts = MCLcore.mountList[2],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\bfa.blp",
	isExpansion = true,
}
MCLcore.sectionNames[3] = {
	name = "Shadowlands",
	mounts = MCLcore.mountList[1],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\sl.blp",
	isExpansion = true,
}
MCLcore.sectionNames[2] = {
	name = "Dragonflight",
	mounts = MCLcore.mountList[18],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\df.blp",
	isExpansion = true,
}
MCLcore.sectionNames[1] = {
	name = "The War Within",
	mounts = MCLcore.mountList[19],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\tww.blp",
	isExpansion = true,
}
MCLcore.sectionNames[12] = {
	name = "Horde",
	mounts = MCLcore.mountList[11],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\horde.blp",
	isExpansion = false,
}
MCLcore.sectionNames[13] = {
	name = "Alliance",
	mounts = MCLcore.mountList[10],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\alliance.blp",
	isExpansion = false,
}
MCLcore.sectionNames[14] = {
	name = "Professions",
	mounts = MCLcore.mountList[12],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\professions.blp",
	isExpansion = false,
}
MCLcore.sectionNames[15] = {
	name = "PVP",
	mounts = MCLcore.mountList[13],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pvp.blp",
	isExpansion = false,
}
MCLcore.sectionNames[16] = {
	name = "World Events",
	mounts = MCLcore.mountList[14],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\holiday.blp",
	isExpansion = false,
}
MCLcore.sectionNames[17] = {
	name = "Promotion",
	mounts = MCLcore.mountList[15],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\promotion.blp",
	isExpansion = false,
}
MCLcore.sectionNames[18] = {
	name = "Other",
	mounts = MCLcore.mountList[16],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\other.blp",
	isExpansion = false,
}
MCLcore.sectionNames[19] = {
	name = "Unobtainable",
	mounts = MCLcore.mountList[17],
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\unobtainable.blp",
	isExpansion = false,
}
MCLcore.sectionNames[20] = {
	name = "Pinned",
	mounts = {MCL_PINNED},
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pin.blp",
	isExpansion = false,
}
MCLcore.sectionNames[21] = {
	name = "Overview",
	mounts = {},
	icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\mcl.blp",
	isExpansion = false,
}

MCLcore.regionalFilter = {
	['CN'] = {210077},
}

MCLcore.Function = {};
local MCL_functions = MCLcore.Function;

MCLcore.mounts = {}
MCLcore.stats= {}
MCLcore.overviewStats = {}
MCLcore.overviewFrames = {}
MCLcore.mountFrames = {}
MCLcore.mountCheck = {}
MCLcore.addon_name = MCLL["Addons"]
MCLcore.pinnedMountsChanged = false  -- Flag to track if pinned mounts have been modified


function MCL_functions:getFaction()
    -- * --------------------------------
    -- * Get's player faction
    -- * --------------------------------
	if UnitFactionGroup("player") == "Alliance" then
		return "Horde" -- Inverse
	else
		return "Alliance" -- Inverse
	end
end

-- local function IsMountFactionSpecific(id)
--     if string.sub(id, 1, 1) == "m" then
--         mount_Id = string.sub(id, 2, -1)
--         local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(mount_Id)
--         return faction, isFactionSpecific
--     else
--         mount_Id = C_MountJournal.GetMountFromItem(id)
--         local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(mount_Id)
--         return faction, isFactionSpecific
--     end
-- end

local function GetMountInfoByIDChecked(mount_Id)
    local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(mount_Id)
    return faction, isFactionSpecific
end

local function IsMountFactionSpecific(id)
    local mount_Id, ok, faction, isFactionSpecific

    if string.sub(id, 1, 1) == "m" then
        mount_Id = string.sub(id, 2, -1)
    else
        mount_Id = C_MountJournal.GetMountFromItem(id)
    end

    -- Use pcall to execute GetMountInfoByIDChecked and capture any error
    local ok, faction, isFactionSpecific = pcall(GetMountInfoByIDChecked, mount_Id)

    -- If an error occurred, print the error message along with the id that caused the error
    if not ok then
        return nil, nil
    else
        return faction, isFactionSpecific
    end
end

MCLcore.Function.IsMountFactionSpecific = IsMountFactionSpecific

function MCL_functions:resetToDefault(setting)
    if setting == nil then
        MCL_SETTINGS = {}        
        MCL_SETTINGS.unobtainable = false
        MCL_SETTINGS.hideCollectedMounts = false
    end
    if setting == "Opacity" or setting == nil then
        MCL_SETTINGS.opacity = 0.95
    end
    if setting == "Texture" or setting == nil then
        MCL_SETTINGS.statusBarTexture = nil
    end
    if setting == "Colors" or setting == nil then
        MCL_SETTINGS.progressColors = {
            low = {
                ["a"] = 1,
                ["r"] = 0.929,
                ["g"] = 0.007,
                ["b"] = 0.019,
            },
            high = {
                ["a"] = 1,
                ["r"] = 0.1,
                ["g"] = 0.9,
                ["b"] = 0.1,
            },
            medium = {
                ["a"] = 1,
                ["r"] = 0.941,
                ["g"] = 0.658,
                ["b"] = 0.019,
            },
            complete = {
                ["a"] = 1,
                ["r"] = 0,
                ["g"] = 0.5,
                ["b"] = 0.9,
            },
        }
    end
    if setting == "HideCollectedMounts" or setting == nil then
        MCL_SETTINGS.hideCollectedMounts = false
    end
    if setting == "BlizzardTheme" or setting == nil then
        MCL_SETTINGS.useBlizzardTheme = false
    end
    if setting == "MountsPerRow" or setting == nil then
        MCL_SETTINGS.mountsPerRow = 12
    end
end

if MCL_SETTINGS == nil then
    MCLcore.Function:resetToDefault()
end

-- Ensure mountsPerRow setting exists for existing users
if MCL_SETTINGS.mountsPerRow == nil then
    MCL_SETTINGS.mountsPerRow = 12
end

-- Tables Mounts into Global List
function MCL_functions:TableMounts(id, frame, section, category)
    local mount = {
        id = id,
        frame = frame,
        section =  section,
        category = category,
    }
    table.insert(MCLcore.mounts, mount)
end

function MCL_functions:simplearmoryLink()
    local region = GetCVar("portal")

    local realmName = GetRealmName()

    local playerName = UnitName("player")

    local string = "https://simplearmory.com/#/"..region.."/"..realmName.."/"..playerName

    KethoEditBox_Show(string)

end

function MCL_functions:dfaLink()
    local region = GetCVar("portal")

    local realmName = GetRealmName()

    local playerName = UnitName("player")

    local string = "https://www.dataforazeroth.com/characters/"..region.."/"..realmName.."/"..playerName

    KethoEditBox_Show(string)

end

function MCL_functions:compareLink()
    local region = GetCVar("portal")

    local realmName = GetRealmName()

    local playerName = UnitName("player")
    local targetName, targetRealm
    if UnitIsPlayer("target") then
        targetName, targetRealm = UnitName("target")
        if targetRealm == nil then
            targetRealm = realmName
        end
    else
        KethoEditBox_Show("挂载需要目标")
        return
    end
    
    local string = "https://wow-mcl.herokuapp.com/?realma="..region.."."..realmName.."&charactera="..playerName.."&realmb="..region.."."..targetRealm.."&characterb="..targetName
    
    KethoEditBox_Show(string)
end


function KethoEditBox_Show(text)
    if not KethoEditBox then
        local f = CreateFrame("Frame", "KethoEditBox", UIParent, "DialogBoxFrame")
        f:SetPoint("CENTER")
        f:SetSize(700, 100)
        
        f:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
            edgeFile = "Interface\\PVPFrame\\UI-Character-PVP-Highlight", -- this one is neat
            edgeSize = 16,
            insets = { left = 8, right = 6, top = 8, bottom = 8 },
        })
        f:SetBackdropBorderColor(0, .44, .87, 0.5) -- darkblue
        
        -- Movable
        f:SetMovable(true)
        f:SetClampedToScreen(true)
        f:SetScript("OnMouseDown", function(self, button)
            if button == "LeftButton" then
                self:StartMoving()
            end
        end)
        f:SetScript("OnMouseUp", f.StopMovingOrSizing)
        
        -- ScrollFrame
        local sf = CreateFrame("ScrollFrame", "KethoEditBoxScrollFrame", KethoEditBox, "UIPanelScrollFrameTemplate")
        sf:SetPoint("LEFT", 16, 0)
        sf:SetPoint("RIGHT", -32, 0)
        sf:SetPoint("TOP", 0, -16)
        sf:SetPoint("BOTTOM", KethoEditBoxButton, "TOP", 0, 0)
        
        -- EditBox
        local eb = CreateFrame("EditBox", "KethoEditBoxEditBox", KethoEditBoxScrollFrame)
        eb:SetSize(sf:GetSize())
        eb:SetMultiLine(true)
        eb:SetAutoFocus(false) -- dont automatically focus
        eb:SetFontObject("ChatFontNormal")
        eb:SetScript("OnEscapePressed", function() f:Hide() end)
        sf:SetScrollChild(eb)
        
        -- Resizable
        f:SetResizable(true)
        f:SetFrameStrata("HIGH")
        
        f:Show()
    end
    
    if text then
        KethoEditBoxEditBox:SetText(text)
    end
    KethoEditBox:Show()
    MCLcore.MCL_MF:Hide()
end

function MCL_functions:initSections()
    -- * --------------------------------
    -- * Create variables and assign strings to each section.
    -- * --------------------------------

    local faction = MCL_functions:getFaction()
    MCLcore.sections = {}

    for i, v in ipairs(MCLcore.sectionNames) do
        -- Skip opposite faction section
        if v.name ~= faction then
            table.insert(MCLcore.sections, v)
        end
    end

    MCLcore.MCL_MF_Nav = MCLcore.Frames:createNavFrame(MCLcore.MCL_MF, MCLL["Sections"])

    -- Create the overview parent frame before SetTabs
    if not MCLcore.overview or not MCLcore.overview:IsObjectType("Frame") then
        -- Use the same width calculations from frames.lua for consistency
        local main_frame_width = 1250  -- Match the width from frames.lua
        MCLcore.overview = CreateFrame("Frame", nil, MCL_mainFrame.ScrollChild, "BackdropTemplate")
        MCLcore.overview:SetSize(main_frame_width - 60, 550)  -- Use consistent width calculation
        MCLcore.overview:SetPoint("TOPLEFT", MCL_mainFrame.ScrollChild, "TOPLEFT", 30, 0)  -- Consistent with other content frames
        MCLcore.overview:SetBackdropColor(0, 0, 0, 0)
    end
    -- Build the overview content into the overview frame
    MCLcore.Frames:createOverviewCategory(MCLcore.sections, MCLcore.overview)

    local tabFrames, numTabs = MCLcore.Frames:SetTabs() 

    MCLcore.sectionFrames = {}
    for i=1, numTabs do
        -- The section frames are already created in SetTabs, just reference them
        if tabFrames and tabFrames[i] then
            table.insert(MCLcore.sectionFrames, tabFrames[i])
        end
    end    
end


function MCL_functions:GetCollectedMounts()
    local mounts = {}
    for k,v in pairs(C_MountJournal.GetMountIDs()) do
        local mountName, spellID, icon, _, isUsable, _, _, isFactionSpecific, faction, _, isCollected, mountID = C_MountJournal.GetMountInfoByID(v)
        if isCollected then
            if faction then
                if faction == 1 then
                    faction = "Alliance"
                else
                    faction = "Horde"
                end
            end
            if (isFactionSpecific == false) or (isFactionSpecific == true and faction == UnitFactionGroup("player")) then                     
                table.insert(mounts, mountID)
            end   
        end
    end
    for k,v in pairs(mounts) do
        local exists = false
        for kk,vv in pairs(MCLcore.mountCheck) do
            if v == vv then
                exists = true
            end
        end
    end
end

function MCL_functions:CreateBorder(frame, side)
    frame.borders = frame:CreateLine(nil, "BACKGROUND", nil, 0)
    local l = frame.borders
    l:SetThickness(1)
    l:SetColorTexture(1, 1, 1, 0.4)
	l:SetStartPoint("BOTTOM"..side)
	l:SetEndPoint("TOP"..side)
    return frame
end


function MCL_functions:CreateFullBorder(self)
    if not self.borders then
        self.borders = {}
        for i=1, 4 do
            self.borders[i] = self:CreateLine(nil, "BACKGROUND", nil, 0)
            local l = self.borders[i]
            l:SetThickness(2)
            l:SetColorTexture(0, 0, 0, 0.7)
            if i==1 then
                l:SetStartPoint("TOPLEFT", 0, 1)
                l:SetEndPoint("TOPRIGHT", 0, 1)
            elseif i==2 then
                l:SetStartPoint("TOPRIGHT", 0, 1)
                l:SetEndPoint("BOTTOMRIGHT", 0, 2)
            elseif i==3 then
                l:SetStartPoint("BOTTOMRIGHT", 0, 2)
                l:SetEndPoint("BOTTOMLEFT", 0, 2)
            else
                l:SetStartPoint("BOTTOMLEFT", 0, 2)
                l:SetEndPoint("TOPLEFT", 0, 1)
            end
        end
    end
end

function MCL_functions:getTableLength(set)
    local i = 1
    for k,v in pairs(set) do
        i = i+1
    end
    return i
end

function MCL_functions:SetMouseClickFunctionalityPin(frame, mountID, mountName, itemLink, spellID, isSteadyFlight)
    frame:SetScript("OnMouseDown", function(self, button)
        if IsControlKeyDown() then
            if button == 'LeftButton' then
                DressUpMount(mountID)
            elseif button == 'RightButton' then
                -- Allow pinning of both collected and uncollected mounts
                -- Initialize MCL_PINNED if it doesn't exist
                if not MCL_PINNED then
                    MCL_PINNED = {}
                end
                
                local pin = false
                local pin_count = table.getn(MCL_PINNED)
                if pin_count ~= nil then                     
                    for i=1, pin_count do                      
                        if MCL_PINNED[i].mountID == "m"..mountID then
                            pin = i
                            break
                        end
                    end
                end
                
                -- Only remove if we found a valid pin index
                if pin ~= false then
                    table.remove(MCL_PINNED, pin)
                    
                    -- Set flag to indicate pinned mounts have been modified
                    MCLcore.pinnedMountsChanged = true
                    
                    -- Update all pin icons for this mount
                    MCLcore.Function:UpdateAllPinIcons(mountID)
                    
                    -- Refresh the pinned section by recreating it
                    if _G["PinnedFrame"] then
                        -- Clear existing mount frames more thoroughly
                        if MCLcore.mountFrames[1] then
                            for _, oldFrame in ipairs(MCLcore.mountFrames[1]) do
                                if oldFrame and oldFrame:GetParent() then
                                    oldFrame:Hide()
                                    oldFrame:SetParent(nil)
                                end
                            end
                        end
                        
                        -- Also clear any untracked children of PinnedFrame
                        local children = {_G["PinnedFrame"]:GetChildren()}
                        for _, child in ipairs(children) do
                            if child and child:IsObjectType("Button") and child.mountID then
                                child:Hide()
                                child:SetParent(nil)
                            end
                        end
                        
                        MCLcore.mountFrames[1] = {}
                        
                        -- Clean up invalid pinned mounts before recreating
                        MCLcore.Function:CleanupInvalidPinnedMounts()
                        
                        -- Recreate the pinned section content
                        local overflow, mountFrame = MCLcore.Function:CreateMountsForCategory(MCL_PINNED, _G["PinnedFrame"], 30, _G["PinnedTab"], true, true)
                        MCLcore.mountFrames[1] = mountFrame
                    end
                end
            end               
        elseif button=='LeftButton' then
            if IsShiftKeyDown() then
                -- Handle shift-click to link mount in chat
                if itemLink and ChatEdit_GetActiveWindow() then
                    ChatEdit_InsertLink(itemLink)
                elseif spellID then
                    local spellLink = C_Spell.GetSpellLink(spellID)
                    if spellLink and ChatEdit_GetActiveWindow() then
                        ChatEdit_InsertLink(spellLink)
                    end
                end
            end
        elseif button == 'RightButton' and not IsControlKeyDown() then
            -- Right-click to show/hide mount card
            if MCLcore and MCLcore.MountCard then
                local mountData = {
                    mountID = mountID,
                    id = mountID,
                    name = mountName,
                    category = frame.category,
                    section = frame.section
                }
                MCLcore.MountCard.Toggle(mountData, frame)
            end
        end
        if button == 'MiddleButton' then
            -- Middle click to cast mount if it's collected
            if IsMountCollected(mountID) then
                CastSpellByName(mountName);
            end
        end
    end)
end

function MCL_functions:SetMouseClickFunctionality(frame, mountID, mountName, itemLink, spellID, isSteadyFlight) -- * Mount Frames

    frame:SetScript("OnMouseDown", function(self, button)
        if IsControlKeyDown() then
            if button == 'LeftButton' then
                DressUpMount(mountID)
            elseif button == 'RightButton' then
                -- Allow pinning of both collected and uncollected mounts
                -- Initialize MCL_PINNED if it doesn't exist
                if not MCL_PINNED then
                    MCL_PINNED = {}
                end
                
                local pin = false
                local pin_count = table.getn(MCL_PINNED)
                if pin_count ~= nil then                     
                    for i=1, pin_count do
                        if MCL_PINNED[i].mountID == "m"..mountID then
                            pin = i
                        end
                    end
                end
                if pin ~= false then
                    if frame.pin then
                        frame.pin:SetAlpha(0)
                    end
                    table.remove(MCL_PINNED, pin)
                    
                    -- Set flag to indicate pinned mounts have been modified
                    MCLcore.pinnedMountsChanged = true
                    
                    -- Update all pin icons for this mount
                    MCLcore.Function:UpdateAllPinIcons(mountID)
                    local index = 0
                    -- Initialize MCLcore.mountFrames[1] if it doesn't exist
                    if not MCLcore.mountFrames[1] then
                        MCLcore.mountFrames[1] = {}
                    end
                    for k,v in pairs(MCLcore.mountFrames[1]) do
                        index = index + 1
                        if tostring(v.mountID) == tostring(mountID) then
                            MCLcore.mountFrames[1][index]:Hide()                                
                            table.remove(MCLcore.mountFrames[1],  index)
                            for kk,vv in ipairs(MCLcore.mountFrames[1]) do
                                if kk == 1 then
                                    vv:SetParent(_G["PinnedFrame"])
                                    vv:Show()
                                else
                                    vv:SetParent(MCLcore.mountFrames[1][kk-1])
                                    vv:Show()
                                end
                            end                                
                        end
                    end
                    
                    -- Refresh the pinned tab layout after unpinning
                    if MCL_frames and MCL_frames.RefreshLayout then
                        -- Check if we're currently viewing the Pinned tab
                        local isPinnedTabActive = false
                        if MCLcore.currentlySelectedTab and MCLcore.currentlySelectedTab.section and MCLcore.currentlySelectedTab.section.name == "Pinned" then
                            isPinnedTabActive = true
                        end
                        
                        -- Refresh the layout to update the pinned content
                        MCLcore.Frames:RefreshLayout()
                        
                        -- If we were on the Pinned tab, reselect it
                        if isPinnedTabActive and MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                            for _, tab in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                                if tab.section and tab.section.name == "Pinned" then
                                    tab:GetScript("OnClick")(tab)
                                    break
                                end
                            end
                        end
                    end
                else	                            
                    if frame.pin then
                        frame.pin:SetAlpha(1)
                    end
                    local t = {
                        mountID = "m"..mountID,
                        category = frame.category,
                        section = frame.section
                    }
                    if pin_count == nil then
                        MCL_PINNED[1] = t
                    else
                        MCL_PINNED[pin_count+1] = t
                    end
                    
                    -- Set flag to indicate pinned mounts have been modified
                    MCLcore.pinnedMountsChanged = true
                    
                    MCLcore.Function:CreatePinnedMount(mountID, frame.category, frame.section)
                    -- Update all pin icons for this mount
                    MCLcore.Function:UpdateAllPinIcons(mountID)

                    -- Refresh the pinned tab layout after pinning
                    C_Timer.After(0.1, function()
                        if MCL_frames and MCL_frames.SetTabs then
                            -- Check if we're currently viewing the Pinned tab
                            local isPinnedTabActive = false
                            if MCLcore.currentlySelectedTab and MCLcore.currentlySelectedTab.section and MCLcore.currentlySelectedTab.section.name == "Pinned" then
                                isPinnedTabActive = true
                            end
                            
                            -- Refresh the tabs to update the pinned content
                            MCLcore.Frames:SetTabs()
                            
                            -- If we were on the Pinned tab, reselect it
                            if isPinnedTabActive and MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                                for _, tab in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                                    if tab.section and tab.section.name == "Pinned" then
                                        tab:GetScript("OnClick")(tab)
                                        break
                                    end
                                end
                            end
                        end
                    end)

                end
            end               
        elseif button=='LeftButton' then
            if IsShiftKeyDown() then
                -- Handle shift-click to link mount in chat
                if itemLink and ChatEdit_GetActiveWindow() then
                    ChatEdit_InsertLink(itemLink)
                elseif spellID then
                    local spellLink = C_Spell.GetSpellLink(spellID)
                    if spellLink and ChatEdit_GetActiveWindow() then
                        ChatEdit_InsertLink(spellLink)
                    end
                end
            elseif isSteadyFlight then
                if frame.pop and frame.pop:IsShown() then 
                    frame.pop:Hide()
                elseif frame.pop then
                    frame.pop:Show()
                end
            else
                -- Don't add conflicting OnClick handlers here since OnMouseDown is already handling mouse events
                -- Shift-click functionality is handled in SetMouseClickFunctionality
            end
        elseif button == 'RightButton' and not IsControlKeyDown() then
            -- Right-click to show/hide mount card
            if MCLcore and MCLcore.MountCard then
                local mountData = {
                    mountID = mountID,
                    id = mountID,
                    name = mountName,
                    category = frame.category,
                    section = frame.section
                }
                MCLcore.MountCard.Toggle(mountData, frame)
            end
        end
        if button == 'MiddleButton' then
            -- Middle click to cast mount if it's collected
            if IsMountCollected(mountID) then
                CastSpellByName(mountName);
            end
        end
    end)
end

function MCL_functions:LinkMountItem(id, frame, pin, dragonriding)
	--Adding a tooltip for mounts
    if string.sub(id, 1, 1) == "m" then
        id = string.sub(id, 2, -1)
        local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, isSteadyFlight = C_MountJournal.GetMountInfoByID(id)

        frame:HookScript("OnEnter", function()
            GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT")
            if (spellID) then
                GameTooltip:SetSpellByID(spellID)
                
                -- Use MCL's category/section information if available
                local sourceText = "Unknown"
                if frame.section and frame.category then
                    if frame.section ~= "Unknown" and frame.category ~= "Unknown" then
                        sourceText = frame.section .. " - " .. frame.category
                    elseif frame.section ~= "Unknown" then
                        sourceText = frame.section
                    elseif frame.category ~= "Unknown" then
                        sourceText = frame.category
                    end
                end
                
                -- Fallback to Blizzard's source if MCL info is not available
                if sourceText == "Unknown" then
                    _, description, source, _, mountTypeID, _, _, _, _ = C_MountJournal.GetMountInfoExtraByID(id)
                    if source and source ~= "" then
                        sourceText = source
                    end
                end
                
                GameTooltip:AddLine(sourceText)
                GameTooltip:Show()
                frame:SetHyperlinksEnabled(true)
            end
            
            -- Show MountCard on hover
            if MCLcore and MCLcore.MountCard then
                local mountData = {
                    mountID = mountID,
                    id = mountID,
                    name = mountName,
                    category = frame.category,
                    section = frame.section
                }
                MCLcore.MountCard.ShowOnHover(mountData, frame, 0.2)  -- Reduced from 0.8 to 0.2
            end
        end)
        frame:HookScript("OnLeave", function()
            GameTooltip:Hide()
            -- Note: MountCard is now persistent, so we don't hide it on hover end
        end)
        if pin == true then
            MCLcore.Function:SetMouseClickFunctionalityPin(frame, mountID, mountName, itemLink, spellID, isSteadyFlight)
        else
            MCLcore.Function:SetMouseClickFunctionality(frame, mountID, mountName, itemLink, spellID, isSteadyFlight)
        end  
    else
        local item, itemLink = GetItemInfo(id);
        if dragonriding then
            frame:HookScript("OnEnter", function()
                GameTooltip:SetOwner(frame, "ANCHOR_TOPLEFT")
                if (id) then
                    GameTooltip:SetItemByID(id)
                    
                    -- Use MCL's category/section information if available
                    local sourceText = "Unknown"
                    if frame.section and frame.category then
                        if frame.section ~= "Unknown" and frame.category ~= "Unknown" then
                            sourceText = frame.section .. " - " .. frame.category
                        elseif frame.section ~= "Unknown" then
                            sourceText = frame.section
                        elseif frame.category ~= "Unknown" then
                            sourceText = frame.category
                        end
                    end
                    
                    -- If still unknown, use the passed source parameter
                    if sourceText == "Unknown" and frame.source then
                        sourceText = frame.source
                    end
                    
                    GameTooltip:AddLine(sourceText)
                    GameTooltip:Show()
                    frame:SetHyperlinksEnabled(true)
                end
                
                -- Show MountCard on hover for dragonriding mounts
                if MCLcore and MCLcore.MountCard then
                    local mountData = {
                        mountID = id,
                        id = id,
                        name = item or "Unknown Mount",
                        category = frame.category,
                        section = frame.section
                    }
                    MCLcore.MountCard.ShowOnHover(mountData, frame, 0.2)  -- Reduced from 0.8 to 0.2
                end
            end)
            frame:HookScript("OnLeave", function()
                GameTooltip:Hide()
                -- Note: MountCard is now persistent, so we don't hide it on hover end
            end)

        else
            local mountID = C_MountJournal.GetMountFromItem(id)
            local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, isSteadyFlight = C_MountJournal.GetMountInfoByID(mountID)
        
            -- Special handling for fallback cases (negative IDs)
            if not mountID and type(id) == "number" and id < 0 then
                local originalItemId = -id
                local itemName, itemLink = GetItemInfo(originalItemId)
                
                frame:HookScript("OnEnter", function()
                    GameTooltip:SetOwner(frame, "ANCHOR_TOP")
                    if itemLink then
                        GameTooltip:SetHyperlink(itemLink)
                        GameTooltip:AddLine("|cFFFF0000[MCL] Mount data not fully loaded|r")
                        GameTooltip:AddLine("|cFFFFFF00Try reloading UI or restarting game|r")
                        GameTooltip:Show()
                        frame:SetHyperlinksEnabled(true)
                    else
                        GameTooltip:SetText(string.format("Item ID: %d", originalItemId))
                        GameTooltip:AddLine("|cFFFF0000[MCL] Mount data not available|r")
                        GameTooltip:Show()
                    end
                end)
                frame:HookScript("OnLeave", function()
                    GameTooltip:Hide()
                end)
                return
            end
            
            frame:HookScript("OnEnter", function()
                GameTooltip:SetOwner(frame, "ANCHOR_TOP")
                if (itemLink) then
                    frame:SetHyperlinksEnabled(true)
                    GameTooltip:SetHyperlink(itemLink)
                    
                    -- Use MCL's category/section information if available
                    local sourceText = "Unknown"
                    if frame.section and frame.category then
                        if frame.section ~= "Unknown" and frame.category ~= "Unknown" then
                            sourceText = frame.section .. " - " .. frame.category
                        elseif frame.section ~= "Unknown" then
                            sourceText = frame.section
                        elseif frame.category ~= "Unknown" then
                            sourceText = frame.category
                        end
                    end
                    
                    -- Fallback to Blizzard's source if MCL info is not available
                    if sourceText == "Unknown" then
                        _, description, source, _, mountTypeID, _, _, _, _ = C_MountJournal.GetMountInfoExtraByID(mountID)
                        if source and source ~= "" then
                            sourceText = source
                        end
                    end
                    
                    GameTooltip:AddLine(sourceText)
                    GameTooltip:Show()
                end
                
                -- Show MountCard on hover for item-based mounts
                if MCLcore and MCLcore.MountCard and mountID then
                    local mountData = {
                        mountID = mountID,
                        id = mountID,
                        name = mountName,
                        category = frame.category,
                        section = frame.section
                    }
                    MCLcore.MountCard.ShowOnHover(mountData, frame, 0.2)  -- Reduced from 0.8 to 0.2
                end
            end)
            frame:HookScript("OnLeave", function()
                GameTooltip:Hide()
                -- Note: MountCard is now persistent, so we don't hide it on hover end
            end)
            if pin == true then
                MCLcore.Function:SetMouseClickFunctionalityPin(frame, mountID, mountName, itemLink, _, isSteadyFlight)
            else
                MCLcore.Function:SetMouseClickFunctionality(frame, mountID, mountName, itemLink, _, isSteadyFlight)
            end
        end
    end
     
end


function MCL_functions:CompareMountJournal()
    local mounts = {}
    local i = 1
    for k,v in pairs(C_MountJournal.GetMountIDs()) do
        mounts[i] = v
        for kk,vv in pairs(MCLcore.mounts) do
            if vv.id == mounts[i] then
                mounts[i] = nil
            end
        end
    end
    for x,y in ipairs(mounts) do
        if y ~= nil then
            local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(y)
        end
    end
end


function MCL_functions:CheckIfPinned(mountID)
    if MCL_PINNED == nil then
        MCL_PINNED = {}
    end
    for k,v in pairs(MCL_PINNED) do
        if v.mountID == mountID then
            return true, k
        end
    end
    return false, nil
end

function MCL_functions:CleanupInvalidPinnedMounts()
    if not MCL_PINNED then
        MCL_PINNED = {}
        return
    end
    
    local validPinnedMounts = {}
    local removedCount = 0
    
    for k, v in pairs(MCL_PINNED) do
        if v and v.mountID then
            local mountId = v.mountID
            local mount_Id = nil
            
            -- Extract numeric ID from string format (e.g., "m517" -> 517)
            if string.sub(tostring(mountId), 1, 1) == "m" then
                mount_Id = tonumber(string.sub(tostring(mountId), 2, -1))
            else
                mount_Id = tonumber(mountId)
            end
            
            -- Check if this mount ID is valid by trying to get mount info
            if mount_Id then
                local mountName, spellID, icon = C_MountJournal.GetMountInfoByID(mount_Id)
                
                if mountName and mountName ~= "" then
                    -- Mount is valid, keep it
                    table.insert(validPinnedMounts, v)
                else
                    -- Mount is invalid, remove it
                    removedCount = removedCount + 1
                end
            else
                -- Invalid format, remove it
                removedCount = removedCount + 1
            end
        else
            -- Invalid entry structure, remove it
            removedCount = removedCount + 1
        end
    end
    
    -- Replace MCL_PINNED with cleaned version
    MCL_PINNED = validPinnedMounts
end

function MCL_functions:CreateMountsForCategory(set, relativeFrame, frame_size, tab, skip_total, pin)
    -- Clean up invalid pinned mounts if this is for the pinned section
    if pin and set == MCL_PINNED then
        MCLcore.Function:CleanupInvalidPinnedMounts()
        -- Update the set to use the cleaned pinned mounts
        set = MCL_PINNED
    end
    
    local category = relativeFrame
    local previous_frame = relativeFrame
    local count = 0
    local first_frame
    local overflow = 0
    local mountFrames = {}
    local val
    local mountName, spellID, icon, _, _, sourceType, _, isFactionSpecific, faction, _, isCollected, mountID, sourceText, isSteadyFlight
    local invalidMounts = {}  -- Track invalid mounts

    for kk,vv in pairs(set) do
        local mount_Id
        local shouldProcessMount = true  -- Control flag
        
        if pin then
            val = vv.mountID
        else
            val = vv
        end

        -- Use a simpler mount ID extraction
        if pin then
            val = vv.mountID
            -- For pinned mounts, extract the numeric ID
            if string.sub(tostring(val), 1, 1) == "m" then
                mount_Id = tonumber(string.sub(tostring(val), 2, -1))
            else
                mount_Id = tonumber(val)
            end
        else
            val = vv
            mount_Id = MCLcore.Function:GetMountID(val)
        end
        
        if not mount_Id then
            -- Mount is invalid, skip it and track for debugging
            table.insert(invalidMounts, {id = val, context = "CreateMountsForCategory"})
            shouldProcessMount = false
        end

        if shouldProcessMount then
            local success = false
            
            if string.sub(tostring(val), 1, 1) == "m" then
                -- mount_Id was already extracted above, don't override it
                mountName, spellID, icon, _, _, sourceType, _, isFactionSpecific, faction, _, isCollected, mountID, isSteadyFlight = C_MountJournal.GetMountInfoByID(mount_Id)
                if mountName then
                    -- Get the source text from the extra info
                    local _, description, source = C_MountJournal.GetMountInfoExtraByID(mount_Id)
                    sourceText = source or "Unknown"
                    success = true
                else
                    table.insert(invalidMounts, {id = val, context = "Mount info retrieval failed"})
                    shouldProcessMount = false
                end
            else
                mount_Id = C_MountJournal.GetMountFromItem(val)
                if mount_Id then
                    mountName, spellID, icon, _, _, sourceType, _, isFactionSpecific, faction, _, isCollected, mountID, isSteadyFlight = C_MountJournal.GetMountInfoByID(mount_Id)
                    if mountName then
                        -- Get the source text from the extra info
                        local _, description, source = C_MountJournal.GetMountInfoExtraByID(mount_Id)
                        sourceText = source or "Unknown"
                        success = true
                    else
                        table.insert(invalidMounts, {id = val, context = "Item-based mount info retrieval failed"})
                        shouldProcessMount = false
                    end
                else
                    table.insert(invalidMounts, {id = val, context = "No mount from item"})
                    shouldProcessMount = false
                end
            end
        end

        if shouldProcessMount then
            local faction, faction_specific = IsMountFactionSpecific(val)
            if faction then
                if faction == 0 then
                    faction = "Horde"
                elseif faction == 1 then
                    faction = "Alliance"
                end
            end
            
            -- For pinned mounts, don't apply hiding filters since user specifically wants to see them
            local shouldHideCollected = false
            local factionAllowed = true
            
            if not pin then
                -- Only apply filters for non-pinned mounts
                shouldHideCollected = MCL_SETTINGS.hideCollectedMounts and IsMountCollected(mount_Id)
                factionAllowed = (faction_specific == false) or (faction_specific == true and faction == UnitFactionGroup("player"))
            end
            
            if not shouldHideCollected and factionAllowed then
                local mountsPerRow = MCL_SETTINGS.mountsPerRow or 12
                if count == mountsPerRow then
                    overflow = overflow + frame_size + 10
                end            
                local frame = CreateFrame("Button", nil, relativeFrame, "BackdropTemplate");
                frame:SetWidth(frame_size);
                frame:SetHeight(frame_size);

                frame:SetBackdrop({
                    edgeFile = [[Interface\Buttons\WHITE8x8]],
                    edgeSize = frame_size + 2,
                    bgFile = [[Interface\Buttons\WHITE8x8]],              
                })

                frame.pin = frame:CreateTexture(nil, "OVERLAY")
                frame.pin:SetWidth(16)
                frame.pin:SetHeight(16)
                frame.pin:SetTexture("Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pin.blp")
                frame.pin:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -2, -2)
                frame.pin:SetAlpha(0)

                -- Handle category and section assignment based on context
                if pin and vv.category and vv.section then
                    frame.category = vv.category
                    frame.section = vv.section
                elseif category and category.category and category.section then
                    frame.category = category.category
                    frame.section = category.section
                else
                    frame.category = "Unknown"
                    frame.section = "Unknown"
                end

                frame.dragonRidable = isSteadyFlight

                frame:SetBackdropBorderColor(1, 0, 0, 0.03)
                frame:SetBackdropColor(0, 0, 0, MCL_SETTINGS.opacity)

                frame.tex = frame:CreateTexture()
                frame.tex:SetSize(frame_size, frame_size)
                frame.tex:SetPoint("LEFT", frame, "LEFT", 8, 0)

                if string.sub(tostring(val), 1, 1) == "m" then
                    frame.tex:SetTexture(icon)
                else
                    frame.tex:SetTexture(GetItemIcon(val))
                end
        
                frame.tex:SetVertexColor(0.75, 0.75, 0.75, 0.3);

                frame.mountID = mount_Id
                frame.itemID = val            

                local pin_check = MCLcore.Function:CheckIfPinned("m"..frame.mountID)
                if pin_check == true then
                    frame.pin:SetAlpha(1)
                else
                    frame.pin:SetAlpha(0)
                end              

                if pin then
                    local y = 30
                    if previous_frame == category then
                        y = 0
                    end

                    -- Mount Name - Primary text (aligned to frame edge, not icon)
                    frame.mountName = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
                    frame.mountName:SetPoint("TOPLEFT", frame, "TOPLEFT", 46, -8)
                    frame.mountName:SetText(mountName)
                    
                    -- Section line (below pin icon on the right)
                    frame.sectionLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                    frame.sectionLine:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -30, -8)
                    frame.sectionLine:SetText(vv.section)

                    -- Category line (under section on the right)
                    frame.categoryLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                    frame.categoryLine:SetPoint("TOPRIGHT", frame.sectionLine, "BOTTOMRIGHT", 0, -2)
                    frame.categoryLine:SetText(vv.category)
                    
                    -- Acquisition line (under mount name, full width)
                    frame.acquisitionLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
                    frame.acquisitionLine:SetPoint("TOPLEFT", frame.mountName, "BOTTOMLEFT", 0, -4)
                    frame.acquisitionLine:SetText(sourceText or "Unknown")
                    frame.acquisitionLine:SetJustifyH("LEFT")
                    frame.acquisitionLine:SetWordWrap(true)
                    frame.acquisitionLine:SetWidth(600)
                    
                    -- Use WoW standard tooltip border and background
                    frame:SetBackdrop({
                        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
                        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                        edgeSize = 16,
                        insets = { left = 4, right = 4, top = 4, bottom = 4 }
                    })
                    
                    -- Bottom border line for separation
                    frame.border = frame:CreateLine(nil, "BACKGROUND", nil, 0)
                    frame.border:SetThickness(1)
                    frame.border:SetColorTexture(0.5, 0.5, 0.5, 0.5)
                    frame.border:SetStartPoint("BOTTOMLEFT", 4, 4)
                    frame.border:SetEndPoint("BOTTOMRIGHT", -4, 4)
                    
                    frame:SetWidth(815)
                    frame:SetHeight(75)
                    
                    local positionRelativeTo = previous_frame
                    local isFirstFrame = (previous_frame == category)
                    
                    C_Timer.After(0, function()
                        local mountNameHeight = frame.mountName:GetStringHeight()
                        local acquisitionHeight = frame.acquisitionLine:GetStringHeight()
                        
                        local contentHeight = 8 + mountNameHeight + 4 + acquisitionHeight + 20
                        local finalHeight = math.max(contentHeight, 75)
                        frame:SetHeight(finalHeight)
                        
                        if isFirstFrame then
                            frame:SetPoint("BOTTOMLEFT", positionRelativeTo, "BOTTOMLEFT", 10, -finalHeight + 20)
                        else
                            frame:SetPoint("BOTTOMLEFT", positionRelativeTo, "BOTTOMLEFT", 0, -finalHeight - 10)
                        end
                    end)
                    
                    -- Apply collection status styling
                    if IsMountCollected(mount_Id) then
                        frame:SetBackdropBorderColor(0, 0.8, 0, 0.8)
                        frame:SetBackdropColor(0, 0.2, 0, 0.15)
                        frame.tex:SetVertexColor(1, 1, 1, 1)
                        frame.mountName:SetTextColor(0, 1, 0)
                    else
                        frame:SetBackdropBorderColor(0.8, 0.3, 0.3, 0.8)
                        frame:SetBackdropColor(0.2, 0.05, 0.05, 0.15)
                        frame.tex:SetVertexColor(0.6, 0.6, 0.6, 0.8)
                        frame.mountName:SetTextColor(0.9, 0.9, 0.9)
                    end

                    frame.pin:SetSize(20, 20)
                    frame.pin:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -8, -8)
                    
                    -- Add hover effects
                    frame:SetScript("OnEnter", function(self)
                        self:SetBackdropColor(1, 1, 1, 0.1)
                        if self.mountName then
                            self.mountName:SetTextColor(1, 1, 1)
                        end
                    end)
                    
                    frame:SetScript("OnLeave", function(self)
                        if IsMountCollected(mount_Id) then
                            self:SetBackdropColor(0, 0.2, 0, 0.15)
                            if self.mountName then
                                self.mountName:SetTextColor(0, 1, 0)
                            end
                        else
                            self:SetBackdropColor(0.2, 0.05, 0.05, 0.15)
                            if self.mountName then
                                self.mountName:SetTextColor(0.9, 0.9, 0.9)
                            end
                        end
                    end)

                    previous_frame = frame
                elseif count == (MCL_SETTINGS.mountsPerRow or 12) then
                    frame:SetPoint("BOTTOMLEFT", first_frame, "BOTTOMLEFT", 0, -overflow);
                    count = 0           
                elseif relativeFrame == category then
                    frame:SetPoint("BOTTOMLEFT", category, "BOTTOMLEFT", 10, -35);
                    first_frame = frame
                else
                    frame:SetPoint("RIGHT", relativeFrame, "RIGHT", frame_size+10, 0);
                end          

                MCLcore.Function:LinkMountItem(val, frame, pin)

                relativeFrame = frame
                count = count + 1
                if skip_total == true then
                else
                    if tab then
                        MCL_functions:TableMounts(mount_Id, frame, tab, category)
                    end
                end
                table.insert(mountFrames, frame)
            end  
        end  -- End of shouldProcessMount condition
    end
        
    return overflow, mountFrames
end


function MCL_functions:CreatePinnedMount(mount_Id, category, section)

    local frame_size = 30
    local mountFrames = {}
    
    -- Initialize MCLcore.mountFrames[1] if it doesn't exist
    if not MCLcore.mountFrames[1] then
        MCLcore.mountFrames[1] = {}
    end
    
    local total_pinned = table.getn(MCLcore.mountFrames[1])
    if total_pinned == 0 then
        -- Initialize MCL_PINNED if it doesn't exist
        if not MCL_PINNED then
            MCL_PINNED = {}
        end
        
        -- Clean up invalid pinned mounts before creating
        MCLcore.Function:CleanupInvalidPinnedMounts()
        
        local overflow, mountFrame = MCLcore.Function:CreateMountsForCategory(MCL_PINNED, _G["PinnedFrame"], 30, _G["PinnedTab"], true, true)
        MCLcore.mountFrames[1] = mountFrame
    else
        local relativeFrame = MCLcore.mountFrames[1][total_pinned]

        local mountName, spellID, icon, _, _, sourceType, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(mount_Id)
        
        -- Get the actual source from the game API
        local _, _, sourceText = C_MountJournal.GetMountInfoExtraByID(mount_Id)
        sourceText = sourceText or "Unknown"

        -- Create frame parented to the Pinned section, not to the previous frame
        local frame = CreateFrame("Button", nil, _G["PinnedFrame"], "BackdropTemplate");
        frame:SetWidth(frame_size);
        frame:SetHeight(frame_size);
        frame:SetBackdrop({
            -- edgeFile = [[Interface\Buttons\WHITE8x8]],
            -- edgeSize = frame_size + 2,
            bgFile = [[Interface\Buttons\WHITE8x8]],    
        })

        frame.pin = frame:CreateTexture(nil, "OVERLAY")
        frame.pin:SetWidth(16)
        frame.pin:SetHeight(16)
        frame.pin:SetTexture("Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pin.blp")
        frame.pin:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -2, -2)
        frame.pin:SetAlpha(1)

        -- Icon with horizontal padding
        frame.tex = frame:CreateTexture()
        frame.tex:SetSize(frame_size, frame_size)
        frame.tex:SetPoint("LEFT", frame, "LEFT", 8, 0)  -- 8px horizontal padding from left edge
        local mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID, _ = C_MountJournal.GetMountInfoByID(mount_Id)
        frame.tex:SetTexture(icon)

        frame.tex:SetVertexColor(0.75, 0.75, 0.75, 0.3);        

        frame.category = category
        frame.section = section

        -- Mount Name - Primary text (aligned to frame edge, not icon)
        frame.mountName = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
        frame.mountName:SetPoint("TOPLEFT", frame, "TOPLEFT", 46, -8)  -- Aligned to frame edge with padding
        frame.mountName:SetText(mountName)
        
        -- Section line (below pin icon on the right)
        frame.sectionLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        frame.sectionLine:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -30, -8)  -- Below pin icon area
        frame.sectionLine:SetText(section)

        -- Category line (under section on the right)
        frame.categoryLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        frame.categoryLine:SetPoint("TOPRIGHT", frame.sectionLine, "BOTTOMRIGHT", 0, -2)  -- Under section
        frame.categoryLine:SetText(category)
        
        -- Acquisition line (under mount name, full width)
        frame.acquisitionLine = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        frame.acquisitionLine:SetPoint("TOPLEFT", frame.mountName, "BOTTOMLEFT", 0, -4)
        frame.acquisitionLine:SetText(sourceText or "Unknown")  -- Removed "Acquisition:" label
        frame.acquisitionLine:SetJustifyH("LEFT")
        frame.acquisitionLine:SetWordWrap(true)  -- Allow wrapping to show full text
        frame.acquisitionLine:SetWidth(600)  -- Adjust width to not overlap with category section

        -- Use WoW standard tooltip border and background
        frame:SetBackdrop({
            bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 16,
            insets = { left = 4, right = 4, top = 4, bottom = 4 }
        })
        
        -- Bottom border line for separation
        frame.border = frame:CreateLine(nil, "BACKGROUND", nil, 0)
        frame.border:SetThickness(1)
        frame.border:SetColorTexture(0.5, 0.5, 0.5, 0.5)
        frame.border:SetStartPoint("BOTTOMLEFT", 4, 4)
        frame.border:SetEndPoint("BOTTOMRIGHT", -4, 4)
        
        frame:SetWidth(800)  -- Increased width to match pinned instruction bar
        
        -- Set a reasonable minimum height first so text can be laid out
        frame:SetHeight(75)  -- Start with minimum height
        
        -- Force text layout by getting dimensions after initial setup
        C_Timer.After(0, function()
            -- Calculate height based on actual rendered content
            local mountNameHeight = frame.mountName:GetStringHeight()
            local acquisitionHeight = frame.acquisitionLine:GetStringHeight()
            
            local contentHeight = 8 + -- Top padding to mount name
                                mountNameHeight + 4 + -- Mount name + spacing
                                acquisitionHeight + -- Acquisition text (can be multiple lines)
                                20  -- Bottom padding - increased for better spacing
            
            local finalHeight = math.max(contentHeight, 75)  -- Minimum height of 75 for better padding
            -- Set the final calculated height
            frame:SetHeight(finalHeight)
            
            -- Position the frame after height is finalized
            frame:SetPoint("BOTTOMLEFT", relativeFrame, "BOTTOMLEFT", 0, -finalHeight - 10)  -- No x-offset since this is not the first frame
        end)
        
        -- Apply collection status styling - more subtle approach
        if IsMountCollected(mount_Id) then
            -- Collected mount styling
            frame:SetBackdropBorderColor(0, 0.8, 0, 0.8)  -- Green border
            frame:SetBackdropColor(0, 0.2, 0, 0.15)       -- Subtle green background
            frame.tex:SetVertexColor(1, 1, 1, 1)          -- Full color icon
            frame.mountName:SetTextColor(0, 1, 0)         -- Green mount name
        else
            -- Uncollected mount styling
            frame:SetBackdropBorderColor(0.8, 0.3, 0.3, 0.8)  -- Red border
            frame:SetBackdropColor(0.2, 0.05, 0.05, 0.15)     -- Subtle red background
            frame.tex:SetVertexColor(0.6, 0.6, 0.6, 0.8)      -- Slightly dimmed icon
            frame.mountName:SetTextColor(0.9, 0.9, 0.9)       -- Light gray mount name
        end

        -- Enhance pin icon
        frame.pin:SetSize(20, 20)  -- Slightly larger
        frame.pin:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -8, -8)
        frame.pin:SetAlpha(0)

        -- Add hover effects
        frame:SetScript("OnEnter", function(self)
            self:SetBackdropColor(1, 1, 1, 0.1)  -- Subtle white highlight on hover
            if self.mountName then
                self.mountName:SetTextColor(1, 1, 1)  -- White text on hover
            end
        end)
        
        frame:SetScript("OnLeave", function(self)
            -- Restore original colors based on collection status
            if IsMountCollected(mount_Id) then
                self:SetBackdropColor(0, 0.2, 0, 0.15)
                if self.mountName then
                    self.mountName:SetTextColor(0, 1, 0)
                end
            else
                self:SetBackdropColor(0.2, 0.05, 0.05, 0.15)
                if self.mountName then
                    self.mountName:SetTextColor(0.9, 0.9, 0.9)
                end
            end
        end)

        frame.mountID = mount_Id

        MCLcore.Function:LinkMountItem("m"..tostring(mount_Id), frame, true)

        table.insert(MCLcore.mountFrames[1], frame)
  
    end
end

-- Function to force load mount data and handle delayed mount journal loading
function MCL_functions:ForceLoadMountData(itemId)
    -- First try to get the item info to ensure it's cached
    local itemName, itemLink = GetItemInfo(itemId)
    
    -- If item info isn't available, request it and return false to retry later
    if not itemName then
        -- This will cache the item data for future calls
        C_Item.RequestLoadItemDataByID(itemId)
        -- For persistent debugging, create a delayed retry
        C_Timer.After(0.1, function()
            local retryItemName = GetItemInfo(itemId)
            if retryItemName then
                -- Force a mount journal update if item becomes available
                C_MountJournal.GetMountFromItem(itemId)
            end
        end)
        return false, "Item data not cached yet"
    end
    
    -- Try to get mount from item
    local mountId = C_MountJournal.GetMountFromItem(itemId)
    
    if not mountId then
        -- For some old items, they might not be directly associated with mounts
        -- but still exist in the game. Try a different approach.
        return false, "No mount associated with item"
    end
    
    -- Try to get mount info
    local mountName, spellID, icon = C_MountJournal.GetMountInfoByID(mountId)
    
    if not mountName then
        -- Try to force refresh the mount journal
        C_MountJournal.ClearSearchFilters()
        C_Timer.After(0.1, function()
            local retryMountName = C_MountJournal.GetMountInfoByID(mountId)
        end)
        return false, "Mount data not available yet"
    end
    
    return true, {
        mountId = mountId,
        mountName = mountName,
        spellID = spellID,
        icon = icon,
        itemId = itemId,
        itemName = itemName
    }
end

-- Enhanced GetMountID function with force loading
function MCL_functions:GetMountIDWithForceLoad(id)
    local mount_Id
    local inputType = type(id)
    local isStringWithM = (inputType == "string" and string.sub(tostring(id), 1, 1) == "m")
    local isNumber = (inputType == "number")
    
    if isStringWithM then
        mount_Id = tonumber(string.sub(tostring(id), 2, -1))
    elseif isNumber and id > 100000 then
        -- Likely an item ID (large number)
        local success, result = MCLcore.Function:ForceLoadMountData(id)
        if success then
            mount_Id = result.mountId
        else
            -- Fallback to original method
            mount_Id = C_MountJournal.GetMountFromItem(id)
        end
    elseif isNumber and id < 10000 then
        -- Could be either a mount ID or an old item ID
        -- First try as direct mount ID
        local mountName = C_MountJournal.GetMountInfoByID(id)
        if mountName then
            mount_Id = id
        else
            -- Try as item ID
            local success, result = MCLcore.Function:ForceLoadMountData(id)
            if success then
                mount_Id = result.mountId
            else
                -- Last resort - try original item lookup
                mount_Id = C_MountJournal.GetMountFromItem(id)
            end
        end
    else
        -- Default to item lookup with force loading
        local success, result = MCLcore.Function:ForceLoadMountData(id)
        if success then
            mount_Id = result.mountId
        else
            mount_Id = C_MountJournal.GetMountFromItem(id)
        end
    end
    
    return mount_Id
end

-- Main GetMountID function that uses force-load logic for problematic item IDs
function MCL_functions:GetMountID(id)
    local problematicItemIds = {8563, 8595}  -- Add more IDs here as needed
    
    -- Check if this is one of the problematic item IDs that need force loading
    if type(id) == "number" then
        for _, problematicId in ipairs(problematicItemIds) do
            if id == problematicId then
                local mount_Id = MCLcore.Function:GetMountIDWithForceLoad(id)
                if mount_Id then
                    return mount_Id
                else
                    -- If force loading fails, still return the item ID
                    -- This allows the mount to be processed even if the API can't find it
                    -- Use a negative ID to indicate this is a fallback case
                    return -id
                end
            end
        end
    end
    
    -- For non-problematic IDs, use the standard logic
    local mount_Id
    local inputType = type(id)
    local isStringWithM = (inputType == "string" and string.sub(tostring(id), 1, 1) == "m")
    
    if isStringWithM then
        mount_Id = tonumber(string.sub(tostring(id), 2, -1))
    else
        mount_Id = C_MountJournal.GetMountFromItem(id)
    end
    
    return mount_Id
end

function IsMountCollected(id)
    -- Handle negative IDs (fallback cases for problematic items)
    local numericId = tonumber(id)
    if numericId and numericId < 0 then
        -- For fallback cases, we can't determine collection status from the API
        -- so we'll return false (not collected) to show them in the UI
        return false
    end
    
    -- Ensure we have a valid mount ID
    if not id or id == 0 then
        return false
    end
    
    -- Use pcall to safely get mount info
    local success, mountName, spellID, icon, _, _, _, _, isFactionSpecific, faction, _, isCollected, mountID = pcall(C_MountJournal.GetMountInfoByID, id)
    
    if not success or not mountName then
        -- Mount data not available yet, return false but don't cache this result
        return false
    end
    
    return isCollected or false
end

function UpdateBackground(frame)
    local pinned, pin = MCLcore.Function:CheckIfPinned("m"..tostring(frame.mountID))
    if pinned == true then
        table.remove(MCL_PINNED, pin)
    end
    frame:SetBackdropBorderColor(0, 0.45, 0, 0.4)
    frame.tex:SetVertexColor(1, 1, 1, 1);	
end


function UpdateProgressBar(frame, total, collected)
    if not frame then
        return
    end    
    
    if total == nil and collected == nil then
        return frame
    else
        if total == 0 then
            -- Handle zero total case properly
            frame:SetValue(0)
            frame.Text:SetText("0/0 (0%)")
            frame:SetStatusBarColor(0.3, 0.3, 0.3)  -- Dark gray for no data
            return frame
        end
        frame.collected = collected
        frame.total = total
        frame:SetValue((collected/total)*100)
        frame.Text:SetText(collected.."/"..total.." ("..math.floor(((collected/total)*100)).."%)")
        frame.val = (collected/total)*100
    end
    
    if frame.val == nil then
        return frame
    end
    
    if not MCL_SETTINGS or not MCL_SETTINGS.progressColors then
        -- Fallback colors
        if frame.val < 33 then
            frame:SetStatusBarColor(1, 0, 0) -- red
        elseif frame.val < 66 then
            frame:SetStatusBarColor(1, 0.65, 0) -- orange
        elseif frame.val < 100 then
            frame:SetStatusBarColor(0, 1, 0) -- green
        else
            frame:SetStatusBarColor(0, 0.5, 1) -- blue
        end
        return frame
    end
    
    if frame.val < 33 then
        frame:SetStatusBarColor(MCL_SETTINGS.progressColors.low.r, MCL_SETTINGS.progressColors.low.g, MCL_SETTINGS.progressColors.low.b) -- red
    elseif frame.val < 66 then
        frame:SetStatusBarColor(MCL_SETTINGS.progressColors.medium.r, MCL_SETTINGS.progressColors.medium.g, MCL_SETTINGS.progressColors.medium.b) -- orange
    elseif frame.val < 100 then
        frame:SetStatusBarColor(MCL_SETTINGS.progressColors.high.r, MCL_SETTINGS.progressColors.high.g, MCL_SETTINGS.progressColors.high.b) -- green
    elseif frame.val == 100 then
        frame:SetStatusBarColor(MCL_SETTINGS.progressColors.complete.r, MCL_SETTINGS.progressColors.complete.g, MCL_SETTINGS.progressColors.complete.b) -- blue
    end
    
    -- Ensure we have a good texture for coloring
    local textureToUse = "Interface\\TargetingFrame\\UI-StatusBar"  -- Default fallback
    
    -- Try to get the texture from settings first
    if MCL_SETTINGS and MCL_SETTINGS.statusBarTexture and MCLcore.media then
        local settingsTexture = MCLcore.media:Fetch("statusbar", MCL_SETTINGS.statusBarTexture)
        if settingsTexture then
            textureToUse = settingsTexture
        end
    end
    
    -- Set the texture
    frame:SetStatusBarTexture(textureToUse)
    local texture = frame:GetStatusBarTexture()
    if texture then
        texture:SetHorizTile(false)
        texture:SetVertTile(false)
    end
    
    return frame
end

function UpdateProgressBarColor(frame)
	frame:SetStatusBarColor(0, 0.5, 0.9)
end

local function clearOverviewStats()
    for k in pairs (MCLcore.overviewStats) do
        MCLcore.overviewStats[k] = nil
    end
end

local function IsMountPinned(id)
    for k,v in pairs(MCLcore.mountFrames[1]) do
        if v.mountID == id then
            return true 
        end
    end
end

local function UpdatePin(frame)
    if not frame.pin then
        return  -- Exit early if pin doesn't exist
    end
    local pinned, pin = MCLcore.Function:CheckIfPinned("m"..tostring(frame.mountID))
    if pinned == true then
        frame.pin:SetAlpha(1)
    else
        frame.pin:SetAlpha(0)
    end
end   


function MCL_functions:UpdateCollection()
    clearOverviewStats()
    if MCLcore.MCL_MF.Bg then
        MCLcore.MCL_MF.Bg:SetVertexColor(0, 0, 0, MCL_SETTINGS.opacity)
    end
    MCLcore.total = 0
    MCLcore.collected = 0

    -- Count mounts from MCLcore.mounts
    for k, v in pairs(MCLcore.mounts) do
        local mountID = v.id
        MCLcore.total = MCLcore.total + 1
        if IsMountCollected(mountID) then
            table.insert(MCLcore.mountCheck, mountID)
            UpdateBackground(v.frame)
            MCLcore.collected = MCLcore.collected + 1
            -- Note: No longer automatically removing collected mounts from pinned list
            -- as users should be able to pin collected mounts for favorites/tracking
            UpdatePin(v.frame)
        else
            UpdatePin(v.frame)
        end
    end

    -- Update section stats with validation
    for k, v in pairs(MCLcore.stats) do
        local section_total = 0
        local section_collected = 0
        local section_name
        for kk, vv in pairs(v) do
            local collected = 0
            local total = 0
            if type(vv) == "table" then
                if vv["mounts"] then
                    for kkk, vvv in pairs(vv.mounts) do
                        local faction, faction_specific = IsMountFactionSpecific(vvv)
                        if faction then
                            if faction == 1 then faction = "Alliance" else faction = "Horde" end
                        end
                        if (faction_specific == false) or (faction_specific == true and faction == UnitFactionGroup("player")) then
                            local mountID
                            if string.sub(vvv, 1, 1) == "m" then
                                mountID = tonumber(string.sub(vvv, 2, -1))
                            else
                                mountID = C_MountJournal.GetMountFromItem(vvv)
                            end
                            if mountID then
                                local isCollected = IsMountCollected(mountID)
                                if isCollected == nil then
                                    C_Item.RequestLoadItemDataByID(vvv) -- Force load if item-based
                                end
                                total = total + 1
                                if isCollected then
                                    collected = collected + 1
                                end
                            end
                        end
                    end
                    if vv.pBar then
                        vv.pBar = UpdateProgressBar(vv.pBar, total, collected)
                    end
                    section_total = section_total + total
                    section_collected = section_collected + collected
                else
                    if vv.pBar then
                        vv.pBar = UpdateProgressBar(vv.pBar, section_total, section_collected)
                    end
                end
                if vv["rel"] then
                    for q, e in pairs(MCLcore.overviewFrames) do
                        if e.name == vv.rel.name and e.frame then
                            e.frame = UpdateProgressBar(e.frame, section_total, section_collected)
                            section_name = e.name
                        end
                    end
                end
            end
        end
        if section_name == MCLL["Unobtainable"] then
            MCLcore.total = MCLcore.total + section_collected - section_total
        end
    end

    -- Validate and update overall progress
    if MCLcore.total < 0 then
        MCLcore.total = 0
    end
    
    -- Only update overview progress bar if it exists
    if MCLcore.overview and MCLcore.overview.pBar then
        MCLcore.overview.pBar = UpdateProgressBar(MCLcore.overview.pBar, MCLcore.total, MCLcore.collected)
    end
end

function MCL_functions:updateFromSettings(setting, val)
    for k,v in pairs(MCLcore.statusBarFrames) do
        if setting == "texture" then
            v:SetStatusBarTexture(MCLcore.media:Fetch("statusbar", MCL_SETTINGS.statusBarTexture))
        elseif setting == "progressColor" then
            -- Call UpdateProgressBar with proper parameters to refresh colors
            if v.total and v.collected then
                v = UpdateProgressBar(v, v.total, v.collected)
            end
        end
    end
    if setting == "opacity" then
        MCLcore.MCL_MF.Bg:SetVertexColor(0,0,0,MCL_SETTINGS.opacity)
    elseif setting:lower() == "unobtainable" then
        for k,v in pairs(MCLcore.overviewFrames) do
            if v.name:lower() == setting:lower() then
                if val == true then
                    v.frame:GetParent():Hide()
                    v.frame.unobtainable = true
                else 
                    v.frame.unobtainable = false
                    v.frame:GetParent():Show()
                end
            end
        end
    end
end

--------------------------------------------------
-- Minimap Icon
--------------------------------------------------

function MCL_functions:test()
end


local MCL_MM = LibStub("AceAddon-3.0"):NewAddon("MCL_MM", "AceConsole-3.0")
local MCL_LDB = LibStub("LibDataBroker-1.1"):NewDataObject("MCL!", {
type = "data source",
text = "MCL!",
icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\mcl-logo-32",
--[[OnTooltipShow = function(tooltip)
    tooltip:SetText("MCL")
    tooltip:AddLine(MCLL["Mount Collection Log"], 1, 1, 1)
    tooltip:Show()
end,]]
OnClick = function(_, button) 
	MCLcore.Main:Toggle() 
end,
})
local icon = LibStub("LibDBIcon-1.0")

function MCL_MM:OnInitialize() -- Obviously you'll need a ## SavedVariables: BunniesDB line in your TOC, duh!
	self.db = LibStub("AceDB-3.0"):New("MCL_DB", { profile = { minimap = { hide = false, }, }, }) icon:Register("MCL!", MCL_LDB, self.db.profile.minimap)
end

function MCL_MM:MCL_MM()
	self.db.profile.minimap.hide = not self.db.profile.minimap.hide
	if self.db.profile.minimap.hide then
		icon:Hide("MCL!")
	else
		icon:Show("MCL!")
	end
end

function MCL_functions:MCL_MM()
	MCL_MM:MCL_MM()
end


function MCL_functions:updateFromDefaults(setting)
    MCLcore.Function:resetToDefault(setting)
    MCLcore.Function:updateFromSettings("opacity")
    MCLcore.Function:updateFromSettings("texture")
    MCLcore.Function:updateFromSettings("progressColor")
    MCLcore.Function:updateFromSettings("unobtainable", false)
end

function MCL_functions:AddonSettings()
    local AceConfig = LibStub("AceConfig-3.0");
    local media = LibStub("LibSharedMedia-3.0")
    MCLcore.media = media
    local options = {
        type = "group",
        name = MCLL["Mount Collection Log Settings"],
        order = 1,
        args = {
            headerone = {             
                order = 1,
                name = MCLL["Main Window Options"],
                type = "header",
                width = "full",
            },            
            mainWindow = {             
                order = 2,
                name = MCLL["Main Window Opacity"],
                desc = MCLL["Changes the opacity of the main window"],
                type = "range",
                width = "normal",
                min = 0,
                max = 1,
                softMin = 0,
                softMax = 1,
                bigStep = 0.05,
                isPercent = false,
                set = function(info, val) MCL_SETTINGS.opacity = val; MCLcore.Function:updateFromSettings("opacity"); end,
                get = function(info) return MCL_SETTINGS.opacity; end,
            },
            spacer1 = {
                order = 2.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "half",
            },
            defaultOpacity = {
                order = 3,
                name = MCLL["Reset Opacity"],
                desc = MCLL["Reset to default opacity"],
                width = "normal",
                type = "execute",
                func = function()
                    MCLcore.Function:updateFromDefaults("Opacity")
                end
            },              
            headertwo = {             
                order = 4,
                name = MCLL["Progress Bar Settings"],
                type = "header",
                width = "normal",
            },             
            texture = {              
                order = 5,
                type = "select",
                name = MCLL["Statusbar Texture"],
                width = "normal",
                desc = MCLL["Set the statusbar texture."],
                values = media:HashTable("statusbar"),
                -- Removed dialogControl = "LSM30_Statusbar",
                set = function(info, val) MCL_SETTINGS.statusBarTexture = val; MCLcore.Function:updateFromSettings("texture"); end,
                get = function(info) return MCL_SETTINGS.statusBarTexture; end,
                style = "dropdown", -- This ensures it uses a dropdown menu for selection
            },
            spacer2 = {
                order = 5.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "half",
            },            
            defaultTexture = {
                order = 6,
                name = MCLL["Reset Texture"],
                desc = MCLL["Reset to default texture"],
                width = "normal",
                type = "execute",
                func = function()
                    MCLcore.Function:updateFromDefaults("Texture")
                end
            },
            spacer3 = {
                order = 6.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "full",
            },
            spacer3large = {
                order = 6.6,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "full",
            },                                  
            progressColorLow = {
                order = 7,
                type = "color",
                name = MCLL["Progress Bar (<33%)"],
                width = "normal",
                desc = MCLL["Set the progress bar colors to be shown when the percentage collected is below 33%"],
                set = function(info, r, g, b) MCL_SETTINGS.progressColors.low.r = r; MCL_SETTINGS.progressColors.low.g = g; MCL_SETTINGS.progressColors.low.b = b; MCLcore.Function:updateFromSettings("progressColor"); end,
                get = function(info) return MCL_SETTINGS.progressColors.low.r, MCL_SETTINGS.progressColors.low.g, MCL_SETTINGS.progressColors.low.b; end,                
            },
            spacer4 = {
                order = 7.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "half",
            },            
            progressColorMedium = {
                order = 8,
                type = "color",
                name = MCLL["Progress Bar (<66%)"],
                width = "normal",
                desc = MCLL["Set the progress bar colors to be shown when the percentage collected is below 66%"],
                set = function(info, r, g, b) MCL_SETTINGS.progressColors.medium.r = r; MCL_SETTINGS.progressColors.medium.g = g; MCL_SETTINGS.progressColors.medium.b = b; MCLcore.Function:updateFromSettings("progressColor"); end,
                get = function(info) return MCL_SETTINGS.progressColors.medium.r, MCL_SETTINGS.progressColors.medium.g, MCL_SETTINGS.progressColors.medium.b; end,                
            },
            spacer5 = {
                order = 8.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "half",
            },             
            progressColorHigh = {
                order = 9,
                type = "color",
                name = MCLL["Progress Bar (<100%)"],
                width = "normal",
                desc = MCLL["Set the progress bar colors to be shown when the percentage collected is below 100%"],
                set = function(info, r, g, b) MCL_SETTINGS.progressColors.high.r = r; MCL_SETTINGS.progressColors.high.g = g; MCL_SETTINGS.progressColors.high.b = b; MCLcore.Function:updateFromSettings("progressColor"); end,
                get = function(info) return MCL_SETTINGS.progressColors.high.r, MCL_SETTINGS.progressColors.high.g, MCL_SETTINGS.progressColors.high.b; end,                
            },
            spacer6 = {
                order = 9.5,
                cmdHidden = true,
                name = "",
                type = "description",
                width = "half",
            },             
            progressColorComplete = {
                order = 10,
                type = "color",
                name = MCLL["Progress Bar (100%)"],
                width = "normal",
                desc = MCLL["Set the progress bar colors to be shown when all mounts are collected"],
                set = function(info, r, g, b) MCL_SETTINGS.progressColors.complete.r = r; MCL_SETTINGS.progressColors.complete.g = g; MCL_SETTINGS.progressColors.complete.b = b; MCLcore.Function:updateFromSettings("progressColor"); end,
                get = function(info) return MCL_SETTINGS.progressColors.complete.r, MCL_SETTINGS.progressColors.complete.g, MCL_SETTINGS.progressColors.complete.b; end,                
            },
            defaultColor = {
                order = 11,
                name = MCLL["Reset Colors"],
                desc = MCLL["Reset to default colors"],
                width = "normal",
                type = "execute",
                func = function()
                    MCLcore.Function:updateFromDefaults("Colors")
                end
            },              
            headerthree = {             
                order = 12,
                name = MCLL["Layout Settings"],
                type = "header",
                width = "full",
            },
            mountsPerRow = {
                order = 12.5,
                name = MCLL["Mounts Per Row"],
                desc = MCLL["Set the number of mounts to display per row in the mount grid. Requires UI reload."],
                type = "range",
                width = "normal",
                min = 6,
                max = 24,
                softMin = 6,
                softMax = 24,
                step = 1,
                bigStep = 1,
                set = function(info, val)
                    if MCL_SETTINGS.mountsPerRow ~= val then
                        -- Save the setting first
                        MCL_SETTINGS.mountsPerRow = val;
                        
                        -- Then ask if they want to reload
                        StaticPopupDialogs["MCL_MOUNTS_PER_ROW_RELOAD"] = {
                            text = MCLL["Changing this setting requires a UI reload. Reload now?"],
                            button1 = MCLL["YES"],
                            button2 = MCLL["NO"],
                            OnAccept = function()
                                ReloadUI();
                            end,
                            OnCancel = function()
                                -- Setting is already saved, so just do nothing
                            end,
                            timeout = 0,
                            whileDead = true,
                            hideOnEscape = true,
                            preferredIndex = 3,
                        }
                        StaticPopup_Show("MCL_MOUNTS_PER_ROW_RELOAD")
                    end
                end,
                get = function(info) return MCL_SETTINGS.mountsPerRow; end,
            },
            headerfour = {             
                order = 13,
                name = MCLL["Unobtainable Settings"],
                type = "header",
                width = "full",
            },            
            unobtainable = {             
                order = 14,
                name = MCLL["Hide Unobtainable from overview"],
                desc = MCLL["Hide Unobtainable mounts from the overview."],
                type = "toggle",
                width = "full",
                set = function(info, val) MCL_SETTINGS.unobtainable = val; MCLcore.Function:updateFromSettings("unobtainable", val); end,
                get = function(info) return MCL_SETTINGS.unobtainable; end,
            },
            hideCollectedMounts = {
                order = 14.5,
                name = MCLL["Hide Collected Mounts"],
                desc = MCLL["If enabled, collected mounts will not be shown in the list at all. Requires UI reload."],
                type = "toggle",
                width = "full",
                set = function(info, val)
                    if MCL_SETTINGS.hideCollectedMounts ~= val then
                        StaticPopupDialogs["MCL_RELOAD_CONFIRM"] = {
                            text = MCLL["Changing this setting requires a UI reload. Reload now?"],
                            button1 = MCLL["YES"],
                            button2 = MCLL["NO"],
                            OnAccept = function()
                                MCL_SETTINGS.hideCollectedMounts = val;
                                ReloadUI();
                            end,
                            OnCancel = function()
                                -- Do nothing
                            end,
                            timeout = 0,
                            whileDead = true,
                            hideOnEscape = true,
                            preferredIndex = 3,
                        }
                        StaticPopup_Show("MCL_RELOAD_CONFIRM")
                    end
                end,
                get = function(info) return MCL_SETTINGS.hideCollectedMounts; end,
            },
            useBlizzardTheme = {
                order = 14.6,
                name = MCLL["Use Blizzard Theme"],
                desc = MCLL["If enabled, the addon will use Blizzard's default UI theme. Requires UI reload."],
                type = "toggle",
                width = "full",
                set = function(info, val)
                    if MCL_SETTINGS.useBlizzardTheme ~= val then
                        StaticPopupDialogs["MCL_RELOADUI"] = {
                            text = MCLL["Changing this setting requires a UI reload. Reload now?"],
                            button1 = MCLL["YES"],
                            button2 = MCLL["NO"],
                            OnAccept = function() MCL_SETTINGS.useBlizzardTheme = val; ReloadUI(); end,
                            timeout = 0,
                            hideOnEscape = true,
                        }
                        StaticPopup_Show("MCL_RELOADUI")
                    end
                end,
                get = function(info) return MCL_SETTINGS.useBlizzardTheme; end,
            },
            minimapIconToggle = {
                order = 14.7,
                name = MCLL["Show Minimap Icon"],
                desc = MCLL["Toggle the display of the Minimap Icon."],
                type = "toggle",
                width = "full",
                set = function(info, val)
                    MCL_MM.db.profile.minimap.hide = not val
                    if val then
                        icon:Show("MCL!")
                    else
                        icon:Hide("MCL!")
                    end
                end,
                get = function(info)
                    return not MCL_MM.db.profile.minimap.hide
                end,
            },
            headerfive = {             
                order = 15,
                name = MCLL["Reset Settings"],
                type = "header",
                width = "full",
            },             
            defaults = {
                order = 16,
                name = MCLL["Reset Settings"],
                desc = MCLL["Reset to default settings"],
                width = "normal",
                type = "execute",
                func = function()
                    MCLcore.Function:updateFromDefaults()
                end
            }                                                                                                       
        }
    }                                                        


    AceConfig:RegisterOptionsTable(MCLcore.addon_name, options, {});
    MCLcore.AceConfigDialog = LibStub("AceConfigDialog-3.0");
    MCLcore.AceConfigDialog:AddToBlizOptions(MCLcore.addon_name, MCLcore.addon_name, nil);
end

function MCL_functions:CalculateSectionStats()
    MCLcore.stats = {}
    
    for _, section in ipairs(MCLcore.sections or {}) do
        local sectionTotal = 0
        local sectionCollected = 0
        
        if section.mounts and section.mounts.categories then
            for categoryName, categoryData in pairs(section.mounts.categories) do
                -- Combine both mounts and mountID arrays
                local mountList = {}
                if categoryData.mounts then
                    for _, mount in ipairs(categoryData.mounts) do
                        table.insert(mountList, mount)
                    end
                end
                if categoryData.mountID then
                    for _, mount in ipairs(categoryData.mountID) do
                        table.insert(mountList, mount)
                    end
                end
                
                for _, mountId in ipairs(mountList) do
                    local mount_Id = MCLcore.Function:GetMountID(mountId)
                    if mount_Id then
                        -- Apply the same faction filtering as the display logic
                        local faction, faction_specific = MCLcore.Function.IsMountFactionSpecific(mountId)
                        local playerFaction = UnitFactionGroup("player")
                        local allowed = false
                        if faction_specific == false then
                            allowed = true
                        elseif faction_specific == true then
                            if faction == 0 then faction = "Horde" elseif faction == 1 then faction = "Alliance" end
                            allowed = (faction == playerFaction)
                        end
                        
                        -- Only count mounts that pass faction restrictions
                        if allowed then
                            sectionTotal = sectionTotal + 1
                            if IsMountCollected(mount_Id) then
                                sectionCollected = sectionCollected + 1
                            end
                        end
                    end
                end
            end
        end
        
        MCLcore.stats[section.name] = {
            total = sectionTotal,
            collected = sectionCollected
        }
    end
end

-- Function to update pin icons for a specific mount across all frames
function MCL_functions:UpdateAllPinIcons(mountID)
    local isPinned = MCLcore.Function:CheckIfPinned("m"..mountID)
    
    -- Update pin icons in all mount frames
    for k, v in pairs(MCLcore.mounts) do
        if v.frame and v.frame.pin and tostring(v.id) == tostring(mountID) then
            if isPinned then
                v.frame.pin:SetAlpha(1)
            else
                v.frame.pin:SetAlpha(0)
            end
        end
    end
    
    -- Also update pin icons in pinned section frames
    if MCLcore.mountFrames[1] then
        for k, v in pairs(MCLcore.mountFrames[1]) do
            if v.pin and tostring(v.mountID) == tostring(mountID) then
                if isPinned then
                    v.pin:SetAlpha(1)
                else
                    v.pin:SetAlpha(0)
                end
            end
        end
    end
end

function MCL_functions:UpdatePinnedMountStyling(mountID)
    -- Update styling for a specific pinned mount when its collection status changes
    if not MCLcore.mountFrames[1] then
        return
    end
    
    for k, frame in pairs(MCLcore.mountFrames[1]) do
        if frame.mountID and tostring(frame.mountID) == tostring(mountID) then
            if IsMountCollected(mountID) then
                -- Collected mount styling
                frame:SetBackdropBorderColor(0, 0.8, 0, 0.8)  -- Green border
                frame:SetBackdropColor(0, 0.2, 0, 0.15)       -- Subtle green background
                frame.tex:SetVertexColor(1, 1, 1, 1)          -- Full color icon
                if frame.mountName then
                    frame.mountName:SetTextColor(0, 1, 0)     -- Green mount name
                end
            else
                -- Uncollected mount styling
                frame:SetBackdropBorderColor(0.8, 0.3, 0.3, 0.8)  -- Red border
                frame:SetBackdropColor(0.2, 0.05, 0.05, 0.15)     -- Subtle red background
                frame.tex:SetVertexColor(0.6, 0.6, 0.6, 0.8)      -- Slightly dimmed icon
                if frame.mountName then
                    frame.mountName:SetTextColor(0.9, 0.9, 0.9)   -- Light gray mount name
                end
            end
            break
        end
    end
end

-- Function to check if we need to refresh layout after pinned mount changes
function MCL_functions:CheckAndRefreshAfterPinnedChanges(newSectionName)
    -- If we're switching away from the Pinned section and pinned mounts were modified
    if MCLcore.pinnedMountsChanged and newSectionName ~= "Pinned" then
        MCLcore.pinnedMountsChanged = false  -- Reset the flag
        
        -- Use a small delay to ensure the new section is fully loaded before refreshing
        C_Timer.After(0.1, function()
            if MCL_frames and MCL_frames.RefreshLayout then
                MCL_frames:RefreshLayout()
            elseif MCLcore.Frames and MCLcore.Frames.RefreshLayout then
                MCLcore.Frames:RefreshLayout()
            end
        end)
    end
end


-- Enhanced GetMountID function with better error handling
function MCL_functions:GetMountIDSafe(id, context)
    local success, isValid, data = pcall(function()
        return MCLcore.Function:DebugMountLoading(id, context)
    end)
    
    if not success then
        --print(string.format("|cffFF0000[MCL Debug]|r Critical error processing mount %s: %s", tostring(id), tostring(isValid)))
        return nil
    end
    
    if isValid and data and data.mountId then
        return data.mountId
    else
        -- Return nil for invalid mounts instead of breaking
        return nil
    end
end



local MCL_Load = MCLcore.Main;

MCLcore.Frames = {};
local MCL_frames = MCLcore.Frames;

MCLcore.TabTable = {}
MCLcore.statusBarFrames  = {}

MCLcore.nav_width = 180
local nav_width = MCLcore.nav_width
local main_frame_width = 900
local main_frame_height = 500

local r,g,b,a
-- Helper function to style navigation buttons for both themes
local function StyleNavButton(button, isExpansionIcon)
    if not button then return end
    
    if MCL_SETTINGS.useBlizzardTheme then
        -- Blizzard theme styling with authentic textures
        if isExpansionIcon then
            -- Expansion icons get a Blizzard-style button frame
            button:SetBackdrop({
                bgFile = "Interface\\Buttons\\UI-Panel-Button-Up", 
                edgeFile = "Interface\\Buttons\\UI-Panel-Button-Border", 
                edgeSize = 8,
                insets = {left = 2, right = 2, top = 2, bottom = 2}
            })
            button:SetBackdropColor(0.9, 0.9, 1, 0.4)  -- Light blue-white background
            button:SetBackdropBorderColor(0.7, 0.7, 0.9, 1)  -- Blue border
        else
            -- Regular navigation buttons get Blizzard panel styling
            button:SetBackdrop({
                bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", 
                edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
                edgeSize = 16,
                insets = {left = 4, right = 4, top = 4, bottom = 4}
            })
            button:SetBackdropColor(0.05, 0.05, 0.2, 0.9)  -- Dark blue background
            button:SetBackdropBorderColor(0.6, 0.6, 0.8, 1)  -- Blue-gray border
        end
        
        -- Blizzard-style text color
        if button.text then
            button.text:SetTextColor(1, 0.82, 0, 1)  -- Gold text
        end
    else
        -- Default theme styling (current)
        button:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8})
        button:SetBackdropColor(0.1, 0.1, 0.1, 0.95)
        button:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
        
        if button.text then
            button.text:SetTextColor(1, 1, 1, 1)  -- White text
        end
    end
end


local function ScrollFrame_OnMouseWheel(self, delta)
	local newValue = self:GetVerticalScroll() - (delta * 50);
	
	if (newValue < 0) then
		newValue = 0;
	elseif (newValue > self:GetVerticalScrollRange()) then
		newValue = self:GetVerticalScrollRange();
	end
	
	self:SetVerticalScroll(newValue);
end


function MCL_frames:openSettings()
	Settings.OpenToCategory(MCLcore.addon_name)
	local panel = SettingsPanel or InterfaceOptionsFrame or _G["SettingsPanel"]
	if not panel then return end

	-- Remove old checkboxes if they exist
	if MCLcore.hideCollectedIconCheckbox then
		MCLcore.hideCollectedIconCheckbox:Hide()
		MCLcore.hideCollectedIconCheckbox = nil
	end
	if MCLcore.useBlizzardThemeCheckbox then
		MCLcore.useBlizzardThemeCheckbox:Hide()
		MCLcore.useBlizzardThemeCheckbox = nil
	end

	-- Find the last checkbox in the Unobtainable Settings section to anchor below
	local lastCheckbox = nil
	if MCLcore.hideUnobtainableCheckbox then
		lastCheckbox = MCLcore.hideUnobtainableCheckbox
	elseif MCLcore.hideCollectedMountsCheckbox then
		lastCheckbox = MCLcore.hideCollectedMountsCheckbox
	elseif MCLcore.showMinimapIconCheckbox then
		lastCheckbox = MCLcore.showMinimapIconCheckbox
	end
end

function MCL_frames:CreateMainFrame()
    local frameTemplate = MCL_SETTINGS.useBlizzardTheme and "MCLBlizzardFrameTemplate" or "MCLFrameTemplateWithInset"
    MCL_mainFrame = CreateFrame("Frame", "MCLFrame", UIParent, frameTemplate);
    if MCL_SETTINGS.useBlizzardTheme then
        if MCL_mainFrame.NineSlice then MCL_mainFrame.NineSlice:Hide() end
        if MCL_mainFrame.MCLFrameTopLeft then MCL_mainFrame.MCLFrameTopLeft:Hide() end
        if MCL_mainFrame.MCLFrameTopRight then MCL_mainFrame.MCLFrameTopRight:Hide() end
        if MCL_mainFrame.MCLFrameBottomLeft then MCL_mainFrame.MCLFrameBottomLeft:Hide() end
        if MCL_mainFrame.MCLFrameBottomRight then MCL_mainFrame.MCLFrameBottomRight:Hide() end
        if MCL_mainFrame.MCLFrameTop then MCL_mainFrame.MCLFrameTop:Hide() end
        if MCL_mainFrame.MCLFrameBottom then MCL_mainFrame.MCLFrameBottom:Hide() end
        if MCL_mainFrame.MCLFrameLeft then MCL_mainFrame.MCLFrameLeft:Hide() end
        if MCL_mainFrame.MCLFrameRight then MCL_mainFrame.MCLFrameRight:Hide() end
    end
    if not MCL_SETTINGS.useBlizzardTheme then
        if MCL_mainFrame.Bg then
            MCL_mainFrame.Bg:SetVertexColor(0,0,0,MCL_SETTINGS.opacity)
        end
        if MCL_mainFrame.TitleBg then
            MCL_mainFrame.TitleBg:SetVertexColor(0.1,0.1,0.1,0.95)
        end
    end
    MCL_mainFrame:Show()
    
    -- Create the main frame title
    MCL_mainFrame.title = MCL_mainFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    
    -- Settings button
    MCL_mainFrame.settings = CreateFrame("Button", nil, MCL_mainFrame);
    MCL_mainFrame.settings:SetSize(14, 14)
    if MCL_SETTINGS.useBlizzardTheme then
        MCL_mainFrame.settings:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -40, -8)
    else
        MCL_mainFrame.settings:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -30, 0)
    end
    MCL_mainFrame.settings.tex = MCL_mainFrame.settings:CreateTexture()
    MCL_mainFrame.settings.tex:SetAllPoints(MCL_mainFrame.settings)
    MCL_mainFrame.settings.tex:SetTexture("Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\settings.blp")
    MCL_mainFrame.settings:SetScript("OnClick", function()MCL_frames:openSettings()end)

    -- Refresh button
    MCL_mainFrame.refresh = CreateFrame("Button", nil, MCL_mainFrame);
    MCL_mainFrame.refresh:SetSize(14, 14)
    if MCL_SETTINGS.useBlizzardTheme then
        MCL_mainFrame.refresh:SetPoint("TOPRIGHT", MCL_mainFrame.settings, "TOPLEFT", -5, 0)
    else
        MCL_mainFrame.refresh:SetPoint("TOPRIGHT", MCL_mainFrame.settings, "TOPLEFT", -5, 0)
    end
    MCL_mainFrame.refresh.tex = MCL_mainFrame.refresh:CreateTexture()
    MCL_mainFrame.refresh.tex:SetAllPoints(MCL_mainFrame.refresh)
    MCL_mainFrame.refresh.tex:SetTexture("Interface\\Buttons\\UI-RefreshButton")
    MCL_mainFrame.refresh:SetScript("OnClick", function()
        if MCL_frames and MCL_frames.RefreshLayout then
            MCL_frames:RefreshLayout()
        end
    end)
    
    -- Add tooltip for refresh button
    MCL_mainFrame.refresh:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText("Refresh Layout", 1, 1, 1)
        GameTooltip:AddLine("Refreshes the mount collection display", 0.8, 0.8, 0.8)
        GameTooltip:Show()
    end)
    MCL_mainFrame.refresh:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    --[[ SA button
    MCL_mainFrame.sa = CreateFrame("Button", nil, MCL_mainFrame);
    MCL_mainFrame.sa:SetSize(60, 15)
    if MCL_SETTINGS.useBlizzardTheme then
        MCL_mainFrame.sa:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -80, -8)
    else
        MCL_mainFrame.sa:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -80, -1)
    end
    MCL_mainFrame.sa.tex = MCL_mainFrame.sa:CreateTexture()
    MCL_mainFrame.sa.tex:SetAllPoints(MCL_mainFrame.sa)
    MCL_mainFrame.sa.tex:SetTexture("Interface\\Buttons\\WHITE8x8")
    MCL_mainFrame.sa.tex:SetVertexColor(0.1,0.1,0.1,0.95, MCL_SETTINGS.opacity)
    MCL_mainFrame.sa.text = MCL_mainFrame.sa:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
    MCL_mainFrame.sa.text:SetPoint("CENTER", MCL_mainFrame.sa, "CENTER", 0, 0);
    MCL_mainFrame.sa.text:SetText("SA")
    MCL_mainFrame.sa.text:SetTextColor(0, 0.7, 0.85)	
    MCL_mainFrame.sa:SetScript("OnClick", function()
        if MCLcore.Function and MCLcore.Function.simplearmoryLink then
            MCLcore.Function:simplearmoryLink()
        end
    end)	
	
    -- DFA button
    MCL_mainFrame.dfa = CreateFrame("Button", nil, MCL_mainFrame);
    MCL_mainFrame.dfa:SetSize(60, 15)
    if MCL_SETTINGS.useBlizzardTheme then
        MCL_mainFrame.dfa:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -125, -8)
    else
        MCL_mainFrame.dfa:SetPoint("TOPRIGHT", MCL_mainFrame, "TOPRIGHT", -125, -1)
    end
    MCL_mainFrame.dfa.tex = MCL_mainFrame.dfa:CreateTexture()
    MCL_mainFrame.dfa.tex:SetAllPoints(MCL_mainFrame.dfa)
    MCL_mainFrame.dfa.tex:SetTexture("Interface\\Buttons\\WHITE8x8")
    MCL_mainFrame.dfa.tex:SetVertexColor(0.1,0.1,0.1,0.95, MCL_SETTINGS.opacity)
    MCL_mainFrame.dfa.text = MCL_mainFrame.dfa:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
    MCL_mainFrame.dfa.text:SetPoint("CENTER", MCL_mainFrame.dfa, "CENTER", 0, 0);
    MCL_mainFrame.dfa.text:SetText("DFA")
    MCL_mainFrame.dfa.text:SetTextColor(0, 0.7, 0.85)	
    MCL_mainFrame.dfa:SetScript("OnClick", function()
        if MCLcore.Function and MCLcore.Function.dfaLink then
            MCLcore.Function:dfaLink()
        end
    end)]]		


	--MCL Frame settings
	MCL_mainFrame:SetSize(main_frame_width, main_frame_height); -- width, height
	MCL_mainFrame:SetPoint("CENTER", UIParent, "CENTER"); -- point, relativeFrame, relativePoint, xOffset, yOffset
	MCL_mainFrame:SetHyperlinksEnabled(true)
	MCL_mainFrame:SetScript("OnHyperlinkClick", ChatFrame_OnHyperlinkShow)
	
	-- Restore saved frame size if available
	MCL_frames:RestoreFrameSize()

	MCL_mainFrame:SetMovable(true)
	MCL_mainFrame:EnableMouse(true)
	MCL_mainFrame:RegisterForDrag("LeftButton")
	MCL_mainFrame:SetScript("OnDragStart", MCL_mainFrame.StartMoving)
	MCL_mainFrame:SetScript("OnDragStop", MCL_mainFrame.StopMovingOrSizing)
	
	-- Make frame resizable
	MCL_mainFrame:SetResizable(true)
	MCL_mainFrame:SetResizeBounds(900, 600, 1600, 1000)  -- min width, min height, max width, max height
	
	-- Create resize grip
	MCL_mainFrame.resizeGrip = CreateFrame("Button", nil, MCL_mainFrame)
	MCL_mainFrame.resizeGrip:SetSize(16, 16)
	MCL_mainFrame.resizeGrip:SetPoint("BOTTOMRIGHT", MCL_mainFrame, "BOTTOMRIGHT", -2, 2)
	MCL_mainFrame.resizeGrip:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
	MCL_mainFrame.resizeGrip:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
	MCL_mainFrame.resizeGrip:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
	MCL_mainFrame.resizeGrip:SetScript("OnMouseDown", function(self)
		MCL_mainFrame:StartSizing("BOTTOMRIGHT")
	end)
	MCL_mainFrame.resizeGrip:SetScript("OnMouseUp", function(self)
		MCL_mainFrame:StopMovingOrSizing()
		-- Save the new size and trigger layout update after resize
		MCL_frames:SaveFrameSize()
		MCL_frames:RefreshLayout()
	end)    

	-- Move title to top center
    if MCL_mainFrame.title then
        MCL_mainFrame.title:ClearAllPoints()
		-- if blizzard theme
		if MCL_SETTINGS.useBlizzardTheme then
			MCL_mainFrame.title:SetPoint("TOPLEFT", MCL_mainFrame, "TOPLEFT", 10, -8)  -- Moved down 10px from the very top
		else
			MCL_mainFrame.title:SetPoint("TOPLEFT", MCL_mainFrame, "TOPLEFT", 10, -2)  -- Moved down 5px from the very top
		end
        MCL_mainFrame.title:SetText(MCLL["Mount Collection Log"])

        MCL_mainFrame.title:SetTextColor(0.3, 0.7, 0.9, 1)  -- White text for better visibility
    end
    
    -- Scroll Frame for Main Window
	MCL_mainFrame.ScrollFrame = CreateFrame("ScrollFrame", nil, MCL_mainFrame, "MinimalScrollFrameTemplate");
	-- Anchor scroll frame to the main frame, not Bg
    MCL_mainFrame.ScrollFrame:ClearAllPoints()
    MCL_mainFrame.ScrollFrame:SetPoint("TOPLEFT", MCL_mainFrame, "TOPLEFT", 10, -40)
    MCL_mainFrame.ScrollFrame:SetPoint("BOTTOMRIGHT", MCL_mainFrame, "BOTTOMRIGHT", -10, 10)
	MCL_mainFrame.ScrollFrame:SetClipsChildren(true);
	MCL_mainFrame.ScrollFrame:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel);
	MCL_mainFrame.ScrollFrame:EnableMouse(true)
    
	MCL_mainFrame.ScrollFrame.ScrollBar:ClearAllPoints();
	MCL_mainFrame.ScrollFrame.ScrollBar:SetPoint("TOPLEFT", MCL_mainFrame.ScrollFrame, "TOPRIGHT", -8, -19);
	MCL_mainFrame.ScrollFrame.ScrollBar:SetPoint("BOTTOMRIGHT", MCL_mainFrame.ScrollFrame, "BOTTOMRIGHT", -8, 17);

    -- Create and assign a dedicated scroll child frame
    if not MCL_mainFrame.ScrollChild then
        MCL_mainFrame.ScrollChild = CreateFrame("Frame", nil, MCL_mainFrame.ScrollFrame)
        MCL_mainFrame.ScrollChild:SetSize(main_frame_width, main_frame_height)
        MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
    end

	MCL_mainFrame:SetFrameStrata("HIGH")
    if not MCL_SETTINGS.useBlizzardTheme then
        if MCLcore.Function and MCLcore.Function.CreateFullBorder then
            MCLcore.Function:CreateFullBorder(MCL_mainFrame)
        end
    end

    tinsert(UISpecialFrames, "MCLFrame")
    
    -- Add OnShow handler to show navigation when main frame is shown
    MCL_mainFrame:SetScript("OnShow", function()
        if MCLcore.MCL_MF_Nav then
            MCLcore.MCL_MF_Nav:Show()
        end
    end)
    
    -- Add OnHide handler to hide navigation when main frame is closed
    MCL_mainFrame:SetScript("OnHide", function()
        if MCLcore.MCL_MF_Nav then
            MCLcore.MCL_MF_Nav:Hide()
        end
    end)
    
    return MCL_mainFrame
end


local function Tab_OnClick(self)
	-- Check if we need to refresh layout when switching away from pinned section
	if MCLcore.Function and MCLcore.Function.CheckAndRefreshAfterPinnedChanges then
		local newSectionName = self.section and self.section.name or "Unknown"
		MCLcore.Function:CheckAndRefreshAfterPinnedChanges(newSectionName)
	end
	
	PanelTemplates_SetTab(self:GetParent(), self:GetID());

	local scrollChild = MCL_mainFrame.ScrollFrame:GetScrollChild();
	if(scrollChild) then
		scrollChild:Hide();
	end

	MCL_mainFrame.ScrollFrame:SetScrollChild(self.content);
	self.content:Show();
	MCL_mainFrame.ScrollFrame:SetVerticalScroll(0);
end


-- Build a nav-ordered list of sections for consistent tab/content mapping
function MCLcore:BuildSectionsOrdered()
    local pinned, overview, expansions, others = nil, nil, {}, {}
    local playerFaction = UnitFactionGroup("player")
    for i = 1, #MCLcore.sectionNames do
        local v = MCLcore.sectionNames[i]
        if v.name == "Pinned" then
            pinned = v
        elseif v.name == "Horde" and playerFaction == "Alliance" then
            -- skip Horde for Alliance players
        elseif v.name == "Alliance" and playerFaction == "Horde" then
            -- skip Alliance for Horde players
        elseif v.name == "Overview" then
            overview = v
        elseif v.isExpansion then
            table.insert(expansions, v)
        else
            table.insert(others, v)
        end
    end
    local ordered = {}
    if overview then table.insert(ordered, overview) end
    for _, v in ipairs(expansions) do table.insert(ordered, v) end
    for _, v in ipairs(others) do table.insert(ordered, v) end
    if pinned then table.insert(ordered, pinned) end
    MCLcore.sectionsOrdered = ordered
end

function MCL_frames:SetTabs()
    -- Always update stats before building tabs/UI
    if MCLcore.Function and MCLcore.Function.UpdateCollection then
        MCLcore.Function:UpdateCollection()
    end
    if MCLcore.BuildSectionsOrdered then
        MCLcore:BuildSectionsOrdered()
    end
    if MCLcore.Function and MCLcore.Function.CalculateSectionStats then
        MCLcore.Function:CalculateSectionStats()
    end
    
    -- Refresh overview stats after calculation
    if MCLcore.overviewFrames then
        for _, overviewFrame in ipairs(MCLcore.overviewFrames) do
            local sectionName = overviewFrame.name
            local pBar = overviewFrame.frame
            local sectionStats = MCLcore.stats and MCLcore.stats[sectionName]
            
            if sectionStats and sectionStats.collected and sectionStats.total then
                UpdateProgressBar(pBar, sectionStats.total, sectionStats.collected)
            end
        end
    end

    local tabFrame
    if MCL_SETTINGS.useBlizzardTheme then
        -- Blizzard theme should ALSO use the separate navigation frame
        tabFrame = MCLcore.MCL_MF_Nav
    else
        tabFrame = MCLcore.MCL_MF_Nav
    end

    -- Store reference for overview navigation
    if not tabFrame.tabs then
        tabFrame.tabs = {}
    end

    local sections = MCLcore.sectionsOrdered or MCLcore.sections
    -- Find Overview, Pinned, expansions, and others
    local overviewSection, pinnedSection, expansionSections, otherSections = nil, nil, {}, {}
    for _, v in ipairs(sections) do
        if v.name == "Overview" then
            overviewSection = v
        elseif v.name == "Pinned" then
            pinnedSection = v
        elseif v.isExpansion then
            table.insert(expansionSections, v)
        else
            table.insert(otherSections, v)
        end
    end

    if tabFrame.tabs then
        for _, tab in ipairs(tabFrame.tabs) do
            tab:Hide()
            if tab.content then tab.content:Hide() end
        end
    end
    tabFrame.tabs = {}
    MCLcore.sectionFrames = {}

    local navYOffset = -55  -- Adjusted to account for search bar
    local tabIndex = 1
    local selectedTab = nil

    local function HideAllTabContents()
        -- Hide all tab content frames
        for _, t in ipairs(tabFrame.tabs) do
            if t.content then 
                t.content:Hide() 
            end
        end
        
        -- Hide all section frames that might be stored globally
        if MCLcore.sectionFrames then
            for _, contentFrame in ipairs(MCLcore.sectionFrames) do
                if contentFrame and contentFrame.Hide then
                    contentFrame:Hide()
                end
            end
        end
        
        -- Hide overview frame specifically
        if MCLcore.overview then
            MCLcore.overview:Hide()
        end
        
        -- Also properly destroy search results content if it exists
        if MCLcore.Search and MCLcore.Search.DestroySearchResultsFrame then
            MCLcore.Search:DestroySearchResultsFrame()
        end
    end
    
    -- Expose HideAllTabContents globally for access from other files
    MCLcore.HideAllTabContents = HideAllTabContents
    local function DeselectAllTabs()
        for _, t in ipairs(tabFrame.tabs) do
            t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
        end
    end
    local function SelectTab(tab)
        -- Check if we need to refresh layout when switching away from pinned section
        if MCLcore.Function and MCLcore.Function.CheckAndRefreshAfterPinnedChanges then
            local newSectionName = tab.section and tab.section.name or "Unknown"
            MCLcore.Function:CheckAndRefreshAfterPinnedChanges(newSectionName)
        end
        
        DeselectAllTabs()
        HideAllTabContents()
        
        -- Clear any active search when switching tabs manually
        if MCLcore.Search and MCLcore.Search.isSearchActive then
            -- Clear search state without restoring previous tab
            MCLcore.Search.currentSearchTerm = ""
            MCLcore.Search.isSearchActive = false
            MCLcore.Search.searchResults = {}
            
            -- Clear any highlighting
            if MCLcore.Search.ClearHighlighting then
                MCLcore.Search:ClearHighlighting()
            end
            
            -- Properly destroy search results content frame
            if MCLcore.Search.DestroySearchResultsFrame then
                MCLcore.Search:DestroySearchResultsFrame()
            end
            
            -- Clear search box text
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.searchBox then
                MCLcore.MCL_MF_Nav.searchBox:SetText("")
                if MCLcore.MCL_MF_Nav.searchPlaceholder then
                    MCLcore.MCL_MF_Nav.searchPlaceholder:Show()
                end
            end
            
            -- Clear the previously selected tab reference
            MCLcore.Search.previouslySelectedTab = nil
        end
        
        tab:SetBackdropBorderColor(1, 0.82, 0, 1)
        
        -- Always ensure the main scroll child is the scroll child
        if MCL_mainFrame.ScrollChild then
            MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
        end
        
        -- Show only the selected tab's content
        if tab.content then
            tab.content:Show()
        end
        
        MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
        -- Store the currently selected tab globally for search functionality
        MCLcore.currentlySelectedTab = tab
    end

    -- 1. Overview tab (always first)
    if overviewSection then
        local tab = CreateFrame("Button", nil, tabFrame, "BackdropTemplate")
        tab:SetSize(nav_width + 8, 32)  -- Use nav width for sidebar tabs
        tab:SetPoint("TOPLEFT", tabFrame, "TOPLEFT", 1, navYOffset)
        StyleNavButton(tab, false)  -- Use our styling function
        tab.text = tab:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        tab.text:SetPoint("LEFT", 10, 0)
        tab.text:SetText(MCLL[overviewSection.name] or overviewSection.name)
        tab.section = overviewSection
        tab.content = MCLcore.overview
        if tab.content then tab.content:Hide() end
        tab:SetScript("OnClick", function(self)
            SelectTab(self)
        end)
        tab:EnableMouse(true)
        tab:SetFrameStrata("HIGH")
        tab:SetFrameLevel(100)
        tab:Show()
        table.insert(tabFrame.tabs, tab)
        -- Also store in navigation frame for overview navigation
        if MCLcore.MCL_MF_Nav and not MCLcore.MCL_MF_Nav.tabs then
            MCLcore.MCL_MF_Nav.tabs = {}
        end
        if MCLcore.MCL_MF_Nav then
            table.insert(MCLcore.MCL_MF_Nav.tabs, tab)
        end
        table.insert(MCLcore.sectionFrames, tab.content)
        tabIndex = tabIndex + 1
        navYOffset = navYOffset - 36
        selectedTab = tab
        -- Store globally for search functionality
        MCLcore.currentlySelectedTab = tab
    end
    -- 2. Expansion grid (icon-only, 3 per row)
    local gridCols, iconSize, iconPad = 3, 36, 8
    local gridStartY = navYOffset
    
    -- Calculate centering for expansion icons within the nav sidebar
    local totalGridWidth = gridCols * iconSize + (gridCols - 1) * iconPad
    local navFrameWidth = nav_width + 10  -- Use the nav frame width
    local gridStartX = (navFrameWidth - totalGridWidth) / 2  -- Center within nav frame
    
    for i, v in ipairs(expansionSections) do
        local col = ((i-1) % gridCols)
        local row = math.floor((i-1) / gridCols)
        local btn = CreateFrame("Button", nil, tabFrame, "BackdropTemplate")
        btn:SetSize(iconSize, iconSize)
        btn:SetPoint("TOPLEFT", tabFrame, "TOPLEFT", gridStartX + col * (iconSize + iconPad), gridStartY - row * (iconSize + iconPad))
        StyleNavButton(btn, true)  -- Use our styling function for expansion icons
        btn.icon = btn:CreateTexture(nil, "ARTWORK")
        btn.icon:SetAllPoints(btn)
        btn.icon:SetTexture(v.icon)
        btn.section = v
        btn.content = MCLcore.Frames:createContentFrame(MCL_mainFrame.ScrollChild, v.name)
        -- Populate expansion tab content
        if v.mounts then
            if v.mounts.categories then
                MCLcore.Frames:createCategoryFrame(v.mounts.categories, btn.content, v.name)
            else
                -- For some sections, mounts might be directly in v.mounts
                MCLcore.Frames:createCategoryFrame(v.mounts, btn.content, v.name)
            end
        end
        btn.content:Hide()
        btn:SetScript("OnClick", function(self)
            SelectTab(self)
        end)
        btn:EnableMouse(true)
        btn:SetFrameStrata("HIGH")
        btn:SetFrameLevel(100)
        btn:Show()
        table.insert(tabFrame.tabs, btn)
        -- Also store in navigation frame for overview navigation
        if MCLcore.MCL_MF_Nav then
            table.insert(MCLcore.MCL_MF_Nav.tabs, btn)
        end
        table.insert(MCLcore.sectionFrames, btn.content)
        tabIndex = tabIndex + 1
    end
    navYOffset = gridStartY - math.ceil(#expansionSections / gridCols) * (iconSize + iconPad) - 10
    -- 3. Remaining full-width tabs
    for _, v in ipairs(otherSections) do
        local tab = CreateFrame("Button", nil, tabFrame, "BackdropTemplate")
        tab:SetSize(nav_width + 8, 32)  -- Use nav width for sidebar tabs
        tab:SetPoint("TOPLEFT", tabFrame, "TOPLEFT", 1, navYOffset)
        StyleNavButton(tab, false)  -- Use our styling function
        tab.text = tab:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        tab.text:SetPoint("LEFT", 10, 0)
        tab.text:SetText(MCLL[v.name] or v.name)
        tab.section = v
        tab.content = MCLcore.Frames:createContentFrame(MCL_mainFrame.ScrollChild, v.name)
        -- Populate other tab content if available
        if v.mounts then
            if v.mounts.categories then
                MCLcore.Frames:createCategoryFrame(v.mounts.categories, tab.content, v.name)
            else
                MCLcore.Frames:createCategoryFrame(v.mounts, tab.content, v.name)
            end
        end
        tab.content:Hide()
        tab:SetScript("OnClick", function(self)
            SelectTab(self)
        end)
        tab:EnableMouse(true)
        tab:SetFrameStrata("HIGH")
        tab:SetFrameLevel(100)
        tab:Show()
        table.insert(tabFrame.tabs, tab)
        -- Also store in navigation frame for overview navigation (other sections)
        if MCLcore.MCL_MF_Nav then
            table.insert(MCLcore.MCL_MF_Nav.tabs, tab)
        end
        table.insert(MCLcore.sectionFrames, tab.content)
        tabIndex = tabIndex + 1
        navYOffset = navYOffset - 28
    end
    -- 4. Pinned tab (always last)
    if pinnedSection then
        local tab = CreateFrame("Button", nil, tabFrame, "BackdropTemplate")
        tab:SetSize(nav_width + 8, 32)  -- Use nav width for sidebar tabs
        tab:SetPoint("TOPLEFT", tabFrame, "TOPLEFT", 1, navYOffset)
        StyleNavButton(tab, false)  -- Use our styling function
        tab.text = tab:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        tab.text:SetPoint("LEFT", 10, 0)
        tab.text:SetText(MCLL[pinnedSection.name] or pinnedSection.name)
        tab.section = pinnedSection
        tab.content = MCLcore.Frames:createContentFrame(MCL_mainFrame.ScrollChild, pinnedSection.name)
                
        -- Set global reference for pinned content frame (used by functions.lua)
        _G["PinnedFrame"] = tab.content
        _G["PinnedTab"] = tab
        
        -- Populate pinned tab content after creating the frame
        -- Initialize MCL_PINNED if it doesn't exist
        if not MCL_PINNED then
            MCL_PINNED = {}
        end
        
        -- Clean up any invalid pinned mounts before creating the content
        if MCLcore.Function and MCLcore.Function.CleanupInvalidPinnedMounts then
            MCLcore.Function:CleanupInvalidPinnedMounts()
        end
        
        if MCL_PINNED and next(MCL_PINNED) then
            -- Clear any existing mount frames for pinned section
            if MCLcore.mountFrames[1] then
                MCLcore.mountFrames[1] = {}
            end
            -- Create the pinned section content
            if MCLcore.Function and MCLcore.Function.CreateMountsForCategory then
                local overflow, mountFrame = MCLcore.Function:CreateMountsForCategory(MCL_PINNED, _G["PinnedFrame"], 30, _G["PinnedTab"], true, true)
                MCLcore.mountFrames[1] = mountFrame
            end
        end
        
        tab.content:Hide()
        tab:SetScript("OnClick", function(self)
            SelectTab(self)
        end)
        tab:EnableMouse(true)
        tab:SetFrameStrata("HIGH")
        tab:SetFrameLevel(100)
        tab:Show()
        table.insert(tabFrame.tabs, tab)
        -- Also store in navigation frame for overview navigation (pinned)
        if MCLcore.MCL_MF_Nav then
            table.insert(MCLcore.MCL_MF_Nav.tabs, tab)
        end
        table.insert(MCLcore.sectionFrames, tab.content)
        tabIndex = tabIndex + 1
        navYOffset = navYOffset - 28
    end
    -- Select Overview by default
    if selectedTab then
        SelectTab(selectedTab)
    elseif tabFrame.tabs[1] then
        SelectTab(tabFrame.tabs[1])
    end
    return MCLcore.sectionFrames, #tabFrame.tabs
end


function MCL_frames:createNavFrame(relativeFrame, title)
    -- Nav frame is parented to the main frame so it opens/closes together
    -- Don't use insetFrameTemplate for default theme as it has its own styling that conflicts
    local frameTemplate = MCL_SETTINGS.useBlizzardTheme and "MCLBlizzardNavTemplate" or "BackdropTemplate"
    local frame = CreateFrame("Frame", "Nav", relativeFrame, frameTemplate);
    frame:SetWidth(nav_width + 10)  -- Keep original nav width as sidebar
    
    -- Set height to match current main frame height
    local _, currentHeight = MCL_frames:GetCurrentFrameDimensions()
    frame:SetHeight(currentHeight+1)
    
    frame:ClearAllPoints()
    
    -- Consistent positioning for both themes - account for any frame insets
    local xOffset = -1
    local yOffset = 2


    if MCL_SETTINGS.useBlizzardTheme then
        -- Blizzard theme has a different inset, adjust accordingly
        xOffset = 3  -- Adjusted for Blizzard theme
        yOffset = -5
        frame:SetHeight(currentHeight-9)
    end

    
    -- Get the actual frame dimensions and adjust for any template differences
    if MCL_SETTINGS.useBlizzardTheme then
        -- UIPanelDialogTemplate frames have different insets, get actual boundaries
        local left, bottom, width, height = relativeFrame:GetRect()
        if left then
            -- Position relative to the actual frame boundaries
            frame:SetPoint("TOPRIGHT", relativeFrame, "TOPLEFT", xOffset, yOffset)
        else
            -- Fallback positioning
            frame:SetPoint("TOPRIGHT", relativeFrame, "TOPLEFT", xOffset, yOffset)
        end
    else
        -- Default theme - standard positioning
        frame:SetPoint("TOPRIGHT", relativeFrame, "TOPLEFT", xOffset, yOffset)
    end
    
    -- Apply styling after frame creation to ensure it sticks
    if MCL_SETTINGS.useBlizzardTheme then
        -- Blizzard-style backdrop with proper textures
        if frame.SetBackdrop then
            frame:SetBackdrop({
                bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", 
                edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
                edgeSize = 16,
                insets = {left = 4, right = 4, top = 4, bottom = 4}
            })
            frame:SetBackdropColor(0.05, 0.05, 0.15, 0.95)  -- Dark blue tint with higher opacity
            frame:SetBackdropBorderColor(0.4, 0.4, 0.6, 1)  -- Blue-gray border
        end
    else
        -- Default theme - dark background with proper opacity
        if frame.SetBackdrop then
            frame:SetBackdrop({bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", edgeSize = 8})
            frame:SetBackdropColor(0.08, 0.08, 0.08, 0.95)  -- Increased opacity to ensure visibility
            frame:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
        end
    end
    
    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    frame.title:SetPoint("TOP", frame, "TOP", 0, -8)
    frame.title:SetText(title or "")
    
    -- Style the title text for Blizzard theme
    if MCL_SETTINGS.useBlizzardTheme then
        frame.title:SetTextColor(1, 0.82, 0, 1)  -- Gold color like Blizzard UI
    else
        frame.title:SetTextColor(1, 1, 1, 1)  -- White for default theme
    end
    
    -- Create search bar
    frame.searchContainer = CreateFrame("Frame", nil, frame, "BackdropTemplate")
    frame.searchContainer:SetSize(nav_width - 10, 25)
    frame.searchContainer:SetPoint("TOP", frame.title, "BOTTOM", 0, -5)
    frame.searchContainer:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 2
    })
    frame.searchContainer:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
    frame.searchContainer:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
    
    -- Create search editbox
    frame.searchBox = CreateFrame("EditBox", nil, frame.searchContainer)
    frame.searchBox:SetSize(nav_width - 20, 20)
    frame.searchBox:SetPoint("CENTER", frame.searchContainer, "CENTER", 0, 0)
    frame.searchBox:SetFontObject("GameFontHighlightSmall")
    frame.searchBox:SetTextColor(1, 1, 1, 1)
    frame.searchBox:SetAutoFocus(false)
    frame.searchBox:SetMaxLetters(50)
    frame.searchBox:EnableMouse(true)
    frame.searchBox:SetScript("OnEnterPressed", function(self)
        self:ClearFocus()
        MCLcore.Search:PerformSearch(self:GetText())
    end)
    frame.searchBox:SetScript("OnEscapePressed", function(self)
        self:ClearFocus()
        self:SetText("")
        MCLcore.Search:ClearSearchAndGoToOverview()
    end)
    frame.searchBox:SetScript("OnTextChanged", function(self, userInput)
        if userInput then
            local text = self:GetText()
            if text == "" then
                MCLcore.Search:ClearSearchAndGoToOverview()
            end
        end
    end)
    
    -- Create search placeholder text
    frame.searchPlaceholder = frame.searchContainer:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    frame.searchPlaceholder:SetPoint("LEFT", frame.searchBox, "LEFT", 5, 0)
    frame.searchPlaceholder:SetText(MCLL["Search mounts..."])
    frame.searchPlaceholder:SetTextColor(0.6, 0.6, 0.6, 1)
    
    -- Show/hide placeholder based on editbox focus and content
    frame.searchBox:SetScript("OnEditFocusGained", function(self)
        frame.searchPlaceholder:Hide()
    end)
    frame.searchBox:SetScript("OnEditFocusLost", function(self)
        if self:GetText() == "" then
            frame.searchPlaceholder:Show()
        end
    end)
    
    -- Create clear search button
    frame.clearButton = CreateFrame("Button", nil, frame.searchContainer)
    frame.clearButton:SetSize(16, 16)
    frame.clearButton:SetPoint("RIGHT", frame.searchContainer, "RIGHT", -3, 0)
    frame.clearButton:SetNormalTexture("Interface\\FriendsFrame\\ClearBroadcastIcon")
    frame.clearButton:SetScript("OnClick", function()
        frame.searchBox:SetText("")
        frame.searchBox:ClearFocus()
        MCLcore.Search:ClearSearchAndGoToOverview()
        frame.searchPlaceholder:Show()
    end)
    frame.clearButton:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        GameTooltip:SetText(MCLL["Clear Search"], 1, 1, 1)
        GameTooltip:Show()
    end)
    frame.clearButton:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)
    
    -- Ensure the frame is visible and at the correct strata
    frame:SetFrameStrata("HIGH")
    frame:Show()
    
    return frame;
end

-- IMPORTANT: Ensure SetTabs is called before any code that uses MCLcore.overview

function MCL_frames:progressBar(relativeFrame, top)
    MyStatusBar = CreateFrame("StatusBar", nil, relativeFrame, "BackdropTemplate")
    MyStatusBar:SetStatusBarTexture(MCLcore.media:Fetch("statusbar", MCL_SETTINGS.statusBarTexture))
    MyStatusBar:GetStatusBarTexture():SetHorizTile(false)
    MyStatusBar:SetMinMaxValues(0, 100)
    MyStatusBar:SetValue(0)
    MyStatusBar:SetWidth(150)
    MyStatusBar:SetHeight(15)
    if top then
        MyStatusBar:SetPoint("BOTTOMLEFT", relativeFrame, "BOTTOMLEFT", 0, 10)
    else
        MyStatusBar:SetPoint("BOTTOMLEFT", relativeFrame, "BOTTOMLEFT", 0, 10)
    end

    MyStatusBar:SetStatusBarColor(0.1, 0.9, 0.1)

    MyStatusBar.bg = MyStatusBar:CreateTexture(nil, "BACKGROUND")
    MyStatusBar.bg:SetTexture("Interface\\TARGETINGFRAME\\UI-Status-Bar")
    MyStatusBar.bg:SetAllPoints(true)
    MyStatusBar.bg:SetVertexColor(0.843, 0.874, 0.898, 0.5)
    MyStatusBar.Text = MyStatusBar:CreateFontString()
    MyStatusBar.Text:SetFontObject(GameFontWhite)
    MyStatusBar.Text:SetPoint("CENTER")
    MyStatusBar.Text:SetJustifyH("CENTER")
    MyStatusBar.Text:SetText()

    table.insert(MCLcore.statusBarFrames, MyStatusBar)

    return MyStatusBar
end

function MCL_frames:createContentFrame(relativeFrame, title)
    -- Calculate dynamic width based on current main frame width
    local currentWidth, _ = MCL_frames:GetCurrentFrameDimensions()
    local availableWidth = currentWidth - 60  -- 60px for padding
    
    local frame = CreateFrame("Frame", nil, relativeFrame, "BackdropTemplate")
    frame:SetWidth(availableWidth)  -- Use current available width
    frame:SetHeight(50)  -- Increased height to accommodate title padding
    frame:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", 30, 0)  -- Remove nav_width since nav is outside
    
    -- Set opaque background for search results to prevent bleed-through
    if title == "Search Results" then
        frame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 8,
            insets = { left = 4, right = 4, top = 4, bottom = 4 }
        })
        frame:SetBackdropColor(0.05, 0.05, 0.05, 1)  -- Opaque dark background
        frame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
    else
        frame:SetBackdropColor(0, 0, 0, 0)  -- Transparent background for other content
    end
    
    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    frame.title:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -15)  -- Added padding: 15px from left and top
    frame.title:SetText(MCLL[title]) -- Localized for display
    frame.name = title -- Store non-localized name

    -- Add pin instructions for all sections except Overview
    if title == "Pinned" then
        local instructionsFrame = CreateFrame("Frame", nil, frame, "BackdropTemplate")
        instructionsFrame:SetSize(availableWidth - 30, 20)  -- Smaller height for compact display
        instructionsFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 10, -30)  -- Position below title
        instructionsFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 2
        })
        instructionsFrame:SetBackdropColor(0.1, 0.1, 0.2, 0.6)  -- Subtle background
        instructionsFrame:SetBackdropBorderColor(0.4, 0.4, 0.6, 0.8)  -- Subtle border
        
        -- Create the instruction text with color formatting
        local instructionsText = instructionsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        instructionsText:SetPoint("LEFT", instructionsFrame, "LEFT", 10, 0)
        -- Use color codes to make "Ctrl + Right Click" bold and orange
        instructionsText:SetText(MCLL["Pin Instructions Text"] or "|cffFF8800|TInterface\\GossipFrame\\AvailableQuestIcon:0:0:0:0:32:32:0:32:0:32|t Ctrl + Right Click|r to pin/unpin mounts")
        instructionsText:SetTextColor(0.9, 0.9, 1, 1)  -- Light blue-white for the rest of the text
        
        -- Adjust frame height to accommodate instructions
        frame:SetHeight(85)  -- Increased to make room for instructions
    end

    if title ~= "Pinned" then
        frame.pBar = MCLcore.Frames:progressBar(frame)
        local yOffset = title == "Overview" and -15 or -55  -- Adjust based on whether instructions are present
        frame.pBar:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 15, yOffset)  -- Aligned with title padding
        frame.pBar:SetWidth(availableWidth - 30)  -- Account for padding on both sides
        frame.pBar:SetHeight(20)
    end

    return frame
end


function MCL_frames:createOverviewCategory(set, relativeFrame)
    if not set or not relativeFrame then
        return
    end

    -- Use the same layout calculations as createCategoryFrame for consistency
    local currentWidth, _ = MCL_frames:GetCurrentFrameDimensions()
    local availableWidth = currentWidth - 60  -- Total content width
    local columnSpacing = 25  -- Spacing between columns
    local numColumns = 2
    local columnWidth = math.floor((availableWidth - columnSpacing * (numColumns - 1)) / numColumns)
    
    local leftColumnX = 15  -- Start with padding from left edge
    local rightColumnX = leftColumnX + columnWidth + columnSpacing
    
    local leftColumnY = -30  -- Reduced from -60 for tighter spacing
    local rightColumnY = -30
    local sectionIndex = 0

    -- Create sections similar to how categories are created in other tabs
    for k, v in pairs(set) do
        if (v.name ~= "Overview") and (v.name ~= "Pinned") then
            sectionIndex = sectionIndex + 1
            
            -- Determine which column to use (alternate left/right)
            local isLeftColumn = (sectionIndex % 2 == 1)
            local xPos = isLeftColumn and leftColumnX or rightColumnX
            local yPos = isLeftColumn and leftColumnY or rightColumnY
            
            -- Get actual stats for this section
            local sectionStats = MCLcore.stats and MCLcore.stats[v.name]
            local totalMounts = (sectionStats and sectionStats.total) or 0
            local collectedMounts = (sectionStats and sectionStats.collected) or 0
            
            -- Create section frame without background
            local sectionFrame = CreateFrame("Frame", nil, relativeFrame)
            sectionFrame:SetWidth(columnWidth)  -- Use calculated column width
            sectionFrame:SetHeight(50)  -- Reduced from 65 to 50 for even tighter spacing
            sectionFrame:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", xPos, yPos)
            
            -- Section title with smaller font
            sectionFrame.title = sectionFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
            sectionFrame.title:SetPoint("TOPLEFT", sectionFrame, "TOPLEFT", 5, -2)  -- Reduced padding
            sectionFrame.title:SetText(MCLL[v.name] or v.name)
            sectionFrame.title:SetTextColor(1, 1, 1, 1)
            
            -- Create progress bar container with dynamic width based on column width
            local progressContainer = CreateFrame("Frame", nil, sectionFrame)
            progressContainer:SetWidth(columnWidth - 10)  -- Use column width with padding
            progressContainer:SetHeight(16)  -- Smaller height
            progressContainer:SetPoint("TOPLEFT", sectionFrame.title, "BOTTOMLEFT", 0, -5)  -- Reduced spacing
            
            -- Create progress bar with background
            local pBar = CreateFrame("StatusBar", nil, progressContainer, "BackdropTemplate")
            
            -- Add dark background to the progress bar
            pBar:SetBackdrop({
                bgFile = "Interface\\Buttons\\WHITE8x8",
                edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                edgeSize = 1
            })
            pBar:SetBackdropColor(0.1, 0.1, 0.1, 0.8)  -- Dark background
            pBar:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)  -- Subtle border
            
            -- Use settings texture if available, otherwise fallback to TargetingFrame
            local textureToUse = "Interface\\TargetingFrame\\UI-StatusBar"  -- Good default that colors well
            if MCL_SETTINGS and MCL_SETTINGS.statusBarTexture and MCLcore.media then
                local settingsTexture = MCLcore.media:Fetch("statusbar", MCL_SETTINGS.statusBarTexture)
                if settingsTexture then
                    textureToUse = settingsTexture
                end
            end
            
            pBar:SetStatusBarTexture(textureToUse)
            pBar:GetStatusBarTexture():SetHorizTile(false)
            pBar:GetStatusBarTexture():SetVertTile(false)
            pBar:SetMinMaxValues(0, 100)
            pBar:SetValue(0)
            pBar:SetAllPoints(progressContainer)
            
            -- Text for progress bar
            pBar.Text = pBar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            pBar.Text:SetPoint("CENTER", pBar, "CENTER", 0, 0)
            pBar.Text:SetJustifyH("CENTER")
            pBar.Text:SetTextColor(1, 1, 1, 1)
            
            -- Update progress bar with actual data
            if totalMounts > 0 then
                local percentage = (collectedMounts / totalMounts) * 100
                pBar:SetValue(percentage)
                pBar.Text:SetText(string.format("%d/%d (%d%%)", collectedMounts, totalMounts, math.floor(percentage)))
                
                -- Use the same color logic as other progress bars
                pBar.val = percentage
                UpdateProgressBar(pBar, totalMounts, collectedMounts)
            else
                pBar:SetValue(0)
                pBar.Text:SetText("0/0 (0%)")
                pBar:SetStatusBarColor(0.5, 0.5, 0.5)  -- Gray for no data
            end
            
            -- Store this in the same way other progress bars are stored
            -- Check if this progress bar is already in the table to prevent duplicates
            local alreadyExists = false
            if MCLcore.statusBarFrames then
                for _, existingBar in ipairs(MCLcore.statusBarFrames) do
                    if existingBar == pBar then
                        alreadyExists = true
                        break
                    end
                end
            end
            if not alreadyExists then
                table.insert(MCLcore.statusBarFrames, pBar)
            end
            
            -- Add hover effects like other sections
            pBar:HookScript("OnEnter", function()
                -- Store the current color before changing to hover color
                local r, g, b, a = pBar:GetStatusBarColor()
                pBar.originalR = r
                pBar.originalG = g
                pBar.originalB = b
                pBar:SetStatusBarColor(0.8, 0.5, 0.9, 1)  -- Purple hover color
            end)
            pBar:HookScript("OnLeave", function()
                -- Restore the stored original color
                if pBar.originalR and pBar.originalG and pBar.originalB then
                    pBar:SetStatusBarColor(pBar.originalR, pBar.originalG, pBar.originalB)
                else
                    -- Fallback: recalculate the color if we don't have stored values
                    if totalMounts > 0 then
                        local percentage = (collectedMounts / totalMounts) * 100
                        if percentage < 33 then
                            pBar:SetStatusBarColor(MCL_SETTINGS.progressColors.low.r, MCL_SETTINGS.progressColors.low.g, MCL_SETTINGS.progressColors.low.b)
                        elseif percentage < 66 then
                            pBar:SetStatusBarColor(MCL_SETTINGS.progressColors.medium.r, MCL_SETTINGS.progressColors.medium.g, MCL_SETTINGS.progressColors.medium.b)
                        elseif percentage < 100 then
                            pBar:SetStatusBarColor(MCL_SETTINGS.progressColors.high.r, MCL_SETTINGS.progressColors.high.g, MCL_SETTINGS.progressColors.high.b)
                        else
                            pBar:SetStatusBarColor(MCL_SETTINGS.progressColors.complete.r, MCL_SETTINGS.progressColors.complete.g, MCL_SETTINGS.progressColors.complete.b)
                        end
                    else
                        pBar:SetStatusBarColor(0.5, 0.5, 0.5)  -- Gray for no data
                    end
                end
            end)
            
            -- Handle unobtainable sections
            if v.name == "Unobtainable" then
                pBar.unobtainable = MCL_SETTINGS.unobtainable
                if MCL_SETTINGS.unobtainable == true then
                    sectionFrame:Hide()
                end
            end

            -- Add click functionality to navigate to the section
            pBar:SetScript("OnMouseDown", function(self, button)
                if button == 'LeftButton' then
                    -- Find the corresponding tab and select it
                    local navFrame = MCLcore.MCL_MF_Nav
                    if navFrame and navFrame.tabs then
                        for _, tab in ipairs(navFrame.tabs) do
                            if tab.section and tab.section.name == v.name then
                                -- Use the same selection logic as in SetTabs
                                for _, t in ipairs(navFrame.tabs) do
                                    if t.content then t.content:Hide() end
                                    if t.SetBackdropBorderColor then
                                        t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                                    end
                                end
                                if tab.SetBackdropBorderColor then
                                    tab:SetBackdropBorderColor(1, 0.82, 0, 1)
                                end
                                if MCL_mainFrame and MCL_mainFrame.ScrollFrame then
                                    -- Always keep the main scroll child as the scroll child
                                    MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                                    if tab.content then
                                        tab.content:Show()
                                    end
                                    MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
                                end
                                break
                            end
                        end
                    end
                end
            end)
            
            -- Store frame reference for updates
            local t = {
                name = v.name, -- Use non-localized name for identification
                frame = pBar
            }
            
            -- Initialize overviewFrames if it doesn't exist
            if not MCLcore.overviewFrames then
                MCLcore.overviewFrames = {}
            end
            
            -- Check for duplicates before adding
            local alreadyExists = false
            for _, existingFrame in ipairs(MCLcore.overviewFrames) do
                if existingFrame.name == v.name then
                    alreadyExists = true
                    break
                end
            end
            
            if not alreadyExists then
                table.insert(MCLcore.overviewFrames, t)
            end
            
            -- Update column positions for next section
            if isLeftColumn then
                leftColumnY = leftColumnY - 55  -- Reduced from 75 to 55 (section height 50 + 5 spacing)
            else
                rightColumnY = rightColumnY - 55
            end
        end
    end
    
    -- Adjust parent frame height to accommodate all sections with proper padding
    local maxY = math.min(leftColumnY, rightColumnY)
    local requiredHeight = math.abs(maxY) + 40  -- Add more padding for better spacing
    relativeFrame:SetHeight(requiredHeight)
end


----------------------------------------------------------------
-- Creating a placeholder for each category, this is where we attach each mount to.
----------------------------------------------------------------

function MCL_frames:createCategoryFrame(set, relativeFrame, sectionName)
    if not set then
        return
    end

    -- Check if set has any data
    local hasData = false
    for k, v in pairs(set) do
        hasData = true
        break
    end
    
    if not hasData then
        return
    end

    -- Dynamic layout calculation based on current frame width
    local currentWidth, _ = MCL_frames:GetCurrentFrameDimensions()
    local availableWidth = currentWidth - 60  -- Total content width
    local columnSpacing = 25  -- Reduced spacing between columns to use more space
    local numColumns = 2
    local columnWidth = math.floor((availableWidth - columnSpacing * (numColumns - 1)) / numColumns)
    
    local leftColumnX = 0
    local rightColumnX = leftColumnX + columnWidth + columnSpacing
    
    local leftColumnY = -50
    local rightColumnY = -50
    local categoryIndex = 0

    -- Get sorted category names
local sortedCategoryNames = {}
for k, v in pairs(set) do
    if type(v) == "table" then
        table.insert(sortedCategoryNames, k)
    end
end
table.sort(sortedCategoryNames)

local leftColumnY = -50
local rightColumnY = -50
local categoryIndex = 0

for _, categoryName in ipairs(sortedCategoryNames) do
    local categoryData = set[categoryName]
    -- Calculate mount stats for this category first (needed for dynamic height)
    local totalMounts = 0
    local collectedMounts = 0
    local displayedMounts = 0  -- Track mounts that will actually be displayed
    
    -- Combine both mounts and mountID arrays
    local mountList = {}
    if categoryData.mounts then
        for _, mount in ipairs(categoryData.mounts) do
            table.insert(mountList, mount)
        end
    end
    if categoryData.mountID then
        for _, mount in ipairs(categoryData.mountID) do
            table.insert(mountList, mount)
        end
    end
    
    for _, mountId in ipairs(mountList) do
        local mount_Id = MCLcore.Function:GetMountID(mountId)
        if mount_Id then
            -- Faction check: Only count mounts that are not faction-specific or match the player's faction
            local faction, faction_specific = MCLcore.Function.IsMountFactionSpecific(mountId)
            local playerFaction = UnitFactionGroup("player")
            local allowed = false
            if faction_specific == false then
                allowed = true
            elseif faction_specific == true then
                if faction == 0 then faction = "Horde" elseif faction == 1 then faction = "Alliance" end
                allowed = (faction == playerFaction)
            end
            if allowed then
                local isCollected = IsMountCollected(mount_Id)
                totalMounts = totalMounts + 1
                if isCollected then
                    collectedMounts = collectedMounts + 1
                end
                if not (MCL_SETTINGS.hideCollectedMounts and isCollected) then
                    displayedMounts = displayedMounts + 1
                end
                
            end
        end
    end

    -- Only increment categoryIndex if the category is actually displayed (e.g., displayedMounts > 0)
    if displayedMounts > 0 then
        categoryIndex = categoryIndex + 1
        -- Determine which column to use (alternate left/right)
        local isLeftColumn = (categoryIndex % 2 == 1)
        local xPos = isLeftColumn and leftColumnX or rightColumnX
        local yPos = isLeftColumn and leftColumnY or rightColumnY
        
        -- Calculate optimal mounts per row based on column width (same calculation as later)
        local categoryPadding = 20  -- Total padding (10px on each side)
        local availableMountWidth = columnWidth - categoryPadding
        
        -- Start with user's preferred mounts per row
        local mountsPerRow = MCL_SETTINGS.mountsPerRow or 12  -- Use setting or default to 12
        -- Ensure it's within bounds
        mountsPerRow = math.max(6, math.min(mountsPerRow, 24))
        
        -- Calculate mount size to fit exactly within available width
        local desiredSpacing = 4  -- Fixed spacing between mounts
        local minMountSize = 16  -- Absolute minimum mount size (reduced from 24)
        local maxMountSize = 48  -- Maximum mount size
        
        -- Try the preferred mounts per row first
        local totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
        local availableForMounts = availableMountWidth - totalSpacingWidth
        local mountSize = math.floor(availableForMounts / mountsPerRow)
        
        -- If mount size is too small, reduce mounts per row until we get acceptable size
        while mountSize < minMountSize and mountsPerRow > 6 do
            mountsPerRow = mountsPerRow - 1
            totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
            availableForMounts = availableMountWidth - totalSpacingWidth
            mountSize = math.floor(availableForMounts / mountsPerRow)
        end
        
        -- Ensure mount size is within bounds
        mountSize = math.max(minMountSize, math.min(mountSize, maxMountSize))
        
        -- Recalculate actual spacing to center the grid
        local actualMountWidth = mountSize * mountsPerRow
        local actualSpacing = mountsPerRow > 1 and math.floor((availableMountWidth - actualMountWidth) / (mountsPerRow - 1)) or 0
        actualSpacing = math.max(1, actualSpacing)  -- Minimum 1px spacing (reduced from 2)
        
        -- Calculate dynamic height based on actual mount layout
        local numRows = math.ceil(displayedMounts / mountsPerRow)
        local baseHeight = 80  -- Base height (title + progress bar + padding)
        local rowSpacing = 4  -- Minimal Y-axis spacing between rows (reduced)
        local rowHeight = mountSize + rowSpacing  -- Actual row height based on calculated mount size
        local categoryHeight = baseHeight + (numRows * rowHeight) + 10  -- Reduced bottom padding
        
        -- Create category frame with dynamic height
        local categoryFrame = CreateFrame("Frame", nil, relativeFrame, "BackdropTemplate")

        categoryFrame:SetWidth(columnWidth)
        categoryFrame:SetHeight(categoryHeight)  -- Dynamic height
        categoryFrame:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", xPos, yPos)
        categoryFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 8
        })
        categoryFrame:SetBackdropColor(0.05, 0.05, 0.05, 0.9)
        categoryFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
        categoryFrame:SetPoint("TOPLEFT", relativeFrame, "TOPLEFT", xPos, yPos)
        categoryFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 8
        })
        categoryFrame:SetBackdropColor(0.05, 0.05, 0.05, 0.9)
        categoryFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)

        -- Category title
        categoryFrame.title = categoryFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
        categoryFrame.title:SetPoint("TOPLEFT", categoryFrame, "TOPLEFT", 10, -8)
        categoryFrame.title:SetText(MCLL[categoryData.name] or MCLL[categoryName] or categoryData.name or categoryName)
        categoryFrame.title:SetTextColor(1, 1, 1, 1)
        
        -- Create progress bar container
        local progressContainer = CreateFrame("Frame", nil, categoryFrame)
        progressContainer:SetWidth(columnWidth - 20)  -- Now 500px wide
        progressContainer:SetHeight(18)
        progressContainer:SetPoint("TOPLEFT", categoryFrame.title, "BOTTOMLEFT", 0, -5)
        
        -- Create progress bar using proper texture fallback
        local pBar = CreateFrame("StatusBar", nil, progressContainer, "BackdropTemplate")
        
        -- Use settings texture if available, otherwise fallback to TargetingFrame
        local textureToUse = "Interface\\TargetingFrame\\UI-StatusBar"  -- Good default that colors well
        if MCL_SETTINGS and MCL_SETTINGS.statusBarTexture and MCLcore.media then
            local settingsTexture = MCLcore.media:Fetch("statusbar", MCL_SETTINGS.statusBarTexture)
            if settingsTexture then
                textureToUse = settingsTexture
            end
        end
        
        pBar:SetStatusBarTexture(textureToUse)
        pBar:GetStatusBarTexture():SetHorizTile(false)
        pBar:GetStatusBarTexture():SetVertTile(false)
        pBar:SetMinMaxValues(0, 100)
        pBar:SetValue(0)
        pBar:SetAllPoints(progressContainer)
        
        -- Background for progress bar
        pBar:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 1
        })
        pBar:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
        pBar:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        
        -- Text for progress bar
        pBar.Text = pBar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        pBar.Text:SetPoint("CENTER", pBar, "CENTER", 0, 0)
        pBar.Text:SetTextColor(1, 1, 1, 1)
        
        -- Update progress bar
        local percentage = totalMounts > 0 and (collectedMounts / totalMounts) * 100 or 0
        pBar:SetValue(percentage)
        pBar.Text:SetText(string.format("%d/%d (%d%%)", collectedMounts, totalMounts, percentage))
        
        -- Use the UpdateProgressBar function for consistent coloring
        pBar.val = percentage
        UpdateProgressBar(pBar, totalMounts, collectedMounts)
        
        -- Store this progress bar in the statusBarFrames table for settings updates
        table.insert(MCLcore.statusBarFrames, pBar)
        
        -- Mount grid within category - positioned below progress bar
        local mountStartY = -60  -- More padding below progress bar
        
        -- Use the same calculations as in height calculation for consistency
        local categoryPadding = 20  -- Total padding (10px on each side)
        local availableMountWidth = columnWidth - categoryPadding
        
        -- Start with user's preferred mounts per row
        local mountsPerRow = MCL_SETTINGS.mountsPerRow or 12  -- Use setting or default to 12
        -- Ensure it's within bounds
        mountsPerRow = math.max(6, math.min(mountsPerRow, 24))
        
        -- Calculate mount size to fit exactly within available width
        local desiredSpacing = 4  -- Fixed spacing between mounts
        local minMountSize = 16  -- Absolute minimum mount size (reduced from 24)
        local maxMountSize = 48  -- Maximum mount size
        
        -- Try the preferred mounts per row first
        local totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
        local availableForMounts = availableMountWidth - totalSpacingWidth
        local mountSize = math.floor(availableForMounts / mountsPerRow)
        
        -- If mount size is too small, reduce mounts per row until we get acceptable size
        while mountSize < minMountSize and mountsPerRow > 6 do
            mountsPerRow = mountsPerRow - 1
            totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
            availableForMounts = availableMountWidth - totalSpacingWidth
            mountSize = math.floor(availableForMounts / mountsPerRow)
        end
        
        -- Ensure mount size is within bounds
        mountSize = math.max(minMountSize, math.min(mountSize, maxMountSize))
        
        -- Recalculate actual spacing to center the grid
        local actualMountWidth = mountSize * mountsPerRow
        local actualSpacing = mountsPerRow > 1 and math.floor((availableMountWidth - actualMountWidth) / (mountsPerRow - 1)) or 0
        actualSpacing = math.max(1, actualSpacing)  -- Minimum 1px spacing (reduced from 2)
        
        -- Y-axis spacing (only affected by height changes)
        local rowSpacing = 4  -- Minimal Y-axis spacing between rows
        
        local maxDisplayMounts = displayedMounts  -- Show all displayed mounts instead of limiting to 24
        local mountStartX = 10
        local displayedIndex = 0  -- Track the actual displayed position
        
        for i, mountId in ipairs(mountList) do
            -- Check if we should skip this mount due to hide collected mounts setting
            local mount_Id = MCLcore.Function:GetMountID(mountId)
            -- Faction check: Only display mounts that are not faction-specific or match the player's faction
            local faction, faction_specific = MCLcore.Function.IsMountFactionSpecific(mountId)
            local playerFaction = UnitFactionGroup("player")
            local allowed = false
            if faction_specific == false then
                allowed = true
            elseif faction_specific == true then
                if faction == 0 then faction = "Horde" elseif faction == 1 then faction = "Alliance" end
                allowed = (faction == playerFaction)
            end
            if allowed and not (mount_Id and MCL_SETTINGS.hideCollectedMounts and IsMountCollected(mount_Id)) then
                displayedIndex = displayedIndex + 1
                if displayedIndex <= maxDisplayMounts then
                local col = ((displayedIndex-1) % mountsPerRow)
                local row = math.floor((displayedIndex-1) / mountsPerRow)
                
                -- Calculate exact position for this icon
                local iconX = mountStartX + col * (mountSize + actualSpacing)
                local iconY = mountStartY - row * (mountSize + rowSpacing)  -- Use rowSpacing for Y
                
                -- Create backdrop frame first (smaller than spacing to create visual gaps)
                local backdropSize = mountSize + 2  -- Only 1px overhang on each side for visual separation
                local backdropFrame = CreateFrame("Frame", nil, categoryFrame, "BackdropTemplate")
                backdropFrame:SetSize(backdropSize, backdropSize)
                backdropFrame:SetPoint("TOPLEFT", categoryFrame, "TOPLEFT", 
                    iconX - 1, -- Minimal offset for overhang
                    iconY + 1) -- Minimal offset for overhang
                
                -- Store the mount ID for search functionality
                backdropFrame.mountID = mountId
                
                -- Create mount frame (for icon) centered in backdrop
                local mountFrame = CreateFrame("Button", nil, backdropFrame)
                mountFrame:SetSize(mountSize, mountSize)
                mountFrame:SetPoint("CENTER", backdropFrame, "CENTER", 0, 0)                            -- Store the mount ID for search functionality
                            mountFrame.mountID = mountId
                            
                            -- Set category and section for pinning functionality
                            mountFrame.category = categoryData.name or categoryName
                            mountFrame.section = sectionName or "Unknown"
                            
                            -- Get mount info and set icon
                            if mount_Id and type(mount_Id) == "number" and mount_Id > 0 then
                                local mountName, spellID, icon = C_MountJournal.GetMountInfoByID(mount_Id)
                                if icon then
                            -- Create the icon texture
                            mountFrame.tex = mountFrame:CreateTexture(nil, "ARTWORK")
                            mountFrame.tex:SetAllPoints(mountFrame)
                            mountFrame.tex:SetTexture(icon)
                            
                            -- Create pin icon for this mount frame
                            mountFrame.pin = mountFrame:CreateTexture(nil, "OVERLAY")
                            mountFrame.pin:SetWidth(16)
                            mountFrame.pin:SetHeight(16)
                            mountFrame.pin:SetTexture("Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pin.blp")
                            mountFrame.pin:SetPoint("TOPRIGHT", mountFrame, "TOPRIGHT", 6, 6)
                            
                            -- Check if this mount is pinned and set pin visibility
                            local pin_check = MCLcore.Function:CheckIfPinned("m"..mount_Id)
                            if pin_check == true then
                                mountFrame.pin:SetAlpha(1)
                            else
                                mountFrame.pin:SetAlpha(0)
                            end
                            
                            -- Check if mount is collected and style backdrop accordingly
                            if IsMountCollected(mount_Id) then
                                -- Collected mount styling - green background with thick border
                                mountFrame.tex:SetVertexColor(1, 1, 1, 1)
                                backdropFrame:SetBackdrop({
                                    bgFile = "Interface\\Buttons\\WHITE8x8",
                                    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                                    edgeSize = 3  -- Thicker border
                                })
                                backdropFrame:SetBackdropColor(0, 0.8, 0, 0.6)  -- Brighter green background
                                backdropFrame:SetBackdropBorderColor(0, 1, 0, 1)  -- Bright green border
                            else
                                -- Uncollected mount styling - red/dark background
                                mountFrame.tex:SetVertexColor(0.4, 0.4, 0.4, 0.7)
                                backdropFrame:SetBackdrop({
                                    bgFile = "Interface\\Buttons\\WHITE8x8",
                                    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                                    edgeSize = 2  -- Slightly thinner border for uncollected
                                })
                                backdropFrame:SetBackdropColor(0.3, 0.1, 0.1, 0.4)  -- Reddish background
                                backdropFrame:SetBackdropBorderColor(0.6, 0.2, 0.2, 0.8)  -- Red border
                            end
                            
                            -- Add mount interaction to the mount frame
                            if MCLcore.Function and MCLcore.Function.LinkMountItem then
                                MCLcore.Function:LinkMountItem(mountId, mountFrame, false, false)
                            end
                        end
                    end
                end  -- Close the if block for displayedIndex <= maxDisplayMounts
            else
                --[[ Debug logging for skipped mounts
                if MCLcore.Debug then
                    local isCollected = mount_Id and IsMountCollected(mount_Id)
                    local reason = ""
                    if not allowed then
                        reason = "Faction restriction"
                    elseif mount_Id and MCL_SETTINGS.hideCollectedMounts and isCollected then
                        reason = "Hidden collected mount"
                    else
                        reason = "Unknown reason"
                    end
                end]]
            end
        end  -- Close the for loop
        
        -- Update column positions for next category
        if isLeftColumn then
            leftColumnY = leftColumnY - (categoryHeight + 8)  -- Reduced spacing between categories
        else
            rightColumnY = rightColumnY - (categoryHeight + 8)  -- Reduced spacing between categories
        end
        
    end
end
    
    -- Adjust parent frame height to accommodate all categories with proper padding
    local maxY = math.min(leftColumnY, rightColumnY)
    local requiredHeight = math.abs(maxY) + 20  -- Reduced padding for tighter layout
    relativeFrame:SetHeight(requiredHeight)
end

-- Helper function to get current frame dimensions
function MCL_frames:GetCurrentFrameDimensions()
    if MCL_mainFrame then
        local width = MCL_mainFrame:GetWidth()
        local height = MCL_mainFrame:GetHeight()
        return width, height
    end
    return main_frame_width, main_frame_height  -- Fallback to defaults
end

-- Function to refresh layout after resize
function MCL_frames:RefreshLayout()
    if not MCL_mainFrame then return end
    
    -- Remember which tab was selected before refresh
    local selectedTabName = nil
    local wasShowingSearchResults = false
    local navFrame = MCLcore.MCL_MF_Nav
    if navFrame and navFrame.tabs then
        for _, tab in ipairs(navFrame.tabs) do
            if tab.content and tab.content:IsShown() then
                selectedTabName = tab.section and tab.section.name
                break
            end
        end
        -- Check if search results are currently being shown
        if MCLcore.searchResultsContent and MCLcore.searchResultsContent:IsShown() then
            wasShowingSearchResults = true
        end
    end
    
    -- Update scroll frame size
    MCL_mainFrame.ScrollFrame:ClearAllPoints()
    MCL_mainFrame.ScrollFrame:SetPoint("TOPLEFT", MCL_mainFrame, "TOPLEFT", 10, -40)
    MCL_mainFrame.ScrollFrame:SetPoint("BOTTOMRIGHT", MCL_mainFrame, "BOTTOMRIGHT", -10, 10)
    
    -- Update scroll child size
    if MCL_mainFrame.ScrollChild then
        local currentWidth, currentHeight = MCL_frames:GetCurrentFrameDimensions()
        MCL_mainFrame.ScrollChild:SetSize(currentWidth, currentHeight)
    end
    
    -- Update navigation frame height to match main frame
    if MCLcore.MCL_MF_Nav then
        local _, currentHeight = MCL_frames:GetCurrentFrameDimensions()
        MCLcore.MCL_MF_Nav:SetHeight(currentHeight)
    end
    
    -- Recreate tabs with new dimensions
    if MCL_frames.SetTabs then
        MCL_frames:SetTabs()
        
        -- Recreate search results content frame if it exists and is currently showing
        if MCLcore.searchResultsContent and wasShowingSearchResults then
            -- If search is active, recreate the search results with new dimensions
            if MCLcore.Search and MCLcore.Search.isSearchActive then
                C_Timer.After(0.1, function()
                    MCLcore.Search:RecreateSearchResultsFrame()
                end)
            end
        end
        
        -- If we're on the overview page, we need to refresh it since it has dynamic content
        if selectedTabName == "Overview" and MCLcore.overview then
            -- Clear existing overview content more thoroughly
            local children = {MCLcore.overview:GetChildren()}
            for i = 1, #children do
                local child = children[i]
                if child then
                    child:Hide()
                    child:ClearAllPoints()
                    child:SetParent(nil)
                end
            end
            
            -- Clear the overview frames array to prevent duplicates
            if MCLcore.overviewFrames then
                MCLcore.overviewFrames = {}
            end
            
            -- Recreate overview content with new dimensions
            if MCLcore.sections and MCL_frames.createOverviewCategory then
                MCL_frames:createOverviewCategory(MCLcore.sections, MCLcore.overview)
            end
        end
        
        -- Restore the previously selected tab (unless we're showing search results)
        if selectedTabName and navFrame and navFrame.tabs and not wasShowingSearchResults then
            for _, tab in ipairs(navFrame.tabs) do
                if tab.section and tab.section.name == selectedTabName then
                    -- Use the same selection logic as in SetTabs
                    for _, t in ipairs(navFrame.tabs) do
                        if t.content then t.content:Hide() end
                        if t.SetBackdropBorderColor then
                            t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                        end
                    end
                    -- Also properly destroy search results content if it exists
                    if MCLcore.Search and MCLcore.Search.DestroySearchResultsFrame then
                        MCLcore.Search:DestroySearchResultsFrame()
                    end
                    if tab.SetBackdropBorderColor then
                        tab:SetBackdropBorderColor(1, 0.82, 0, 1)
                    end
                    if MCL_mainFrame and MCL_mainFrame.ScrollFrame then
                        -- Always keep the main scroll child as the scroll child
                        MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                        if tab.content then
                            tab.content:Show()
                        end
                        MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
                    end
                    break
                end
            end
        end
    end
    collectgarbage("collect")    
end

-- Function to save frame size to settings
function MCL_frames:SaveFrameSize()
    if MCL_mainFrame and MCL_SETTINGS then
        MCL_SETTINGS.frameWidth = MCL_mainFrame:GetWidth()
        MCL_SETTINGS.frameHeight = MCL_mainFrame:GetHeight()
    end
end

-- Function to restore frame size from settings
function MCL_frames:RestoreFrameSize()
    if MCL_mainFrame and MCL_SETTINGS then
        local width = MCL_SETTINGS.frameWidth or main_frame_width
       
        local height = MCL_SETTINGS.frameHeight or main_frame_height
        MCL_mainFrame:SetSize(width, height)
    end
end

-- Function to calculate minimum height based on navigation content
function MCL_frames:CalculateMinHeight()
    local baseHeight = 100  -- Base height for frame borders, title, etc.
    local navStartY = -20   -- Starting Y position for nav items
    local currentY = navStartY
    
    -- Calculate sections like in SetTabs
    local sections = MCLcore.sectionsOrdered or MCLcore.sections
    if not sections then
        return baseHeight + 200  -- Fallback minimum
    end
    
    local overviewSection, pinnedSection, expansionSections, otherSections = nil, nil, {}, {}
    for _, v in ipairs(sections) do
        if v.name == "Overview" then
            overviewSection = v
        elseif v.name == "Pinned" then
            pinnedSection = v
        elseif v.isExpansion then
            table.insert(expansionSections, v)
        else
            table.insert(otherSections, v)
        end
    end
    
    -- 1. Overview section (32px height + 4px spacing)
    if overviewSection then
        currentY = currentY - 36
    end
    
    -- 2. Expansion grid (calculate rows needed)
    if #expansionSections > 0 then
        local gridCols = 3
        local iconSize = 36
        local iconPad = 8
        local gridRows = math.ceil(#expansionSections / gridCols)
        local gridHeight = gridRows * (iconSize + iconPad)
        currentY = currentY - gridHeight - 10  -- 10px spacing after grid
    end
    
    -- 3. Other sections (28px each)
    for _, v in ipairs(otherSections) do
        currentY = currentY - 28
    end
    
    -- 4. Pinned section (28px)
    if pinnedSection then
        currentY = currentY - 28
    end
    
    -- Convert negative Y offset to positive height requirement
    local requiredNavHeight = math.abs(currentY) + 40  -- 40px bottom padding
    local totalMinHeight = baseHeight + requiredNavHeight
    
    return math.max(totalMinHeight, 300)  -- Ensure at least 300px minimum
end


-- MCL Notification System
-- Shows update notifications and first-time user messages

local MCL = MCL or {}
MCL.Notifications = {}

-- Make MCL globally accessible
_G["MCL"] = MCL

-- Current version from TOC (update this when version changes)
local CURRENT_VERSION = "2.6.4"

-- Notification messages
local NOTIFICATION_MESSAGES = {
    welcome = {
        title = "Welcome to Mount Collection Log!",
        text = "Thank you for choosing MCL to enhance your mount collecting experience!\n\n" ..
               "Mount Collection Log helps you track and organize your mount collection with advanced features:\n\n" ..
               "• |cFF00FF00Detailed Collection Statistics|r - See your progress at a glance\n" ..
               "• |cFF00FF00Mount Filtering|r - Find specific mounts by expansion, type, or source\n" ..
               "• |cFF00FF00Missing Mount Finder|r - Discover which mounts you still need\n" ..
               "• |cFF00FF00Collection Comparison|r - Compare with other players\n\n" ..
               "|cFFFFD700Don't forget to check out our sister addon:|r\n" ..
               "|cFF1FB7EBPet Collection Log (PCL)|r - The ultimate battle pet tracking companion!\n\n" ..
               "Click the minimap button or use |cFFFFFFFF/mcl|r to get started!",
        icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\mcl-logo-32"
    },
    update = {
        title = "MCL Updated to v" .. CURRENT_VERSION .. "!",
        text = "Mount Collection Log has been successfully updated!\n\n" ..
               "|cFF00FF00What's new in this version:|r\n" ..
               "• Enhanced notification system for better user experience\n" ..
               "• Improved performance and stability\n" ..
               "• Bug fixes and optimizations\n\n" ..
               "|cFFFFD700Keep your collection complete with:|r\n" ..
               "• |cFF1FB7EBMount Collection Log|r - For comprehensive mount tracking\n" ..
               "• |cFF1FB7EBPet Collection Log|r - For all your battle pet needs\n\n" ..
               "Thank you for using MCL and supporting our development!",
        icon = "Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\mcl-logo-32"
    }
}

-- Create the notification frame
local function CreateNotificationFrame()
    -- Use the same template as the main addon window
    local frameTemplate = (MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme) and "MCLBlizzardFrameTemplate" or "MCLFrameTemplateWithInset"
    local frame = CreateFrame("Frame", "MCLNotificationFrame", UIParent, frameTemplate)
    frame:SetSize(400, 300)
    frame:SetPoint("CENTER")
    frame:SetFrameStrata("DIALOG")
    
    -- Apply the same styling as the main window
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        -- Hide nine-slice elements like the main frame does
        if frame.NineSlice then frame.NineSlice:Hide() end
    else
        -- Apply the same background styling as main frame
        if frame.Bg then
            local opacity = (MCL_SETTINGS and MCL_SETTINGS.opacity) or 0.95
            frame.Bg:SetVertexColor(0, 0, 0, opacity)
        end
        if frame.TitleBg then
            frame.TitleBg:SetVertexColor(0.1, 0.1, 0.1, 0.95)
        end
        -- Add border like the main frame (only if MCLcore is available)
        if MCLcore and MCLcore.Function and MCLcore.Function.CreateFullBorder then
            MCLcore.Function:CreateFullBorder(frame)
        end
    end
    
    frame:EnableMouse(true)
    frame:SetMovable(true)
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", frame.StartMoving)
    frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
    
    -- Use the template's built-in close button (no need to create our own)
    if frame.CloseButton then
        frame.CloseButton:SetScript("OnClick", function() frame:Hide() end)
    end
    
    -- Icon
    local icon = frame:CreateTexture(nil, "ARTWORK")
    icon:SetSize(32, 32)
    icon:SetPoint("TOPLEFT", 20, -20)
    frame.icon = icon
    
    -- Title - style it like the main window title
    local title = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", icon, "TOPRIGHT", 10, -5)
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        title:SetTextColor(1, 0.82, 0, 1)  -- Gold color like Blizzard UI
    else
        title:SetTextColor(0.12, 0.72, 0.92, 1)  -- MCL blue color
    end
    frame.title = title
    
    -- Message text
    local messageText = frame:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    messageText:SetPoint("TOPLEFT", 20, -60)
    messageText:SetPoint("TOPRIGHT", -20, -60)
    messageText:SetJustifyH("LEFT")
    messageText:SetJustifyV("TOP")
    messageText:SetWordWrap(true)
    frame.messageText = messageText
    
    -- OK Button
    local okButton = CreateFrame("Button", nil, frame, "GameMenuButtonTemplate")
    okButton:SetSize(100, 30)
    okButton:SetPoint("BOTTOM", 0, 20)
    okButton:SetText("OK")
    okButton:SetScript("OnClick", function() frame:Hide() end)
    
    frame:Hide()
    return frame
end

-- Show notification
function MCL.Notifications:ShowNotification(messageType)
    local message = NOTIFICATION_MESSAGES[messageType]
    if not message then return end
    
    if not self.notificationFrame then
        self.notificationFrame = CreateNotificationFrame()
    end
    
    local frame = self.notificationFrame
    frame.icon:SetTexture(message.icon)
    frame.title:SetText(message.title)
    frame.messageText:SetText(message.text)
    
    -- Adjust frame height based on text
    local textHeight = frame.messageText:GetStringHeight()
    frame:SetHeight(math.max(300, textHeight + 120))
    
    frame:Show()
end

-- Check if we should show a notification
function MCL.Notifications:CheckAndShowNotification()
    -- Initialize settings if they don't exist
    if not MCL_SETTINGS then
        MCL_SETTINGS = {}
    end
    
    if not MCL_SETTINGS.notifications then
        MCL_SETTINGS.notifications = {}
    end
    
    local lastVersion = MCL_SETTINGS.notifications.lastVersion
    local hasSeenWelcome = MCL_SETTINGS.notifications.hasSeenWelcome
    
    -- First time user
    if not hasSeenWelcome then
        C_Timer.After(1, function() -- Delay to let UI load
            self:ShowNotification("welcome")
        end)
        MCL_SETTINGS.notifications.hasSeenWelcome = true
        MCL_SETTINGS.notifications.lastVersion = CURRENT_VERSION
        return
    end
    
    -- Version update
    if lastVersion and lastVersion ~= CURRENT_VERSION then
        C_Timer.After(1, function() -- Delay to let UI load
            self:ShowNotification("update")
        end)
        MCL_SETTINGS.notifications.lastVersion = CURRENT_VERSION
        return
    end
    
    -- Set version if it's missing but user has seen welcome
    if not lastVersion then
        MCL_SETTINGS.notifications.lastVersion = CURRENT_VERSION
    end
end

-- Reset notification status (for testing or admin purposes)
function MCL.Notifications:ResetNotificationStatus()
    if not MCL_SETTINGS then
        MCL_SETTINGS = {}
    end
    
    MCL_SETTINGS.notifications = {
        hasSeenWelcome = false,
        lastVersion = nil
    }
    
    print("|cFF1FB7EBMCL:|r Notification status has been reset. You will see the welcome message next time you open MCL.")
end

-- Force show a specific notification (for testing)
function MCL.Notifications:ForceShowNotification(messageType)
    messageType = messageType or "welcome"
    if NOTIFICATION_MESSAGES[messageType] then
        self:ShowNotification(messageType)
        print("|cFF1FB7EBMCL:|r Showing " .. messageType .. " notification.")
    else
        print("|cFF1FB7EBMCL:|r Invalid notification type. Use 'welcome' or 'update'.")
    end
end

-- Manual trigger for testing the automatic check
function MCL.Notifications:TriggerCheck()
    self:CheckAndShowNotification()
end

-- Initialize the notification system
local function InitializeNotifications()
    -- Simple approach: Monitor the main frame directly
    local function SetupMainFrameHook()
        -- Find the main frame (it might be MCL_mainFrame or MCLFrame)
        local mainFrame = MCLcore and MCLcore.MCL_MF
        if not mainFrame then
            mainFrame = _G["MCLFrame"] or _G["MCL_mainFrame"]
        end
        
        if mainFrame then
            -- Hook the OnShow script
            local originalOnShow = mainFrame:GetScript("OnShow")
            mainFrame:SetScript("OnShow", function(self)
                if originalOnShow then
                    originalOnShow(self)
                end
                -- Check for notifications when main frame shows
                C_Timer.After(0.5, function()
                    MCL.Notifications:CheckAndShowNotification()
                end)
            end)
            return true
        end
        return false
    end
    
    -- Try to set up the hook immediately
    if not SetupMainFrameHook() then
        -- If main frame doesn't exist yet, keep trying
        local attempts = 0
        local function TryAgain()
            attempts = attempts + 1
            if SetupMainFrameHook() then
                return -- Success
            elseif attempts < 10 then -- Try for up to 10 seconds
                C_Timer.After(1, TryAgain)
            end
        end
        TryAgain()
    end
end

-- Event handler for addon loaded
local notificationEventFrame = CreateFrame("Frame")
notificationEventFrame:RegisterEvent("ADDON_LOADED")
notificationEventFrame:SetScript("OnEvent", function(self, event, addonName)
    if event == "ADDON_LOADED" and addonName == "OrzUI" then
        -- Ensure MCL is globally accessible immediately
        _G["MCL"] = MCL
        
        -- Also make it accessible through MCLcore if it exists
        if MCLcore then
            MCLcore.Notifications = MCL.Notifications
        end
        
        -- Initialize after a short delay to ensure all components are loaded
        C_Timer.After(2, function()
            InitializeNotifications()
        end)
    end
end)


-- Ensure the Frames module exists
MCLcore.Frames = MCLcore.Frames or {};
MCLcore.MountCard = {};

local MountCard = MCLcore.MountCard;
local MCL_functions = MCLcore.Functions or {};

-- Constants
local MOUNT_CARD_WIDTH = 400;
local MOUNT_CARD_HEIGHT = 600;

-- Global frame reference
local MCL_MountCard = nil

-- Hover delay system to prevent tooltip flickering when moving between mounts
local hoverTimer = nil
local currentHoveredMount = nil
local currentAnchorFrame = nil

-- MountCollector compatibility interface
MCLcore.MountCard.Display = MCLcore.MountCard.Display or {}

--[[
  Get mount information from WoW API
]]
local function GetMountInfo(mountID)
    if not mountID then
        return nil
    end
    
    -- Handle both item IDs and mount IDs
    local actualMountID = mountID
    if type(mountID) == "string" and string.sub(mountID, 1, 1) == "m" then
        actualMountID = tonumber(string.sub(mountID, 2))
    elseif type(mountID) == "number" and mountID > 100000 then
        -- This might be an item ID, try to get mount from item
        actualMountID = C_MountJournal.GetMountFromItem(mountID)
    end
    
    if not actualMountID then
        return nil
    end
    
    local mountName, spellID, icon, isActive, isUsable, sourceType, isFavorite, 
          isFactionSpecific, faction, shouldHideOnChar, isCollected, mountID_returned = 
          C_MountJournal.GetMountInfoByID(actualMountID)
    
    if not mountName then
        return nil
    end
    
    local creatureDisplayID, description, source, isSelfMount, mountTypeID, uiModelSceneID = 
          C_MountJournal.GetMountInfoExtraByID(actualMountID)
    
    return {
        mountID = actualMountID,
        name = mountName,
        spellID = spellID,
        icon = icon,
        isActive = isActive,
        isUsable = isUsable,
        sourceType = sourceType,
        isFavorite = isFavorite,
        isFactionSpecific = isFactionSpecific,
        faction = faction,
        shouldHideOnChar = shouldHideOnChar,
        isCollected = isCollected,
        creatureDisplayID = creatureDisplayID,
        description = description,
        source = source,
        isSelfMount = isSelfMount,
        mountTypeID = mountTypeID,
        uiModelSceneID = uiModelSceneID
    }
end

--[[
  Get mount source details (vendor, zone, cost, etc.)
]]
local function GetMountSourceDetails(mountInfo, mountData)
    if not mountInfo then
        return {}
    end
    
    local details = {
        vendor = "Unknown",
        zone = "Unknown", 
        cost = "",
        method = "Unknown"
    }
    
    -- Use MCL categorization data first if available
    if mountData and mountData.section and mountData.category then
        local section = mountData.section
        local category = mountData.category
        
        -- Map MCL categories to display information
        if category == "Vendor" or category == "Guild Vendor" or category == "Kun-Lai Vendor" then
            details.method = category
            details.vendor = "Available from " .. category
        elseif category == "Achievement" then
            details.method = "Achievement"
            details.vendor = "Achievement Reward"
        elseif category == "Reputation" or category == "Paragon Reputation" then
            details.method = category
            details.vendor = category .. " Reward"
        elseif category == "Dungeon Drop" then
            details.method = "Dungeon"
            details.vendor = "Dungeon Drop"
        elseif category == "Raid Drop" then
            details.method = "Raid"
            details.vendor = "Raid Drop"
        elseif category == "Rare Spawn" then
            details.method = "Rare Spawn"
            details.vendor = "Rare Mob Drop"
        elseif category == "Treasures" then
            details.method = "Treasure"
            details.vendor = "Treasure Chest"
        elseif category == "Adventures" then
            details.method = "Mission Table"
            details.vendor = "Mission Table Reward"
        elseif category == "Zone" then
            details.method = "Zone Drop"
            details.vendor = "Zone Activity"
        elseif category == "Daily Activities" then
            details.method = "Daily"
            details.vendor = "Daily Activity"
        elseif category == "Tormentors" then
            details.method = "Event"
            details.vendor = "Tormentors of Torghast"
        elseif category == "Maw Assaults" then
            details.method = "Event"
            details.vendor = "Maw Assault"
        elseif category == "Covenant Feature" then
            details.method = "Covenant"
            details.vendor = "Covenant Feature"
        elseif string.find(category, "Night Fae") or string.find(category, "Kyrian") or 
               string.find(category, "Necrolord") or string.find(category, "Venthyr") then
            details.method = "Covenant"
            details.vendor = category .. " Covenant"
        else
            details.method = category
            details.vendor = category
        end
        
        -- Map sections to zones
        if section == "SL" then
            details.zone = "Shadowlands"
        elseif section == "DF" then
            details.zone = "Dragon Isles"
        elseif section == "TWW" then
            details.zone = "Khaz Algar"
        elseif section == "BFA" then
            details.zone = "Kul Tiras / Zandalar"
        elseif section == "Legion" then
            details.zone = "Broken Isles"
        elseif section == "WoD" then
            details.zone = "Draenor"
        elseif section == "Mists" then
            details.zone = "Pandaria"
        elseif section == "Cata" then
            details.zone = "Cataclysm Zones"
        elseif section == "Wrath" then
            details.zone = "Northrend"
        elseif section == "BC" then
            details.zone = "Outland"
        elseif section == "Classic" then
            details.zone = "Eastern Kingdoms / Kalimdor"
        elseif section == "Holiday" then
            details.zone = "Holiday Event"
        elseif section == "Promotion" then
            details.zone = "Promotional"
        elseif section == "Other" then
            details.zone = "Various"
        else
            details.zone = section
        end
    end
    
    -- Parse source information from WoW API as fallback or enhancement
    if mountInfo.source then
        local source = mountInfo.source
        
        -- If we still have unknown vendor, try to parse from source
        if details.vendor == "Unknown" then
            local vendorPatterns = {
                "Sold by ([^,%.]+)",
                "Available from ([^,%.]+)",
                "Purchased from ([^,%.]+)",
                "Vendor: ([^,%.]+)",
                "from ([^,%.]+)"
            }
            
            for _, pattern in ipairs(vendorPatterns) do
                local vendorMatch = string.match(source, pattern)
                if vendorMatch then
                    details.vendor = vendorMatch:gsub("^%s*(.-)%s*$", "%1") -- Trim whitespace
                    details.method = "Vendor"
                    break
                end
            end
        end
        
        -- If we still have unknown zone, try to parse from source
        if details.zone == "Unknown" then
            local zonePatterns = {
                "in ([^,%.]+)",
                "from ([^,%.]+)",
                "at ([^,%.]+)",
                "Zone: ([^,%.]+)"
            }
            
            for _, pattern in ipairs(zonePatterns) do
                local zoneMatch = string.match(source, pattern)
                if zoneMatch and not string.find(zoneMatch:lower(), "vendor") and not string.find(zoneMatch:lower(), "sold") then
                    details.zone = zoneMatch:gsub("^%s*(.-)%s*$", "%1") -- Trim whitespace
                    break
                end
            end
        end
        
        -- Enhanced method detection from source
        if details.method == "Unknown" then
            if string.find(source:lower(), "drop") then
                details.method = "Drop"
            elseif string.find(source:lower(), "achievement") then
                details.method = "Achievement"
            elseif string.find(source:lower(), "reputation") then
                details.method = "Reputation"
            elseif string.find(source:lower(), "quest") then
                details.method = "Quest"
            elseif string.find(source:lower(), "rare") then
                details.method = "Rare Spawn"
            elseif string.find(source:lower(), "treasure") then
                details.method = "Treasure"
            elseif string.find(source:lower(), "dungeon") then
                details.method = "Dungeon"
            elseif string.find(source:lower(), "raid") then
                details.method = "Raid"
            elseif details.vendor ~= "Unknown" then
                details.method = "Vendor"
            end
        end
        
        -- Try to extract cost information
        local costPatterns = {
            "(%d+%s*gold)",
            "(%d+g)",
            "(%d+%s*honor)",
            "(%d+%s*conquest)",
            "(%d+%s*[%w%s]+points?)",
            "Cost: ([^,%.]+)"
        }
        
        for _, pattern in ipairs(costPatterns) do
            local costMatch = string.match(source, pattern)
            if costMatch then
                details.cost = costMatch:gsub("^%s*(.-)%s*$", "%1") -- Trim whitespace
                break
            end
        end
        
        -- Handle texture/icon references in cost (remove them or convert to readable format)
        if details.cost and string.find(details.cost, "Interface\\") then
            -- If cost contains texture path, try to extract meaningful info
            local numericCost = string.match(details.cost, "(%d+)")
            local iconPath = string.match(details.cost, "(Interface\\[^%s]+)")
            
            if numericCost then
                -- Try to determine currency type from icon path
                if iconPath then
                    if string.find(iconPath:lower(), "gold") then
                        details.cost = numericCost .. " Gold"
                    elseif string.find(iconPath:lower(), "honor") then
                        details.cost = numericCost .. " Honor"
                    elseif string.find(iconPath:lower(), "conquest") then
                        details.cost = numericCost .. " Conquest"
                    elseif string.find(iconPath:lower(), "azerite") then
                        details.cost = numericCost .. " Residual Memories"
                    elseif string.find(iconPath:lower(), "currency") then
                        details.cost = numericCost .. " Currency"
                    else
                        -- Generic fallback - just show the number
                        details.cost = numericCost
                    end
                else
                    details.cost = numericCost
                end
            else
                -- If no numeric value found, clear the cost
                details.cost = ""
            end
        end
    end
    
    return details
end

--[[
  Create section header with MCL navigation frame styling (matching PetCard)
]]
local function CreateSectionHeader(parent, text, yOffset, currentOpacity)
    local header = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    header:SetSize(MOUNT_CARD_WIDTH - 40, 25)
    header:SetPoint("TOP", parent, "TOP", 0, yOffset)
    
    -- Use current opacity if provided, otherwise fallback
    local opacity = currentOpacity or (MCL_SETTINGS and MCL_SETTINGS.opacity) or 0.95
    
    -- Use MCL navigation frame styling (matching PetCard)
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        header:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", 
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
            edgeSize = 8,
            insets = {left = 2, right = 2, top = 2, bottom = 2}
        })
        header:SetBackdropColor(0.05, 0.05, 0.2, opacity)
        header:SetBackdropBorderColor(0.6, 0.6, 0.8, 0.8)
    else
        header:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8", 
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
            edgeSize = 4
        })
        header:SetBackdropColor(0.1, 0.1, 0.1, opacity)
        header:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
    end
    
    local headerText = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    headerText:SetPoint("LEFT", header, "LEFT", 8, 0)
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        headerText:SetTextColor(1, 0.82, 0, 1)  -- Gold color like Blizzard UI
    else
        headerText:SetTextColor(0.3, 0.7, 0.9, 1)  -- MCL blue color
    end
    headerText:SetText(text)
    
    return header
end

--[[
  Create the main MountCard frame using MCL styling
]]
function MountCard:CreateMountCard()
    if MCL_MountCard then
        return MCL_MountCard  -- Already exists
    end
    
    -- Get the main addon height
    local addonHeight = (MCL_SETTINGS and MCL_SETTINGS.frameHeight) or main_frame_height or 500
    
    -- Create main frame with MCL styling (matching PetCard)
    local f = CreateFrame("Frame", "MCL_MountCard", UIParent, "BackdropTemplate")
    f:SetSize(MOUNT_CARD_WIDTH, addonHeight)  -- Match main window height
    f:SetFrameStrata("HIGH")
    f:SetFrameLevel(100)
    f:SetMovable(false)  -- Disable moving since it's anchored
    f:EnableMouse(true)
    f:SetClampedToScreen(true)
    f:Hide()  -- Start hidden
    
    -- Apply MCL theming (matching PetCard style)
    local currentOpacity = (MCL_SETTINGS and MCL_SETTINGS.opacity) or 0.95
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        f:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", 
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
            edgeSize = 16,
            insets = {left = 4, right = 4, top = 4, bottom = 4}
        })
        f:SetBackdropColor(0.05, 0.05, 0.15, currentOpacity)
        f:SetBackdropBorderColor(0.4, 0.4, 0.6, 1)
    else
        f:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8", 
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
            edgeSize = 8
        })
        f:SetBackdropColor(0.08, 0.08, 0.08, currentOpacity)
        f:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
    end
    
    -- Title bar with mount icon and name (no "Mount Information" title)
    f.titleFrame = CreateFrame("Frame", nil, f)
    f.titleFrame:SetSize(MOUNT_CARD_WIDTH - 20, 30)
    f.titleFrame:SetPoint("TOP", f, "TOP", 0, -10)
    f.titleFrame:EnableMouse(false)  -- Disable dragging since frame is anchored
    
    -- Mount icon in title bar
    f.mountIcon = f.titleFrame:CreateTexture(nil, "ARTWORK")
    f.mountIcon:SetSize(24, 24)
    f.mountIcon:SetPoint("LEFT", f.titleFrame, "LEFT", 10, 0)
    
    -- Mount name in title bar
    f.mountName = f.titleFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.mountName:SetPoint("LEFT", f.mountIcon, "RIGHT", 8, 0)
    if MCL_SETTINGS and MCL_SETTINGS.useBlizzardTheme then
        f.mountName:SetTextColor(1, 0.82, 0, 1)
    else
        f.mountName:SetTextColor(0.3, 0.7, 0.9, 1)
    end
    
    -- Header frame for additional mount info (below title)
    f.headerFrame = CreateFrame("Frame", nil, f)
    f.headerFrame:SetSize(MOUNT_CARD_WIDTH - 20, 1)
    f.headerFrame:SetPoint("TOP", f.titleFrame, "BOTTOM", 0, -5)
    f.headerFrame:EnableMouse(false)
    
    -- Scroll frame for content (positioned below header frame)
    f.scrollFrame = CreateFrame("ScrollFrame", nil, f)
    f.scrollFrame:SetPoint("TOPLEFT", f.headerFrame, "BOTTOMLEFT", 0, -10)
    f.scrollFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -10, 10)
    
    -- Scroll child
    f.scrollChild = CreateFrame("Frame", nil, f.scrollFrame)
    f.scrollChild:SetSize(MOUNT_CARD_WIDTH - 20, addonHeight - 80)
    f.scrollFrame:SetScrollChild(f.scrollChild)
    
    -- Initialize properties
    f.isPinned = false
    f.currentMountID = nil
    f.currentAnchorFrame = nil
    
    -- Add hover detection to keep the card open when hovering over it
    f:SetScript("OnEnter", function(self)
        -- Cancel any pending hide timer when hovering over the card
        if hoverTimer then
            hoverTimer:Cancel()
            hoverTimer = nil
        end
    end)
    
    -- Hook into main MCL window hide event to close mount card
    -- Use a safer approach to avoid potential infinite loops
    local function setupMainFrameHook()
        if MCL_mainFrame and not MCL_mainFrame.mountCardHooked then
            local originalHide = MCL_mainFrame:GetScript("OnHide")
            MCL_mainFrame:SetScript("OnHide", function(self)
                -- Hide mount card when main window closes
                if MCL_MountCard and MCL_MountCard:IsVisible() then
                    MCL_MountCard:Hide()
                end
                -- Call original hide handler if it exists
                if originalHide then
                    originalHide(self)
                end
            end)
            MCL_mainFrame.mountCardHooked = true
            return true
        end
        return false
    end
    
    -- Try to set up the hook immediately
    if not setupMainFrameHook() then
        -- If main frame doesn't exist yet, set up a one-time event listener
        local eventFrame = CreateFrame("Frame")
        eventFrame:RegisterEvent("ADDON_LOADED")
        eventFrame:RegisterEvent("PLAYER_LOGIN")
        eventFrame:SetScript("OnEvent", function(self, event, addonName)
            if (event == "ADDON_LOADED" and addonName == "OrzUI") or 
               event == "PLAYER_LOGIN" or MCL_mainFrame then
                if setupMainFrameHook() then
                    self:UnregisterEvent("ADDON_LOADED")
                    self:UnregisterEvent("PLAYER_LOGIN")
                    self:SetScript("OnEvent", nil)
                end
            end
        end)
    end
    
    -- Also set up the hook whenever we show the mount card, as a backup
    f.ensureHook = setupMainFrameHook
    
    -- Store global reference
    MCL_MountCard = f
    return f
end

--[[
  Create mount card content
]]
function MountCard:CreateMountCardContent(parentFrame, mountData)
    if not parentFrame or not mountData then
        return
    end
    
    -- Clear existing content more thoroughly
    -- First clear all child frames
    local children = {parentFrame:GetChildren()}
    for _, child in ipairs(children) do
        child:Hide()
        child:ClearAllPoints()
        child:SetParent(nil)
    end
    
    -- Clear all regions (FontStrings, Textures, etc.)
    local regions = {parentFrame:GetRegions()}
    for _, region in ipairs(regions) do
        region:Hide()
        region:ClearAllPoints()
        region:SetParent(nil)
    end
    
    -- Also clear the title frame content to prevent overlapping
    local card = MCL_MountCard
    if card and card.titleFrame then
        -- Clear previous title frame content completely
        local titleChildren = {card.titleFrame:GetChildren()}
        for _, child in ipairs(titleChildren) do
            if child ~= card.mountIcon and child ~= card.mountName then
                child:Hide()
                child:SetParent(nil)
            end
        end
        
        local titleRegions = {card.titleFrame:GetRegions()}
        for _, region in ipairs(titleRegions) do
            if region ~= card.mountIcon and region ~= card.mountName then
                region:Hide()
                region:SetParent(nil)
            end
        end
    end
    
    -- Get mount data from WoW API
    local mountInfo = GetMountInfo(mountData.mountID or mountData.id)
    if not mountInfo then
        -- Show error message
        local errorText = parentFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        errorText:SetPoint("CENTER", parentFrame, "CENTER", 0, 0)
        errorText:SetText("Mount information not available")
        errorText:SetTextColor(1, 0.5, 0.5, 1)
        --print("MCL Debug: No mountInfo found for ID:", mountData.mountID or mountData.id)
        return
    end
    
    -- Get source details
    local sourceDetails = GetMountSourceDetails(mountInfo, mountData)
    
    -- Set mount icon and name in the title bar
    local card = MCL_MountCard
    if card and card.titleFrame then
        -- Clear previous title frame content
        if card.mountIcon then
            card.mountIcon:SetTexture(nil)
        end
        if card.mountName then
            card.mountName:SetText("")
        end
        
        -- Set new mount icon in title bar
        if card.mountIcon then
            if mountInfo.icon then
                card.mountIcon:SetTexture(mountInfo.icon)
            end
        end
        
        -- Set new mount name in title bar
        if card.mountName then
            card.mountName:SetText(mountInfo.name or "Unknown Mount")
        end
    end
    
    local yOffset = 0   -- Start right underneath the title area (was -5)
    local contentHeight = 10  -- Reduced from 20
    local contentWidth = parentFrame:GetWidth() - 20 -- Reduced padding from 60 to 20
    
    -- Description section (no header, just content)
    if mountInfo.description and mountInfo.description ~= "" then
        local descriptionText = parentFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        descriptionText:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 10, yOffset)  -- Reduced left margin from 30 to 10
        descriptionText:SetPoint("TOPRIGHT", parentFrame, "TOPRIGHT", -10, yOffset)  -- Reduced right margin from -30 to -10
        descriptionText:SetText(mountInfo.description)
        -- set descriptionText to a soft yellow
        descriptionText:SetTextColor(0.9, 0.9, 0.2, 1)
        descriptionText:SetJustifyH("LEFT")
        descriptionText:SetWordWrap(true)
        
        -- Make description italic
        local fontFile, fontSize, fontFlags = descriptionText:GetFont()
        descriptionText:SetFont(fontFile, fontSize, "ITALIC")
        
        local textHeight = descriptionText:GetStringHeight()
        yOffset = yOffset - (textHeight + 10)  -- Further reduced spacing from 15 to 10
        contentHeight = contentHeight + (textHeight + 10)
    end
    
    -- Source details section (aligned left with description)
    local mainContentFrame = CreateFrame("Frame", nil, parentFrame)
    mainContentFrame:SetSize(contentWidth, 80)
    mainContentFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 10, yOffset)  -- Aligned with description at x=10
    
    -- Mount details frame (aligned with description)
    local detailsFrame = CreateFrame("Frame", nil, mainContentFrame)
    detailsFrame:SetPoint("TOPLEFT", mainContentFrame, "TOPLEFT", 0, 0)  -- Removed extra indentation
    detailsFrame:SetPoint("BOTTOMRIGHT", mainContentFrame, "BOTTOMRIGHT", 0, 10)  -- Removed extra indentation
    
    local detailsYOffset = -5
    
    -- Determine appropriate labels based on mount source/method
    local sourceLabel, expansionLabel, requirementLabel = "Source:", "Expansion:", "Requirement:"
    
    if sourceDetails.method == "Reputation" or sourceDetails.method == "Paragon Reputation" then
        requirementLabel = "Other:"
    elseif sourceDetails.method == "Vendor" or sourceDetails.method == "Guild Vendor" then
        requirementLabel = "Cost:"
    elseif sourceDetails.method == "Achievement" then
        requirementLabel = "Progress:"
    elseif sourceDetails.method == "Dungeon" then
        requirementLabel = "Drop Rate:"
    elseif sourceDetails.method == "Raid" then
        requirementLabel = "Drop Rate:"
    elseif sourceDetails.method == "Rare Spawn" then
        requirementLabel = "Drop Rate:"
    elseif sourceDetails.method == "Treasure" then
        requirementLabel = "Location:"
    elseif sourceDetails.method == "Quest" then
        requirementLabel = "Completion:"
    elseif sourceDetails.method == "Covenant" then
        requirementLabel = "Requirement:"
    elseif sourceDetails.method == "Event" then
        requirementLabel = "Requirement:"
    end
    
    -- Source/Faction/Achievement etc.
    local sourceDisplayLabel = detailsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    sourceDisplayLabel:SetPoint("TOPLEFT", detailsFrame, "TOPLEFT", 0, detailsYOffset)
    sourceDisplayLabel:SetText(sourceLabel)
    sourceDisplayLabel:SetTextColor(0.8, 0.8, 0.8, 1)
    
    local sourceText = detailsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    sourceText:SetPoint("TOPLEFT", sourceDisplayLabel, "TOPRIGHT", 5, 0)
    sourceText:SetPoint("TOPRIGHT", detailsFrame, "TOPRIGHT", 0, detailsYOffset)
    sourceText:SetText(sourceDetails.vendor)
    sourceText:SetTextColor(1, 0.9, 0.7, 1)
    sourceText:SetJustifyH("LEFT")
    sourceText:SetWordWrap(true)
    
    detailsYOffset = detailsYOffset - 18
    
    -- Expansion
    local expansionDisplayLabel = detailsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    expansionDisplayLabel:SetPoint("TOPLEFT", detailsFrame, "TOPLEFT", 0, detailsYOffset)
    expansionDisplayLabel:SetText(expansionLabel)
    expansionDisplayLabel:SetTextColor(0.8, 0.8, 0.8, 1)
    
    local expansionText = detailsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    expansionText:SetPoint("TOPLEFT", expansionDisplayLabel, "TOPRIGHT", 5, 0)
    expansionText:SetPoint("TOPRIGHT", detailsFrame, "TOPRIGHT", 0, detailsYOffset)
    expansionText:SetText(sourceDetails.zone)
    expansionText:SetTextColor(0.7, 0.9, 0.7, 1)
    expansionText:SetJustifyH("LEFT")
    expansionText:SetWordWrap(true)
    
    detailsYOffset = detailsYOffset - 18
    
    -- Requirement/Cost/Level etc. (if available)
    if sourceDetails.cost and sourceDetails.cost ~= "" then
        local requirementDisplayLabel = detailsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        requirementDisplayLabel:SetPoint("TOPLEFT", detailsFrame, "TOPLEFT", 0, detailsYOffset)
        requirementDisplayLabel:SetText(requirementLabel)
        requirementDisplayLabel:SetTextColor(0.8, 0.8, 0.8, 1)
        
        -- Parse cost string for icon and text
        local costText = sourceDetails.cost
        local iconPath = nil
        local iconID = nil
        
        -- Check if cost contains | separator for icon data or texture markup
        if string.find(costText, "|T") then
            -- Handle WoW texture format: |TTexture:size:size:xOffset:yOffset|t
            iconPath = string.match(costText, "|T([^:]+)")
            -- Remove the entire texture markup from the text
            costText = string.gsub(costText, "|T.-|t", "")
        elseif string.find(costText, "|") then
            local parts = {strsplit("|", costText)}
            local textParts = {}
            
            for i, part in ipairs(parts) do
                -- Look for texture paths or icon IDs
                if string.find(part, "Interface\\") or string.find(part, "INTERFACE\\") then
                    iconPath = part
                elseif tonumber(part) and tonumber(part) > 0 then
                    -- Numeric icon ID
                    iconID = tonumber(part)
                else
                    -- This is likely the text part - but double check it's not an interface path
                    if part and part ~= "" and 
                       not string.find(string.upper(part), "INTERFACE\\") and 
                       not string.find(string.upper(part), "INTERFACE/") then
                        table.insert(textParts, part)
                    end
                end
            end
            
            -- Join the text parts together
            if #textParts > 0 then
                costText = table.concat(textParts, " ")
            else
                costText = ""
            end
        end
        
        -- Additional cleanup - remove any remaining interface paths that might have slipped through
        costText = string.gsub(costText, "%s*[Ii][Nn][Tt][Ee][Rr][Ff][Aa][Cc][Ee]\\[^%s]*", "")
        costText = string.gsub(costText, "%s*[Ii][Nn][Tt][Ee][Rr][Ff][Aa][Cc][Ee]/[^%s]*", "")
        
        -- Remove any remaining |T markup (with or without closing |t)
        costText = string.gsub(costText, "|T[^|]*", "")
        costText = string.gsub(costText, "|t", "")
        
        -- Clean up the cost text (remove any remaining markup)
        costText = string.gsub(costText, "|c.-|r", function(s) return string.gsub(s, "|c%x%x%x%x%x%x%x%x(.-)|r", "%1") end)
        costText = strtrim(costText or "")
        
        -- Create a frame to hold both icon and text
        local costFrame = CreateFrame("Frame", nil, detailsFrame)
        costFrame:SetPoint("TOPLEFT", requirementDisplayLabel, "TOPRIGHT", 5, 0)
        costFrame:SetPoint("TOPRIGHT", detailsFrame, "TOPRIGHT", 0, detailsYOffset)
        costFrame:SetHeight(16)
        
        local xOffset = 0
        
        -- Add icon if we found one
        if iconPath or iconID then
            local costIcon = costFrame:CreateTexture(nil, "ARTWORK")
            costIcon:SetSize(16, 16)
            costIcon:SetPoint("LEFT", costFrame, "LEFT", xOffset, 0)
            
            if iconID then
                costIcon:SetTexture(iconID)
            elseif iconPath then
                costIcon:SetTexture(iconPath)
            end
            
            xOffset = xOffset + 20  -- Make room for the icon
        end
        
        -- Add the cost text
        local requirementText = costFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        requirementText:SetPoint("LEFT", costFrame, "LEFT", xOffset, 0)
        requirementText:SetPoint("RIGHT", costFrame, "RIGHT", 0, 0)
        requirementText:SetText(costText)
        requirementText:SetTextColor(0.9, 0.7, 0.9, 1)
        requirementText:SetJustifyH("LEFT")
        requirementText:SetWordWrap(true)
        
        detailsYOffset = detailsYOffset - 18
    end
    
    yOffset = yOffset - 80
    contentHeight = contentHeight + 80
    
    -- Mount Model Section (no header, small spacing, no backdrop)
    yOffset = yOffset - 5  -- Reduced gap from 10 to 5
    contentHeight = contentHeight + 5
    
    -- Use fixed height for model frame
    local modelHeight = 450 -- Fixed height instead of dynamic calculation
    
    local modelFrame = CreateFrame("Frame", nil, parentFrame)
    modelFrame:SetSize(parentFrame:GetWidth() - 20, modelHeight) -- Use full width minus small padding
    modelFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 10, yOffset)  -- Aligned with description
    
    -- Create model display using PlayerModel frame (no backdrop)
    local mountModel = CreateFrame("PlayerModel", nil, modelFrame)
    -- Use the full frame size to prevent clipping
    mountModel:SetSize(modelFrame:GetWidth(), modelFrame:GetHeight())
    mountModel:SetPoint("CENTER", modelFrame, "CENTER", 0, 0)
    
    -- Try to display the mount model
    if mountInfo.creatureDisplayID and mountInfo.creatureDisplayID > 0 then
        -- Clear any existing model first to prevent caching issues
        mountModel:ClearModel()
        mountModel:SetDisplayInfo(0)
        
        -- Small delay to ensure clearing takes effect, then set the new model
        C_Timer.After(0.1, function()
            mountModel:SetDisplayInfo(mountInfo.creatureDisplayID)
            
            -- Force a refresh first to ensure the model is properly initialized
            mountModel:RefreshCamera()
                        
            -- Use camera setting 2 for better mount viewing angle
            mountModel:SetCamera(2)
            
            -- Set consistent model size regardless of original model size
            -- This ensures all mounts appear at the same absolute size
            mountModel:SetSize(300, 300)  -- Fixed 300x300 size for all mounts
            
            -- Position the model for better viewing distance
            mountModel:SetPosition(0, 0, 0)
            
            -- Set initial facing (front-facing like dressing room)
            mountModel:SetFacing(0)

            -- Force a refresh first to ensure the model is properly initialized
            mountModel:RefreshCamera()
        end)
        
        -- Variables for drag rotation
        local isDragging = false
        local lastCursorX = 0
        
        -- Add model controls with proper click-and-drag
        mountModel:EnableMouse(true)
        mountModel:SetScript("OnMouseDown", function(self, button)
            if button == "LeftButton" then
                isDragging = true
                lastCursorX = select(1, GetCursorPosition())
                self:SetScript("OnUpdate", function(self)
                    if isDragging then
                        local currentX = select(1, GetCursorPosition())
                        local deltaX = currentX - lastCursorX
                        local sensitivity = 0.01 -- Adjust for rotation speed
                        
                        -- Rotate based on horizontal mouse movement
                        local currentFacing = self:GetFacing()
                        self:SetFacing(currentFacing + (deltaX * sensitivity))
                        
                        lastCursorX = currentX
                    end
                end)
            end
        end)
        
        mountModel:SetScript("OnMouseUp", function(self, button)
            if button == "LeftButton" then
                isDragging = false
                self:SetScript("OnUpdate", nil)
            end
        end)
        
        -- Also handle mouse leaving the frame
        mountModel:SetScript("OnLeave", function(self)
            isDragging = false
            self:SetScript("OnUpdate", nil)
        end)
        
        -- Model controls text
        local modelControlsText = modelFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        modelControlsText:SetPoint("BOTTOM", mountModel, "BOTTOM", 0, -25)
        modelControlsText:SetText("Left-click and drag to rotate")
        modelControlsText:SetTextColor(0.7, 0.7, 0.7, 1)
    else
        -- Fallback: show large mount icon if no model available
        local largeIconFrame = CreateFrame("Frame", nil, modelFrame)
        largeIconFrame:SetSize(128, 128)
        largeIconFrame:SetPoint("CENTER", modelFrame, "CENTER", 0, 0)
        
        local largeIcon = largeIconFrame:CreateTexture(nil, "ARTWORK")
        largeIcon:SetPoint("CENTER", largeIconFrame, "CENTER", 0, 0)
        largeIcon:SetSize(120, 120)
        largeIcon:SetTexture(mountInfo.icon)
        
        -- No model available text
        local noModelText = modelFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        noModelText:SetPoint("BOTTOM", largeIconFrame, "BOTTOM", 0, -15)
        noModelText:SetText("3D Model not available")
        noModelText:SetTextColor(0.7, 0.7, 0.7, 1)
    end
    
    yOffset = yOffset - modelHeight
    contentHeight = contentHeight + modelHeight
    
    -- Set the parent frame height to fit all content
    parentFrame:SetHeight(contentHeight + 40)
end

--[[
  Show mount card for a specific mount
]]
function MountCard:ShowMountCard(mountData, anchorFrame)
    if not mountData then
        return
    end
    
    local card = self:CreateMountCard()
    if not card then
        return
    end
    
    -- Store current mount and anchor
    card.currentMountID = mountData.mountID or mountData.id
    card.currentAnchorFrame = anchorFrame
    
    -- Position the card relative to main MCL window
    card:ClearAllPoints()
    if MCL_mainFrame and MCL_mainFrame:IsVisible() then
        -- Attach to the right of the main MCL window
        card:SetPoint("TOPLEFT", MCL_mainFrame, "TOPRIGHT", 10, 0)
    elseif anchorFrame then
        -- Fallback to anchor frame if main window not available
        card:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 10, 0)
    else
        -- Final fallback to center of screen
        card:SetPoint("CENTER", UIParent, "CENTER", 200, 0)
    end
    
    -- Create content
    self:CreateMountCardContent(card.scrollChild, mountData)
    
    -- Ensure the main frame hook is established (backup safety check)
    if card.ensureHook then
        card.ensureHook()
    end
    
    -- Show the card
    card:Show()
    
    return card
end

--[[
  Hide mount card
]]
function MountCard:HideMountCard()
    if MCL_MountCard then
        MCL_MountCard:Hide()
    end
end

--[[
  Check if mount card is visible
]]
function MountCard:IsMountCardVisible()
    return MCL_MountCard and MCL_MountCard:IsVisible()
end

--[[
  Show mount card on hover with delay
]]
function MountCard:ShowMountCardOnHover(mountData, anchorFrame, delay)
    -- Cancel any existing hover timer
    if hoverTimer then
        hoverTimer:Cancel()
        hoverTimer = nil
    end
    
    -- Store the current hovered mount
    currentHoveredMount = mountData
    currentAnchorFrame = anchorFrame
    
    -- Set up a delay before showing to prevent flickering
    local showDelay = delay or 0.2  -- Reduced from 0.5 to 0.2 seconds for faster response
    
    -- If delay is 0 or very small, show immediately
    if showDelay <= 0.05 then
        self:ShowMountCard(mountData, anchorFrame)
        return
    end
    
    hoverTimer = C_Timer.NewTimer(showDelay, function()
        -- Only show if we're still hovering the same mount
        if currentHoveredMount and currentHoveredMount.mountID == mountData.mountID then
            self:ShowMountCard(mountData, anchorFrame)
        end
        hoverTimer = nil
    end)
end

--[[
  Show mount card instantly (no delay)
]]
function MountCard:ShowMountCardInstant(mountData, anchorFrame)
    return self:ShowMountCardOnHover(mountData, anchorFrame, 0)
end

--[[
  Hide mount card on hover end
]]
function MountCard:HideMountCardOnHover()
    -- Cancel any pending hover timer
    if hoverTimer then
        hoverTimer:Cancel()
        hoverTimer = nil
    end
    
    -- Clear current hovered mount
    currentHoveredMount = nil
    currentAnchorFrame = nil
    
    -- Hide the card
    self:HideMountCard()
end

--[[
  Toggle mount card visibility
]]
function MountCard:ToggleMountCard(mountData, anchorFrame)
    if self:IsMountCardVisible() and MCL_MountCard.currentMountID == (mountData.mountID or mountData.id) then
        self:HideMountCard()
    else
        self:ShowMountCard(mountData, anchorFrame)
    end
end

-- Compatibility functions for external access
MCLcore.MountCard.Show = function(mountData, anchorFrame)
    return MountCard:ShowMountCard(mountData, anchorFrame)
end

MCLcore.MountCard.Hide = function()
    return MountCard:HideMountCard()
end

MCLcore.MountCard.Toggle = function(mountData, anchorFrame)
    return MountCard:ToggleMountCard(mountData, anchorFrame)
end

MCLcore.MountCard.ShowOnHover = function(mountData, anchorFrame, delay)
    return MountCard:ShowMountCardOnHover(mountData, anchorFrame, delay)
end

MCLcore.MountCard.ShowInstant = function(mountData, anchorFrame)
    return MountCard:ShowMountCardInstant(mountData, anchorFrame)
end

MCLcore.MountCard.HideOnHover = function()
    return MountCard:HideMountCardOnHover()
end

MCLcore.MountCard.IsVisible = function()
    return MountCard:IsMountCardVisible()
end

-- Test slash command for debugging
SLASH_MCLMOUNTCARD1 = "/mclmount"
SlashCmdList["MCLMOUNTCARD"] = function(msg)
    local mountID = tonumber(msg) or 280 -- Default to Stormwind Steed (similar to your screenshot)
    local testData = {
        mountID = mountID,
        id = mountID,
        name = "Test Mount"
    }
    MCLcore.MountCard.Show(testData)
    print("MCL: Showing mount card for mount ID:", mountID)
end

-- Test slash command to show specific mount like Stormwind Steed
SLASH_MCLSTORMWIND1 = "/mclstormwind"
SlashCmdList["MCLSTORMWIND"] = function(msg)
    local testData = {
        mountID = 280, -- Stormwind Steed mount ID
        id = 280,
        name = "Stormwind Steed"
    }
    MCLcore.MountCard.Show(testData)
    print("MCL: Showing Stormwind Steed mount card")
end

-- Test instant show command
SLASH_MCLINSTANT1 = "/mclinstant"
SlashCmdList["MCLINSTANT"] = function(msg)
    local mountID = tonumber(msg) or 280
    local testData = {
        mountID = mountID,
        id = mountID,
        name = "Instant Test Mount"
    }
    MCLcore.MountCard.ShowInstant(testData)
    print("MCL: Showing mount card instantly for mount ID:", mountID)
end

-- Test slash command with full MCL categorization data
SLASH_MCLVENDORTEST1 = "/mclvendor"
SlashCmdList["MCLVENDORTEST"] = function(msg)
    local testData = {
        mountID = 280, -- Stormwind Steed mount ID
        id = 280,
        name = "Stormwind Steed",
        section = "Classic",
        category = "Vendor"
    }
    MCLcore.MountCard.Show(testData)
    print("MCL: Showing vendor test mount card with categorization")
end

-- Test slash command for different categories
SLASH_MCLRAIDTEST1 = "/mclraid"
SlashCmdList["MCLRAIDTEST"] = function(msg)
    local testData = {
        mountID = 213209, -- Example raid mount
        id = 213209,
        name = "Raid Mount Test",
        section = "TWW",
        category = "Raid Drop"
    }
    MCLcore.MountCard.Show(testData)
    print("MCL: Showing raid test mount card")
end


local PCL, PCLcore = ...;

-- Ensure the Frames module exists
PCLcore.Frames = PCLcore.Frames or {};
PCLcore.PetCard = {};

local PetCard = PCLcore.PetCard;
local PCL_functions = PCLcore.Functions or {};

-- Constants
local PET_CARD_WIDTH = 400;  -- Increased from 350 to 380 for better space utilization
local PET_CARD_HEIGHT = 600; -- Keep height for content display

-- Global frame reference
local PAPetCard = nil

-- Pet type mappings for display
local PET_TYPE_SUFFIX = {
    [1] = "Humanoid", [2] = "Dragonkin", [3] = "Flying", [4] = "Undead", [5] = "Critter",
    [6] = "Magic", [7] = "Elemental", [8] = "Beast", [9] = "Aquatic", [10] = "Mechanical"
}

-- Hover delay system to prevent tooltip flickering when moving between pets
local hoverTimer = nil
local currentHoveredPet = nil
local currentAnchorFrame = nil

-- PetCollector compatibility interface
PCLcore.PetCard.Display = PCLcore.PetCard.Display or {}

--[[
  Family Details - Returns family name, icon key, and RGB colors
]]
local function getFamilyDetails(family)
    if family == 1 then
        return "Humanoid", "humanoid", 8 / 256, 138 / 256, 222 / 256
    elseif family == 2 then
        return "Dragonkin", "dragon", 34 / 256, 165 / 256, 24 / 256
    elseif family == 3 then
        return "Flying", "flying", 214 / 256, 199 / 256, 74 / 256
    elseif family == 4 then
        return "Undead", "undead", 164 / 256, 109 / 256, 115 / 256
    elseif family == 5 then
        return "Critter", "critter", 140 / 256, 101 / 256, 74 / 256
    elseif family == 6 then
        return "Magical", "magical", 156 / 256, 105 / 256, 255 / 256
    elseif family == 7 then
        return "Elemental", "elemental", 247 / 256, 105 / 256, 0 / 256
    elseif family == 8 then
        return "Beast", "beast", 193 / 256, 36 / 256, 33 / 256
    elseif family == 9 then
        return "Aquatic", "water", 8 / 256, 170 / 256, 181 / 256
    elseif family == 10 then
        return "Mechanical", "mechanical", 132 / 256, 125 / 256, 115 / 256
    end
    return "Unknown", "beast", 1, 1, 1
end

--[[
  Detect breed ID from pet stats (simplified version)
]]
local function DetectPetBreed(speciesID, health, power, speed, level, rarity)
    -- Quality multipliers (exact values from BattlePetBreedID)
    local qualityMultipliers = {
        [1] = 0.5, [2] = 0.550000011920929, [3] = 0.600000023841858, 
        [4] = 0.649999976158142, [5] = 0.699999988079071, [6] = 0.75
    }
    
    -- Breed stats modifiers (exact values from BattlePetBreedID)
    local breedStatsModifiers = {
        [3] = {0.5, 0.5, 0.5},   -- B/B
        [4] = {0, 2, 0},         -- P/P
        [5] = {0, 0, 2},         -- S/S
        [6] = {2, 0, 0},         -- H/H
        [7] = {0.9, 0.9, 0},     -- H/P
        [8] = {0, 0.9, 0.9},     -- P/S
        [9] = {0.9, 0, 0.9},     -- H/S
        [10] = {0.4, 0.9, 0.4},  -- P/B
        [11] = {0.4, 0.4, 0.9},  -- S/B
        [12] = {0.9, 0.4, 0.4}   -- H/B
    }
    
    -- Local function to get breed letters from breed ID
    local function GetBreedLetters(breedID)
        local breedLetters = {
            [3] = "B/B",   -- Balanced
            [4] = "P/P",   -- Power
            [5] = "S/S",   -- Speed
            [6] = "H/H",   -- Health
            [7] = "H/P",   -- Health/Power
            [8] = "P/S",   -- Power/Speed
            [9] = "H/S",   -- Health/Speed
            [10] = "P/B",  -- Power/Balanced
            [11] = "S/B",  -- Speed/Balanced
            [12] = "H/B"   -- Health/Balanced
        }
        return breedLetters[breedID] or "?/?"
    end
    
    -- If we don't have complete stats, return first available breed
    if not health or not power or not speed or not level or not rarity then
        if PCLcore.breedData and PCLcore.breedData.species and PCLcore.breedData.species[speciesID] then
            local availableBreeds = PCLcore.breedData.species[speciesID].breeds
            if availableBreeds and #availableBreeds > 0 then
                local firstBreed = availableBreeds[1]
                return firstBreed, GetBreedLetters(firstBreed)
            end
        end
        return 3, "B/B"  -- Fallback only if no breed data
    end
    
    -- Get available breeds for this species
    if not PCLcore.breedData or not PCLcore.breedData.species or not PCLcore.breedData.species[speciesID] then
        return 3, "B/B"  -- Default if no breed data
    end
    
    local availableBreeds = PCLcore.breedData.species[speciesID].breeds
    if not availableBreeds or #availableBreeds == 0 then
        return 3, "B/B"
    end
    
    -- Get base stats for this species (rough estimation)
    local baseHealth, basePower, baseSpeed = 10, 8, 9  -- Default fallback
    
    -- Try to reverse-engineer base stats from the pet's actual stats
    -- This is a simplified approach - for a more accurate one, we'd need the full BattlePetBreedID algorithm
    local qualityMult = qualityMultipliers[rarity] or qualityMultipliers[3]
    local nQL = qualityMult * 2 * level
    
    -- For level 25 rare pets, try to match against expected breed patterns
    if level == 25 and rarity == 3 then
        -- Test each available breed to see which one matches closest
        local bestBreed = availableBreeds[1]  -- Default to first available breed
        local bestLetters = GetBreedLetters(bestBreed)
        local smallestDiff = math.huge
        
        for _, breedID in ipairs(availableBreeds) do
            local breedMods = breedStatsModifiers[breedID]
            if breedMods then
                -- Calculate expected stats for this breed
                local expectedHealth = math.floor(((baseHealth + breedMods[1]) * nQL * 5 + 100) + 0.5)
                local expectedPower = math.floor(((basePower + breedMods[2]) * nQL) + 0.5)
                local expectedSpeed = math.floor(((baseSpeed + breedMods[3]) * nQL) + 0.5)
                
                -- Calculate difference from actual stats
                local diff = math.abs(health - expectedHealth) + math.abs(power - expectedPower) + math.abs(speed - expectedSpeed)
                
                if diff < smallestDiff then
                    smallestDiff = diff
                    bestBreed = breedID
                    bestLetters = GetBreedLetters(breedID)
                end
            end
        end
        
        return bestBreed, bestLetters
    end
    
    -- For other cases, use scoring system to find best match among available breeds
    local totalStats = health + power + speed
    local healthRatio = health / totalStats
    local powerRatio = power / totalStats
    local speedRatio = speed / totalStats
    
    -- Look for stat distribution patterns in available breeds only
    local bestMatch = availableBreeds[1]  -- Default to first available
    local bestLetters = GetBreedLetters(bestMatch)
    local bestScore = 0
    
    for _, breedID in ipairs(availableBreeds) do
        local letters = GetBreedLetters(breedID)
        local score = 0
        
        -- Calculate match score based on stat emphasis
        if letters == "P/P" and powerRatio > 0.4 then
            score = powerRatio * 100
        elseif letters == "S/S" and speedRatio > 0.4 then
            score = speedRatio * 100
        elseif letters == "H/H" and healthRatio > 0.5 then
            score = healthRatio * 100
        elseif letters == "H/P" and healthRatio > 0.35 and powerRatio > 0.3 then
            score = (healthRatio + powerRatio) * 50
        elseif letters == "P/S" and powerRatio > 0.3 and speedRatio > 0.3 then
            score = (powerRatio + speedRatio) * 50
        elseif letters == "H/S" and healthRatio > 0.35 and speedRatio > 0.3 then
            score = (healthRatio + speedRatio) * 50
        elseif letters == "P/B" then
            score = powerRatio * 60  -- Medium power bias
        elseif letters == "S/B" then
            score = speedRatio * 60  -- Medium speed bias
        elseif letters == "H/B" then
            score = healthRatio * 60  -- Medium health bias
        elseif letters == "B/B" then
            score = 30  -- Balanced gets moderate score
        end
        
        if score > bestScore then
            bestScore = score
            bestMatch = breedID
            bestLetters = letters
        end
    end
    
    return bestMatch, bestLetters
end

--[[
  Update ability display with proper tooltip
]]
local function UpdateAbility(texture, abilityID, petType)
    if not abilityID then
        texture:Hide()
        return
    end
    
    local _, icon = C_PetJournal.GetPetAbilityInfo(abilityID)
    if icon then
        texture:Show()
        texture:SetTexture(icon)
        
        texture:SetScript("OnEnter", function(self)
            -- Try to use the proper WoW pet battle tooltip first
            if SharedPetBattleAbilityTooltip_SetAbility and PetBattlePrimaryAbilityTooltip then
                local abilityInfo = C_PetJournal.GetPetAbilityInfo(abilityID)
                if abilityInfo then
                    local success = pcall(function()
                        PetBattlePrimaryAbilityTooltip:SetOwner(self, "ANCHOR_RIGHT")
                        SharedPetBattleAbilityTooltip_SetAbility(PetBattlePrimaryAbilityTooltip, abilityInfo)
                        PetBattlePrimaryAbilityTooltip:Show()
                    end)
                    if success then
                        return
                    end
                end
            end
            
            -- Fallback to custom tooltip
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            local name, icon, petType, noStrongWeakHints = C_PetJournal.GetPetAbilityInfo(abilityID)
            if name then
                GameTooltip:SetText(name, 1, 1, 1, 1, true)
                if petType then
                    local familyName = getFamilyDetails(petType)
                    GameTooltip:AddLine("Type: " .. familyName, 0.9, 0.9, 0.9)
                end
                GameTooltip:AddLine("Ability ID: " .. abilityID, 0.6, 0.6, 0.6)
            end
            GameTooltip:Show()
        end)
        
        texture:SetScript("OnLeave", function()
            if PetBattlePrimaryAbilityTooltip then
                pcall(function() PetBattlePrimaryAbilityTooltip:Hide() end)
            end
            GameTooltip:Hide()
        end)
    else
        texture:Hide()
    end
end

-- Breed ID to stat allocation mapping (based on WoW pet breed system)
local breedData = {
    [3] = {health = 5, power = 5, speed = 5, letters = "B/B"}, -- Balanced
    [4] = {health = 9, power = 0, speed = 9, letters = "H/S"}, -- Health/Speed 
    [5] = {health = 0, power = 20, speed = 0, letters = "P/P"}, -- Pure Power
    [6] = {health = 20, power = 0, speed = 0, letters = "H/H"}, -- Pure Health
    [7] = {health = 9, power = 9, speed = 0, letters = "H/P"}, -- Health/Power
    [8] = {health = 0, power = 9, speed = 9, letters = "P/S"}, -- Power/Speed
    [9] = {health = 4, power = 9, speed = 4, letters = "H/S"}, -- Health/Speed (variant)
    [10] = {health = 4, power = 4, speed = 9, letters = "P/B"}, -- Power/Balance
    [11] = {health = 4, power = 4, speed = 9, letters = "S/B"}, -- Speed/Balance
    [12] = {health = 9, power = 4, speed = 4, letters = "H/B"}, -- Health/Balance
    [13] = {health = 5, power = 5, speed = 5, letters = "B/B"}, -- Balanced (variant)
    [14] = {health = 0, power = 0, speed = 20, letters = "S/S"}, -- Pure Speed
    [15] = {health = 0, power = 0, speed = 20, letters = "S/S"}, -- Pure Speed (variant)
    [16] = {health = 20, power = 0, speed = 0, letters = "H/H"}, -- Pure Health (variant)
    [17] = {health = 9, power = 0, speed = 9, letters = "H/P"}, -- Health/Power (variant)
    [18] = {health = 0, power = 9, speed = 9, letters = "P/S"}, -- Power/Speed (variant)
    [19] = {health = 4, power = 9, speed = 4, letters = "H/S"}, -- Health/Speed (variant)
    [20] = {health = 4, power = 4, speed = 9, letters = "P/B"}, -- Power/Balance (variant)
    [21] = {health = 4, power = 4, speed = 9, letters = "S/B"}, -- Speed/Balance (variant)
    [22] = {health = 9, power = 4, speed = 4, letters = "H/B"}, -- Health/Balance (variant)
}

-- Quality multipliers (exact values from BattlePetBreedID)
local qualityMultipliers = {
    [1] = 0.5,
    [2] = 0.550000011920929,
    [3] = 0.600000023841858, 
    [4] = 0.649999976158142,
    [5] = 0.699999988079071,
    [6] = 0.75
}

-- Breed stats modifiers (exact values from BattlePetBreedID)
local breedStatsModifiers = {
    [3] = {0.5, 0.5, 0.5},   -- B/B
    [4] = {0, 2, 0},         -- P/P
    [5] = {0, 0, 2},         -- S/S
    [6] = {2, 0, 0},         -- H/H
    [7] = {0.9, 0.9, 0},     -- H/P
    [8] = {0, 0.9, 0.9},     -- P/S
    [9] = {0.9, 0, 0.9},     -- H/S
    [10] = {0.4, 0.9, 0.4},  -- P/B
    [11] = {0.4, 0.4, 0.9},  -- S/B
    [12] = {0.9, 0.4, 0.4}   -- H/B
}

--[[
  Calculate breed stats for a pet using BattlePetBreedID algorithm
]]
local function CalculateBreedStats(baseHealth, basePower, baseSpeed, breedID, level, quality)
    level = level or 25
    quality = quality or 3
    
    local breedMods = breedStatsModifiers[breedID]
    if not breedMods then
        return nil -- Unknown breed
    end
    
    local qualityMult = qualityMultipliers[quality] or qualityMultipliers[3]
    local nQL = qualityMult * 2 * level
    
    -- Use exact BattlePetBreedID formulas
    local health = math.floor(((baseHealth + breedMods[1]) * nQL * 5 + 100) + 0.5)
    local power = math.floor(((basePower + breedMods[2]) * nQL) + 0.5)
    local speed = math.floor(((baseSpeed + breedMods[3]) * nQL) + 0.5)
    
    return {
        health = health,
        power = power,
        speed = speed,
        letters = breedData[breedID] and breedData[breedID].letters or "?/?"
    }
end

--[[
  Get collection status for a pet species with breed information
]]
local function GetPetCollectionInfo(speciesID)
    local collectedCount = 0
    local collectedPets = {}
    local maxQuality = 0
    
    for i = 1, C_PetJournal.GetNumPets() do
        local petID, speciesIDCheck, owned, customName, level, favorite, isRevoked = C_PetJournal.GetPetInfoByIndex(i)
        if speciesIDCheck == speciesID and owned then
            collectedCount = collectedCount + 1
            local health, maxHealth, power, speed, rarity = C_PetJournal.GetPetStats(petID)
            if rarity and rarity > maxQuality then
                maxQuality = rarity
            end
            
            -- Use the DetectPetBreed function which respects available breeds
            local breedID, breedLetters = DetectPetBreed(speciesID, health, power, speed, level, rarity)
            
            table.insert(collectedPets, {
                petID = petID,
                level = level or 1,
                rarity = rarity or 1,
                health = health or 0,
                power = power or 0,
                speed = speed or 0,
                breedID = breedID,
                breedLetters = breedLetters,
                customName = customName or nil
            })
        end
    end
    
    -- Sort by quality (rarity) descending, then by level descending
    table.sort(collectedPets, function(a, b)
        if a.rarity ~= b.rarity then
            return a.rarity > b.rarity
        end
        return a.level > b.level
    end)
    
    return collectedCount, collectedPets, maxQuality
end

--[[
  Get available breeds for a pet species with realistic WoW data
]]
--[[
  Get available breeds for a pet species using comprehensive breed data
]]
local function GetPetBreeds(speciesID)
    -- Check if we have breed data loaded and available for this species
    if not PCLcore.breedData or not PCLcore.breedData.species or not PCLcore.breedData.species[speciesID] then
        return {} -- No breed data available
    end
    
    -- Get the available breeds from our comprehensive data
    local availableBreedIDs = PCLcore.breedData.species[speciesID].breeds
    if not availableBreedIDs or #availableBreedIDs == 0 then
        return {} -- No breeds available for this species
    end
    
    -- Get base stats for this species (try to get from actual collected pets first)
    local baseHealth, basePower, baseSpeed = 10, 8, 9 -- Default fallback values
    local foundRealStats = false
    
    -- Look for collected pets of this species to get real base stats
    for i = 1, C_PetJournal.GetNumPets() do
        local petID, speciesIDCheck, owned, customName, level, favorite, isRevoked = C_PetJournal.GetPetInfoByIndex(i)
        if speciesIDCheck == speciesID and owned then
            local health, maxHealth, power, speed, rarity = C_PetJournal.GetPetStats(petID)
            if health and power and speed and level and level > 1 then
                -- Reverse calculate base stats using BattlePetBreedID method
                local qualityMult = qualityMultipliers[rarity] or qualityMultipliers[3]
                local nQL = qualityMult * 2 * level
                baseHealth = ((health - 100) / (nQL * 5)) - 0.5
                basePower = (power / nQL) - 0.5
                baseSpeed = (speed / nQL) - 0.5
                foundRealStats = true
                break
            end
        end
    end
    
    -- If no real stats found, use species-specific defaults based on common pet types
    if not foundRealStats then
        -- These are based on common WoW pet stat patterns
        local speciesName = C_PetJournal.GetPetInfoBySpeciesID(speciesID)
        if speciesName then
            if string.find(string.lower(speciesName), "moth") or string.find(string.lower(speciesName), "flying") then
                baseHealth, basePower, baseSpeed = 8, 7, 12  -- Flying pets tend to be fast
            elseif string.find(string.lower(speciesName), "beast") or string.find(string.lower(speciesName), "wolf") then
                baseHealth, basePower, baseSpeed = 10, 10, 8   -- Balanced stats
            else
                baseHealth, basePower, baseSpeed = 9, 8, 9     -- Default balanced
            end
        end
    end
    
    -- Build breeds list using only the available breeds for this species
    local breeds = {}
    for _, breedID in ipairs(availableBreedIDs) do
        local breedName = PCLcore.GetBreedName(breedID)
        local stats = CalculateBreedStats(baseHealth, basePower, baseSpeed, breedID, 25, 3)
        if stats and breedName then
            table.insert(breeds, {
                breedID = breedID,
                breedCode = breedName,
                health = stats.health,
                power = stats.power,
                speed = stats.speed
            })
        end
    end
    
    -- Sort by total stats descending (most powerful first)
    table.sort(breeds, function(a, b)
        local totalA = a.health + a.power + a.speed
        local totalB = b.health + b.power + b.speed
        return totalA > totalB
    end)
    
    return breeds
end

--[[
  Update ability display with proper tooltip
]]
local function UpdateAbility(texture, abilityID, petType)
    if not abilityID then
        texture:Hide()
        return
    end
    
    local _, icon = C_PetJournal.GetPetAbilityInfo(abilityID)
    if icon then
        texture:Show()
        texture:SetTexture(icon)
        
        -- Add border to ability icons
        if not texture.border then
            texture.border = texture:GetParent():CreateTexture(nil, "OVERLAY")
            texture.border:SetPoint("CENTER", texture, "CENTER")
            texture.border:SetSize(texture:GetSize())
            texture.border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
            texture.border:SetVertexColor(0.5, 0.5, 0.5, 0.8)
        end
        
        texture:SetScript("OnEnter", function(self)
            -- Try to use the proper WoW pet battle tooltip first
            if SharedPetBattleAbilityTooltip_SetAbility and PetBattlePrimaryAbilityTooltip and PetBattlePrimaryAbilityTooltip.SetOwner then
                local abilityInfo = C_PetJournal.GetPetAbilityInfo(abilityID)
                if abilityInfo then
                    local success = pcall(function()
                        PetBattlePrimaryAbilityTooltip:SetOwner(self, "ANCHOR_RIGHT")
                        SharedPetBattleAbilityTooltip_SetAbility(PetBattlePrimaryAbilityTooltip, abilityInfo)
                        PetBattlePrimaryAbilityTooltip:Show()
                    end)
                    if success then
                        return
                    end
                end
            end
            
            -- Fallback to custom tooltip with detailed ability info
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            local name, icon, petType, noStrongWeakHints = C_PetJournal.GetPetAbilityInfo(abilityID)
            if name then
                GameTooltip:SetText(name, 1, 1, 1, 1, true)
                if petType then
                    local familyName = getFamilyDetails(petType)
                    GameTooltip:AddLine("Type: " .. familyName, 0.9, 0.9, 0.9)
                end
                GameTooltip:AddLine("Ability ID: " .. abilityID, 0.6, 0.6, 0.6)
            else
                GameTooltip:SetText("Pet Ability", 1, 1, 1)
                GameTooltip:AddLine("Ability ID: " .. abilityID, 0.8, 0.8, 0.8)
            end
            GameTooltip:Show()
        end)
        
        texture:SetScript("OnLeave", function()
            if PetBattlePrimaryAbilityTooltip and PetBattlePrimaryAbilityTooltip.Hide then
                pcall(function()
                    PetBattlePrimaryAbilityTooltip:Hide()
                end)
            end
            GameTooltip:Hide()
        end)
    else
        texture:Hide()
    end
end

--[[
  Create section header with your navigation frame styling
]]
local function CreateSectionHeader(parent, text, yOffset, currentOpacity)
    local header = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    header:SetSize(PET_CARD_WIDTH - 40, 25)
    header:SetPoint("TOP", parent, "TOP", 0, yOffset)
    
    -- Use current opacity if provided, otherwise fallback
    local opacity = currentOpacity or (PCL_SETTINGS and PCL_SETTINGS.opacity) or 0.95
    
    -- Use your navigation frame styling
    if PCL_SETTINGS and PCL_SETTINGS.useBlizzardTheme then
        header:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background", 
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
            edgeSize = 8,
            insets = {left = 2, right = 2, top = 2, bottom = 2}
        })
        header:SetBackdropColor(0.05, 0.05, 0.2, opacity)
        header:SetBackdropBorderColor(0.6, 0.6, 0.8, 0.8)
    else
        header:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8", 
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
            edgeSize = 4
        })
        header:SetBackdropColor(0.1, 0.1, 0.1, opacity)  -- Use current opacity setting
        header:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
    end
    
    local headerText = header:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    headerText:SetPoint("LEFT", header, "LEFT", 8, 0)
    if PCL_SETTINGS and PCL_SETTINGS.useBlizzardTheme then
        headerText:SetTextColor(1, 0.82, 0, 1)  -- Gold color like Blizzard UI
    else
        headerText:SetTextColor(0.3, 0.7, 0.9, 1)  -- Your PCL blue color
    end
    headerText:SetText(text)
    
    return header
end

-- Mixed implementation cleanup - removed incomplete functions

--[[
  Create the main PetCard frame using PCL styling
]]
function PetCard:CreatePetCard()
    if PCL_PetCard then
        return PCL_PetCard  -- Already exists
    end
    
    -- Create main frame with PCL styling
    local f = CreateFrame("Frame", "PCL_PetCard", UIParent, "BackdropTemplate")
    f:SetSize(PET_CARD_WIDTH, 500)  -- Match main window height
    f:SetFrameStrata("HIGH")
    f:SetFrameLevel(100)
    f:SetMovable(false)  -- Disable moving since it's anchored
    f:EnableMouse(true)
    f:SetClampedToScreen(true)
    f:Hide()  -- Start hidden
    
    -- Apply PCL theming
    local currentOpacity = (PCL_SETTINGS and PCL_SETTINGS.opacity) or 0.95
    if PCL_SETTINGS and PCL_SETTINGS.useBlizzardTheme then
        f:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", 
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", 
            edgeSize = 16,
            insets = {left = 4, right = 4, top = 4, bottom = 4}
        })
        f:SetBackdropColor(0.05, 0.05, 0.15, currentOpacity)
        f:SetBackdropBorderColor(0.4, 0.4, 0.6, 1)
    else
        f:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8", 
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
            edgeSize = 8
        })
        f:SetBackdropColor(0.08, 0.08, 0.08, currentOpacity)
        f:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
    end
    
    -- Tabs removed - simplified layout
    
    -- Title bar
    f.titleFrame = CreateFrame("Frame", nil, f)
    f.titleFrame:SetSize(PET_CARD_WIDTH - 20, 40)
    f.titleFrame:SetPoint("TOP", f, "TOP", 0, -10)
    f.titleFrame:EnableMouse(false)  -- Disable dragging since frame is anchored
    
    -- Title text
    f.title = f.titleFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.title:SetPoint("LEFT", f.titleFrame, "LEFT", 10, 0)
    f.title:SetText("Pet Information")
    if PCL_SETTINGS and PCL_SETTINGS.useBlizzardTheme then
        f.title:SetTextColor(1, 0.82, 0, 1)
    else
        f.title:SetTextColor(0.3, 0.7, 0.9, 1)
    end
    
    
    -- Scroll frame for content (positioned below title frame)
    f.scrollFrame = CreateFrame("ScrollFrame", nil, f)
    f.scrollFrame:SetPoint("TOPLEFT", f.titleFrame, "BOTTOMLEFT", 0, -10)  -- Below title frame
    f.scrollFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -10, 10)
    
    -- Scroll child
    f.scrollChild = CreateFrame("Frame", nil, f.scrollFrame)
    f.scrollChild:SetSize(PET_CARD_WIDTH - 20, PET_CARD_HEIGHT - 80)  -- Adjusted for no tab bar and no scrollbar
    f.scrollFrame:SetScrollChild(f.scrollChild)
    
    -- Initialize properties
    f.isPinned = false
    f.currentSpeciesID = nil
    f.currentAnchorFrame = nil
    
    -- Store global reference
    PCL_PetCard = f
    return f
end

--[[
  Create pet card content directly in the main window
]]
function PetCard:CreatePetCardContent(parentFrame, petData)
    if not parentFrame or not petData then
        -- Missing parentFrame or petData
        return
    end
    
    
    -- Clear existing content in the parent frame
    local children = {parentFrame:GetChildren()}
    for _, child in ipairs(children) do
        if child then
            child:Hide()
            if child.SetParent then
                child:SetParent(nil)
            end
        end
    end
    
    -- Get pet data from WoW API
    local speciesName, speciesIcon, petType, companionID, tooltipSource, tooltipDescription, isWild, canBattle, isTradeable, isUnique, obtainable, creatureDisplayID = C_PetJournal.GetPetInfoBySpeciesID(petData.speciesID)
    local abilities = C_PetJournal.GetPetAbilityList(petData.speciesID)
    
    
    -- Get pet collection info
    local collectedCount, collectedPets, maxQuality = GetPetCollectionInfo(petData.speciesID)
    
    local yOffset = -20
    local contentHeight = 40
    local contentWidth = parentFrame:GetWidth() - 60 -- Leave margins
    
    -- Pet Card Title
    local titleFrame = CreateFrame("Frame", nil, parentFrame)
    titleFrame:SetSize(contentWidth, 40)
    titleFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 30, yOffset)
    
    local title = titleFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("LEFT", titleFrame, "LEFT", 0, 0)
    title:SetText(speciesName or "Unknown Pet")
    title:SetTextColor(1, 0.82, 0, 1) -- Yellow title
    
    yOffset = yOffset - 50
    contentHeight = contentHeight + 50
    
    -- Main content area: Full-width model frame
    local mainContentFrame = CreateFrame("Frame", nil, parentFrame)
    mainContentFrame:SetSize(contentWidth, 125)
    mainContentFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 30, yOffset)
    
    -- Full-width model area
    local modelFrame = CreateFrame("Frame", nil, mainContentFrame, "BackdropTemplate")
    modelFrame:SetSize(contentWidth, 125)
    modelFrame:SetPoint("TOPLEFT", mainContentFrame, "TOPLEFT", 0, 0)
    
    -- Style the model frame
    modelFrame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 4,
        insets = {left = 3, right = 3, top = 3, bottom = 3}
    })
    modelFrame:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
    modelFrame:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
    
    -- Create the 3D model in the model frame
    local petModel = CreateFrame("PlayerModel", nil, modelFrame)
    petModel:SetSize(contentWidth - 50, 190)
    petModel:SetPoint("CENTER", modelFrame, "CENTER", 0, 0)
    
    -- Enable mouse interaction
    petModel:EnableMouse(true)
    petModel:SetScript("OnMouseWheel", function(self, delta)
        -- Use SetCamDistanceScale for PlayerModel frames
        local currentScale = self.cameraScale or 1.8
        currentScale = currentScale - (delta * 0.2)  -- Adjust zoom sensitivity
        currentScale = math.max(0.5, math.min(5.0, currentScale))  -- Reasonable zoom range
        self:SetCamDistanceScale(currentScale)
        self.cameraScale = currentScale  -- Store current scale
    end)
    
    -- Set up the 3D model with fallback
    if modelVariations and modelVariations.variations and #modelVariations.variations > 0 then
        -- Model variations available - will be handled by tab system below
    else
        -- No variations - set up default model
        if companionID and companionID > 0 then
            local success = pcall(function()
                petModel:SetCreature(companionID)
            end)
            
            if success then
                petModel:Show()
                C_Timer.After(0.1, function()
                    if petModel then
                        petModel:SetCamDistanceScale(1.8)
                        petModel:SetRotation(0.3)
                        if petModel.RefreshCamera then
                            petModel:RefreshCamera()
                        end
                    end
                end)
            else
                petModel:Hide()
            end
        end
    end
    
    -- Fallback icon if 3D model doesn't work
    local fallbackIcon = mainContentFrame.modelFrame.fallbackIcon
    if not fallbackIcon then
        fallbackIcon = mainContentFrame.modelFrame:CreateTexture(nil, "ARTWORK")
        mainContentFrame.modelFrame.fallbackIcon = fallbackIcon
        fallbackIcon:SetSize(128, 128)
        fallbackIcon:SetPoint("CENTER", mainContentFrame.modelFrame, "CENTER", 20, 0)  -- Offset for tabs
    end
    
    if not companionID or companionID <= 0 then
        if speciesIcon then
            fallbackIcon:SetTexture(speciesIcon)
            fallbackIcon:Show()
        end
        petModel:Hide()
    else
        fallbackIcon:Hide()
    end
    
    yOffset = yOffset - 140
    contentHeight = contentHeight + 140
    
    -- Description section
    if tooltipDescription then
        local descFrame = CreateFrame("Frame", nil, parentFrame)
        descFrame:SetSize(contentWidth, 30)
        descFrame:SetPoint("TOPLEFT", parentFrame, "TOPLEFT", 30, yOffset)
        
        local descText = descFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        descText:SetPoint("TOPLEFT", descFrame, "TOPLEFT", 0, 0)
        descText:SetPoint("TOPRIGHT", descFrame, "TOPRIGHT", 0, 0)
        descText:SetJustifyH("CENTER")
        descText:SetWordWrap(true)
        descText:SetText(tooltipDescription)
        descText:SetTextColor(1, 0.82, 0, 1)
        
        local descHeight = descText:GetStringHeight()
        descFrame:SetHeight(descHeight + 10)
        yOffset = yOffset - (descHeight + 20)
        contentHeight = contentHeight + descHeight + 20
    end
    
    -- Set the parent frame's height to fit all content
    parentFrame:SetHeight(contentHeight + 40)
end

--[[
  Update window with pet data - Main content update function
]]
function PetCard:UpdateWindow(petData)
    if not PCL_PetCard or not petData then 
        -- Missing PetCard or petData
        return 
    end
    
    
    -- Get the current opacity setting fresh each time
    local currentOpacity = 0.95  -- default fallback
    if PCL_SETTINGS and PCL_SETTINGS.opacity then
        currentOpacity = PCL_SETTINGS.opacity
    end
    
    -- For backdrop color, we need to use a much lower opacity to match the main frame's visual appearance
    local backdropOpacity = math.min(1.0, currentOpacity * 1.2)  -- More opaque to match main frame appearance, clamped to 1.0
    
    -- Update main frame opacity if it exists using navigation frame styling
    if PCL_PetCard.SetBackdropColor then
        if PCL_SETTINGS and PCL_SETTINGS.useBlizzardTheme then
            PCL_PetCard:SetBackdropColor(0.05, 0.05, 0.15, 0.95)  -- Dark blue tint with higher opacity
        else
            PCL_PetCard:SetBackdropColor(0.08, 0.08, 0.08, 0.95)  -- Same as nav frame
        end
    end
    
    -- Get pet data from WoW API
    local speciesName, speciesIcon, petType, companionID, tooltipSource, tooltipDescription, isWild, canBattle, isTradeable, isUnique, obtainable, creatureDisplayID = C_PetJournal.GetPetInfoBySpeciesID(petData.speciesID)
    local abilities = C_PetJournal.GetPetAbilityList(petData.speciesID)
    
    
    -- Get pet collection info
    local collectedCount, collectedPets, maxQuality = GetPetCollectionInfo(petData.speciesID)
    
    -- Update title
    PCL_PetCard.title:SetText(speciesName or "Unknown Pet")
    
    -- Clear and rebuild content - properly destroy all child frames
    if PCL_PetCard.scrollChild then
        -- Get all children and completely remove them
        local children = {PCL_PetCard.scrollChild:GetChildren()}
        for _, child in ipairs(children) do
            if child then
                -- Hide child first
                if child.Hide then
                    child:Hide()
                end
                
                -- Clear all child's own children recursively
                local subChildren = {child:GetChildren()}
                for _, subChild in ipairs(subChildren) do
                    if subChild and subChild.Hide then
                        subChild:Hide()
                    end
                    if subChild and subChild.SetParent then
                        subChild:SetParent(nil)
                    end
                end
                
                -- Clear all regions (textures/fontstrings) on the child
                local childRegions = {child:GetRegions()}
                for _, region in ipairs(childRegions) do
                    if region and region.Hide then
                        region:Hide()
                    end
                    if region and region.SetParent then
                        region:SetParent(nil)
                    end
                end
                
                -- Finally remove the child itself
                if child.SetParent then
                    child:SetParent(nil)
                end
            end
        end
        
        -- Also clear font strings and textures that are direct children of scrollChild
        local regions = {PCL_PetCard.scrollChild:GetRegions()}
        for _, region in ipairs(regions) do
            if region and region.Hide then
                region:Hide()
            end
            if region and region.SetParent then
                region:SetParent(nil)
            end
        end
        
        -- Clear ALL stored references so they get recreated fresh
        PCL_PetCard.scrollChild.mainContent = nil
        PCL_PetCard.scrollChild.modelFrame = nil
        PCL_PetCard.scrollChild.infoFrame = nil
        PCL_PetCard.scrollChild.petModel = nil
        PCL_PetCard.scrollChild.fallbackIcon = nil
        PCL_PetCard.scrollChild.petNameLabel = nil
        PCL_PetCard.scrollChild.familyIconTex = nil
        PCL_PetCard.scrollChild.familyText = nil
        PCL_PetCard.scrollChild.collectionText = nil
        PCL_PetCard.scrollChild.tradeableText = nil
        PCL_PetCard.scrollChild.petTabContainer = nil
        PCL_PetCard.scrollChild.sourceLabel = nil
        PCL_PetCard.scrollChild.descText = nil
        PCL_PetCard.scrollChild.descFrame = nil
        PCL_PetCard.scrollChild.bannerFrame = nil
        PCL_PetCard.scrollChild.mainFrame = nil
        -- Clear section headers
        PCL_PetCard.scrollChild.abilitiesHeader = nil
        PCL_PetCard.scrollChild.petsHeader = nil
        PCL_PetCard.scrollChild.sourceHeader = nil
        PCL_PetCard.scrollChild.descHeader = nil
        -- Clear ability frames
        for i = 1, 10 do
            PCL_PetCard.scrollChild["abilityFrame" .. i] = nil
        end
    end
    
    local yOffset = -5  -- Moved closer to title (was -20)
    local contentHeight = 20
    
    -- Main content area: Full-width model frame like in reference
    local mainContentFrame = PCL_PetCard.scrollChild.mainContent or CreateFrame("Frame", nil, PCL_PetCard.scrollChild)
    PCL_PetCard.scrollChild.mainContent = mainContentFrame
    mainContentFrame:SetSize(PET_CARD_WIDTH - 20, 180)  -- Increased height from 125 to 180
    mainContentFrame:SetPoint("TOPLEFT", PCL_PetCard.scrollChild, "TOPLEFT", 10, yOffset)  -- Reduced left margin from 20 to 10
    
    -- Full-width model area (like in reference image)
    local modelFrame = mainContentFrame.modelFrame or CreateFrame("Frame", nil, mainContentFrame, "BackdropTemplate")
    mainContentFrame.modelFrame = modelFrame
    modelFrame:SetSize(PET_CARD_WIDTH - 20, 180)  -- Increased height from 125 to 180
    modelFrame:SetPoint("TOPLEFT", mainContentFrame, "TOPLEFT", 0, 0)
    
    -- Style the model frame
    modelFrame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 4,
        insets = {left = 3, right = 3, top = 3, bottom = 3}
    })
    modelFrame:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
    modelFrame:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
    
    -- Create the 3D model in the model frame
    local petModel = mainContentFrame.modelFrame.petModel
    
    if not petModel then
        -- Use PlayerModel for 3D display
        petModel = CreateFrame("PlayerModel", nil, mainContentFrame.modelFrame)
        mainContentFrame.modelFrame.petModel = petModel
        petModel:SetSize(PET_CARD_WIDTH - 90, 175)  -- Reduced width to make room for tabs
        petModel:SetPoint("CENTER", mainContentFrame.modelFrame, "CENTER", 20, 0)  -- Offset right for tabs
        
        -- Enable mouse interaction for camera controls
        petModel:EnableMouse(true)
        petModel:SetScript("OnMouseWheel", function(self, delta)
            -- Use SetCamDistanceScale for PlayerModel frames
            local currentScale = self.cameraScale or 1.8
            currentScale = currentScale - (delta * 0.2)  -- Adjust zoom sensitivity
            currentScale = math.max(0.5, math.min(5.0, currentScale))  -- Reasonable zoom range
            self:SetCamDistanceScale(currentScale)
            self.cameraScale = currentScale  -- Store current scale
        end)
        
        -- Enable dragging to rotate
        petModel:SetScript("OnMouseDown", function(self, button)
            if button == "LeftButton" then
                self.isRotating = true
                self.startX = GetCursorPosition()
            end
        end)
        
        petModel:SetScript("OnMouseUp", function(self, button)
            if button == "LeftButton" then
                self.isRotating = false
            end
        end)
        
        petModel:SetScript("OnUpdate", function(self)
            if self.isRotating then
                local currentX = GetCursorPosition()
                if self.startX then
                    local deltaX = (currentX - self.startX) * 0.01
                    local currentRotation = self.currentRotation or 0.3
                    currentRotation = currentRotation + deltaX
                    self:SetRotation(currentRotation)
                    self.currentRotation = currentRotation
                    self.startX = currentX
                end
            end
        end)
    end
    
    -- Create model variation tabs system
    local modelVariationsFrame = mainContentFrame.modelFrame.modelVariationsFrame
    if not modelVariationsFrame then
        modelVariationsFrame = CreateFrame("Frame", nil, mainContentFrame.modelFrame)
        mainContentFrame.modelFrame.modelVariationsFrame = modelVariationsFrame
        modelVariationsFrame:SetSize(40, 175)  -- Narrow tab area
        modelVariationsFrame:SetPoint("LEFT", mainContentFrame.modelFrame, "LEFT", 5, 0)
    end
    
    -- Get model variations for this pet
    local modelVariations = nil
    if PCLcore.PetModelVariations and PCLcore.PetModelVariations[petData.speciesID] then
        modelVariations = PCLcore.PetModelVariations[petData.speciesID]
    end
    
    -- Clear existing tabs
    if modelVariationsFrame.tabs then
        for _, tab in ipairs(modelVariationsFrame.tabs) do
            tab:Hide()
            tab:SetParent(nil)
        end
    end
    modelVariationsFrame.tabs = {}
    
    -- Function to update the model display
    local function UpdateModelDisplay(displayID, isOwned)
        if not petModel then 
            return 
        end
        
        local modelShown = false
        
        if displayID then
            -- Try method 1: Set display info directly
            local success = pcall(function()
                petModel:SetDisplayInfo(tonumber(displayID))
                modelShown = true
            end)
            
            if not success and companionID and companionID > 0 then
                -- Try method 2: Set creature and override display
                success = pcall(function()
                    petModel:SetCreature(companionID)
                    -- Some models might need the display ID set after creature
                    petModel:SetDisplayInfo(tonumber(displayID))
                    modelShown = true
                end)
            end
            
            if not success and companionID and companionID > 0 then
                -- Fallback: Just use the base creature model
                success = pcall(function()
                    petModel:SetCreature(companionID)
                    modelShown = true
                end)
            end
        elseif companionID and companionID > 0 then
            -- No specific display ID, use creature ID
            local success = pcall(function()
                petModel:SetCreature(companionID)
                modelShown = true
            end)
        end
        
        if modelShown then
            petModel:Show()
            -- Apply camera settings after a brief delay
            C_Timer.After(0.1, function()
                if petModel then
                    petModel:SetCamDistanceScale(1.8)
                    petModel:SetRotation(0.3)
                    petModel.currentRotation = 0.3
                    if petModel.RefreshCamera then
                        petModel:RefreshCamera()
                    end
                end
            end)
            
            -- Update visual feedback based on ownership
            if petModel and petModel.SetDesaturated then
                if isOwned then
                    petModel:SetDesaturated(false)
                    petModel:SetAlpha(1.0)
                else
                    petModel:SetDesaturated(true)
                    petModel:SetAlpha(0.6)
                end
            elseif petModel then
                -- Fallback: only set alpha if SetDesaturated is not available
                if isOwned then
                    petModel:SetAlpha(1.0)
                else
                    petModel:SetAlpha(0.6)
                end
            end
            
            -- Hide fallback icon
            if fallbackIcon then
                fallbackIcon:Hide()
            end
        else
            -- Model failed to load, show fallback icon
            if petModel then
                petModel:Hide()
            end
            if fallbackIcon and speciesIcon then
                fallbackIcon:SetTexture(speciesIcon)
                fallbackIcon:Show()
                if fallbackIcon.SetDesaturated then
                    if not isOwned then
                        fallbackIcon:SetDesaturated(true)
                        fallbackIcon:SetAlpha(0.6)
                    else
                        fallbackIcon:SetDesaturated(false)
                        fallbackIcon:SetAlpha(1.0)
                    end
                else
                    -- Fallback: only set alpha if SetDesaturated is not available
                    if not isOwned then
                        fallbackIcon:SetAlpha(0.6)
                    else
                        fallbackIcon:SetAlpha(1.0)
                    end
                end
            elseif fallbackIcon then
                -- Ensure fallback icon is hidden if no speciesIcon
                fallbackIcon:Hide()
            end
        end
    end
    
    -- Function to check if player owns this specific display variant
    local function PlayerOwnsDisplayVariant(displayID)
        if not displayID then return false end
        
        -- If player doesn't have any of this species, they can't own any variants
        if collectedCount == 0 then
            return false
        end
        
        -- Check probability and return ownership based on collection count
        local variations = modelVariations and modelVariations.variations
        if variations then
            for _, variation in ipairs(variations) do
                if variation.displays then
                    for _, display in ipairs(variation.displays) do
                        if display.id == displayID then
                            -- For high-probability variants (>= 80%), assume owned if pet is collected
                            if display.probability >= 80 then
                                return true
                            end
                            
                            -- For medium-probability variants (20-79%), show as potentially owned based on collection count
                            if display.probability >= 20 and display.probability < 80 then
                                local result = collectedCount >= 2
                                return result
                            end
                            
                            -- For rare variants (<20%), be more generous
                            if display.probability < 20 and display.probability > 0 then
                                local result
                                if display.probability < 5 then
                                    -- For very rare variants, show the most common one as owned if we have any pets
                                    -- Find the highest probability among all variants for this pet
                                    local maxProbability = 0
                                    if PCLcore.PetModelVariations[petData.speciesID] and PCLcore.PetModelVariations[petData.speciesID].variations then
                                        for _, variation in ipairs(PCLcore.PetModelVariations[petData.speciesID].variations) do
                                            if variation.displays then
                                                for _, varDisplay in ipairs(variation.displays) do
                                                    if varDisplay.probability > maxProbability then
                                                        maxProbability = varDisplay.probability
                                                    end
                                                end
                                            end
                                        end
                                    end
                                    
                                    -- If this is the most common variant and we have any pets, show as owned
                                    if display.probability == maxProbability and collectedCount >= 1 then
                                        result = true
                                    else
                                        result = collectedCount >= 2
                                    end
                                else
                                    result = collectedCount >= 1
                                end
                                return result
                            end
                        end
                    end
                end
            end
        end
        
        -- Fallback: If we have collected pets but no variants detected, 
        -- assume ownership of at least the most common variant
        if collectedCount > 0 and variations then
            local highestProb = 0
            local mostCommonDisplayID = nil
            for _, variation in ipairs(variations) do
                if variation.displays then
                    for _, display in ipairs(variation.displays) do
                        if display.probability > highestProb then
                            highestProb = display.probability
                            mostCommonDisplayID = display.id
                        end
                    end
                end
            end
            
            if mostCommonDisplayID == displayID then
                return true
            end
        end
        
        return false
    end
    
    if modelVariations and modelVariations.variations and #modelVariations.variations > 0 then
        -- Count total display variants across all variations
        local totalDisplays = 0
        for varIndex, variation in ipairs(modelVariations.variations) do
            if variation.displays then
                totalDisplays = totalDisplays + #variation.displays
            end
        end
        
        -- Only show tabs if there are multiple display variants
        if totalDisplays > 1 then
            -- Calculate total probability for percentage normalization
            local totalProbability = 0
            for varIndex, variation in ipairs(modelVariations.variations) do
                if variation.displays then
                    for dispIndex, display in ipairs(variation.displays) do
                        totalProbability = totalProbability + (display.probability or 1)
                    end
                end
            end
            
            -- Create tabs for each model variation
            local tabIndex = 1
            local selectedTab = 1
        
        for varIndex, variation in ipairs(modelVariations.variations) do
            if variation.displays then
                for dispIndex, display in ipairs(variation.displays) do
                    if tabIndex <= 6 then  -- Limit to 6 tabs to fit in the space
                        local tab = CreateFrame("Button", nil, modelVariationsFrame, "BackdropTemplate")
                        tab:SetSize(32, 25)
                        tab:SetPoint("TOPLEFT", modelVariationsFrame, "TOPLEFT", 2, -(tabIndex - 1) * 28)
                        
                        -- Tab styling
                        tab:SetBackdrop({
                            bgFile = "Interface\\Buttons\\WHITE8x8",
                            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                            edgeSize = 2,
                            insets = {left = 2, right = 2, top = 2, bottom = 2}
                        })
                        
                        -- Check if player owns this variant
                        local isOwned = PlayerOwnsDisplayVariant(display.id)
                        
                        if isOwned then
                            tab:SetBackdropColor(0.2, 0.6, 0.2, 0.8)  -- Green for owned
                            tab:SetBackdropBorderColor(0.4, 0.8, 0.4, 1)
                        else
                            tab:SetBackdropColor(0.3, 0.3, 0.3, 0.8)  -- Gray for not owned
                            tab:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
                        end
                        
                        -- Tab number and ownership indicator
                        local tabText = tab:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                        tabText:SetPoint("CENTER", tab, "CENTER", 0, 0)
                        tabText:SetText(tostring(tabIndex))
                        if isOwned then
                            tabText:SetTextColor(1, 1, 1, 1)  -- White for owned
                        else
                            tabText:SetTextColor(0.6, 0.6, 0.6, 1)  -- Gray for not owned
                        end
                        
                        -- Add checkmark for owned variants
                        if isOwned then
                            local checkmark = tab:CreateTexture(nil, "OVERLAY")
                            checkmark:SetTexture("Interface\\RaidFrame\\ReadyCheck-Ready")
                            checkmark:SetSize(8, 8)
                            checkmark:SetPoint("BOTTOMRIGHT", tab, "BOTTOMRIGHT", -2, 2)
                            tab.checkmark = checkmark
                        end
                        
                        -- Store display info
                        tab.displayID = display.id
                        tab.isOwned = isOwned
                        tab.probability = display.probability
                        tab.totalProbability = totalProbability
                        tab.tabIndex = tabIndex
                        
                        -- Tab click handler
                        tab:SetScript("OnClick", function(self)
                            -- Update all tabs to unselected state
                            for _, otherTab in ipairs(modelVariationsFrame.tabs) do
                                if otherTab.isOwned then
                                    otherTab:SetBackdropColor(0.2, 0.6, 0.2, 0.8)
                                    otherTab:SetBackdropBorderColor(0.4, 0.8, 0.4, 1)
                                else
                                    otherTab:SetBackdropColor(0.3, 0.3, 0.3, 0.8)
                                    otherTab:SetBackdropBorderColor(0.5, 0.5, 0.5, 1)
                                end
                            end
                            
                            -- Set this tab as selected
                            if self.isOwned then
                                self:SetBackdropColor(0.1, 0.8, 0.1, 1.0)  -- Brighter green for selected owned
                                self:SetBackdropBorderColor(0.6, 1.0, 0.6, 1)
                            else
                                self:SetBackdropColor(0.5, 0.5, 0.5, 1.0)  -- Brighter gray for selected not owned
                                self:SetBackdropBorderColor(0.7, 0.7, 0.7, 1)
                            end
                            
                            selectedTab = self.tabIndex
                            UpdateModelDisplay(self.displayID, self.isOwned)
                        end)
                        
                        -- Tooltip for tab
                        tab:SetScript("OnEnter", function(self)
                            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                            GameTooltip:SetText("Model Variant " .. self.tabIndex, 1, 1, 1, 1, true)
                            GameTooltip:AddLine("Display ID: " .. self.displayID, 0.8, 0.8, 0.8)
                            
                            -- Show probability info
                            if self.probability and self.probability > 0 then
                                -- Calculate normalized percentage
                                local percentage = 0
                                if self.totalProbability and self.totalProbability > 0 then
                                    percentage = (self.probability / self.totalProbability) * 100
                                end
                                
                                if percentage >= 80 then
                                    GameTooltip:AddLine(string.format("Very Common (%.0f%%)", percentage), 0.2, 1, 0.2)
                                elseif percentage >= 20 then
                                    GameTooltip:AddLine(string.format("Common (%.1f%%)", percentage), 0.9, 0.9, 0.5)
                                else
                                    GameTooltip:AddLine(string.format("Rare (%.1f%%)", percentage), 1, 0.5, 0.2)
                                end
                            end
                            
                            -- Ownership status
                            if self.isOwned then
                                GameTooltip:AddLine("You likely own this variant", 0.2, 1, 0.2)
                            else
                                GameTooltip:AddLine("You likely don't own this variant", 1, 0.4, 0.4)
                            end
                            
                            GameTooltip:AddLine("Click to preview", 0.6, 0.6, 1)
                            GameTooltip:Show()
                        end)
                        
                        tab:SetScript("OnLeave", function(self)
                            GameTooltip:Hide()
                        end)
                        
                        table.insert(modelVariationsFrame.tabs, tab)
                        tabIndex = tabIndex + 1
                    end
                end
            end
        end
        
        -- Select first owned variant, or first variant if none owned
        local firstOwnedTab = nil
        local firstTab = modelVariationsFrame.tabs[1]
        
        for _, tab in ipairs(modelVariationsFrame.tabs) do
            if tab.isOwned and not firstOwnedTab then
                firstOwnedTab = tab
                break
            end
        end
        
        local defaultTab = firstOwnedTab or firstTab
        if defaultTab then
            defaultTab:GetScript("OnClick")(defaultTab)
        end
        
        -- Show variation count and ownership summary
        local variationLabel = modelVariationsFrame.variationLabel
        if not variationLabel then
            variationLabel = modelVariationsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            modelVariationsFrame.variationLabel = variationLabel
            variationLabel:SetPoint("BOTTOM", modelVariationsFrame, "BOTTOM", 0, 5)
        end
        
        -- Count owned variants
        local ownedCount = 0
        for _, tab in ipairs(modelVariationsFrame.tabs) do
            if tab.isOwned then
                ownedCount = ownedCount + 1
            end
        end
        
        local totalCount = #modelVariationsFrame.tabs
        variationLabel:SetText(string.format("%d/%d variants", ownedCount, totalCount))
        
        -- Color based on completion
        if ownedCount == totalCount then
            variationLabel:SetTextColor(0.2, 1, 0.2, 1)  -- Green - complete
        elseif ownedCount > 0 then
            variationLabel:SetTextColor(1, 1, 0.5, 1)  -- Yellow - partial
        else
            variationLabel:SetTextColor(1, 0.4, 0.4, 1)  -- Red - none
        end
        
        else
            -- Only one variant, don't show tabs - just use default display
            UpdateModelDisplay(creatureDisplayID, true)
        end
        
    else
        -- No model variations - use default display
        UpdateModelDisplay(creatureDisplayID, true)
    end
    
    -- Add fullscreen button to model frame
    local fullscreenButton = mainContentFrame.modelFrame.fullscreenButton
    if not fullscreenButton then
        fullscreenButton = CreateFrame("Button", nil, mainContentFrame.modelFrame, "BackdropTemplate")
        mainContentFrame.modelFrame.fullscreenButton = fullscreenButton
        fullscreenButton:SetSize(28, 28)  -- Made even larger
        fullscreenButton:SetPoint("TOPRIGHT", mainContentFrame.modelFrame, "TOPRIGHT", -5, -5)  -- Adjusted for larger frame
        fullscreenButton:SetFrameLevel(mainContentFrame.modelFrame:GetFrameLevel() + 10)  -- Ensure it's on top
        
        -- Very visible background
        fullscreenButton:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 2,
        })
        fullscreenButton:SetBackdropColor(0.2, 0.2, 0.2, 0.9)  -- More opaque dark background
        fullscreenButton:SetBackdropBorderColor(0.8, 0.8, 0.8, 1)  -- Bright border
        
        -- Very visible expand icon using a simple texture
        local fullscreenIcon = fullscreenButton:CreateTexture(nil, "ARTWORK")
        fullscreenIcon:SetSize(20, 20)
        fullscreenIcon:SetPoint("CENTER", fullscreenButton, "CENTER", 0, 0)
        fullscreenIcon:SetTexture("Interface\\Buttons\\Arrow-Up-Up")
        fullscreenIcon:SetVertexColor(1, 1, 1, 1)
        
        -- Very obvious hover effects
        fullscreenButton:SetScript("OnEnter", function(self)
            self:SetBackdropColor(1, 0.82, 0, 0.9)  -- Bright yellow on hover
            fullscreenIcon:SetVertexColor(0, 0, 0, 1)  -- Black icon on yellow background
            
            GameTooltip:SetOwner(self, "ANCHOR_TOP")
            GameTooltip:SetText("Click for Fullscreen Pet View", 1, 1, 1)
            GameTooltip:Show()
        end)
        
        fullscreenButton:SetScript("OnLeave", function(self)
            self:SetBackdropColor(0.2, 0.2, 0.2, 0.9)  -- Back to dark
            fullscreenIcon:SetVertexColor(1, 1, 1, 1)  -- Back to white
            GameTooltip:Hide()
        end)
        
        -- Make sure button is always visible and clickable
        fullscreenButton:Show()
        fullscreenButton:EnableMouse(true)
        
        -- Fullscreen button created and positioned
    end
    
    -- Always update the click handler with current petData
    fullscreenButton:SetScript("OnClick", function(self)
        PCLcore.PetCard:ShowFullscreen(petData)
    end)
    
    -- Set up the 3D model
    if petModel and companionID and companionID > 0 then
        local success = pcall(function()
            petModel:SetCreature(companionID)
        end)
        
        if success then
            petModel:Show()
            C_Timer.After(0.1, function()
                if petModel then
                    petModel:SetCamDistanceScale(1.8)
                    petModel:SetRotation(0.3)
                    if petModel.RefreshCamera then
                        petModel:RefreshCamera()
                    end
                end
            end)
        else
            petModel:Hide()
        end
    end
    
    -- Fallback icon if 3D model doesn't work
    local fallbackIcon = mainContentFrame.modelFrame.fallbackIcon
    if not fallbackIcon then
        fallbackIcon = mainContentFrame.modelFrame:CreateTexture(nil, "ARTWORK")
        mainContentFrame.modelFrame.fallbackIcon = fallbackIcon
        fallbackIcon:SetSize(128, 128)
        fallbackIcon:SetPoint("CENTER", mainContentFrame.modelFrame, "CENTER", 0, 0)
    end
    
    if not petModel or not companionID or companionID <= 0 then
        if speciesIcon then
            fallbackIcon:SetTexture(speciesIcon)
            fallbackIcon:Show()
        end
        if petModel then petModel:Hide() end
    else
        fallbackIcon:Hide()
    end
    
    yOffset = yOffset - 185  -- Account for larger main content frame (was -130)
    contentHeight = contentHeight + 175  -- Account for increased height (was +120)
    
    -- Description section (directly under model - like in the reference image)
    if tooltipDescription then
        local descFrame = PCL_PetCard.scrollChild.descFrame or CreateFrame("Frame", nil, PCL_PetCard.scrollChild)
        PCL_PetCard.scrollChild.descFrame = descFrame
        descFrame:SetSize(PET_CARD_WIDTH - 20, 30)  -- Will adjust height based on content
        descFrame:SetPoint("TOPLEFT", PCL_PetCard.scrollChild, "TOPLEFT", 0, yOffset)  -- Position right after model
        
        local descText = descFrame.text or descFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        descFrame.text = descText
        descText:SetPoint("TOPLEFT", descFrame, "TOPLEFT", 0, 0)
        descText:SetPoint("TOPRIGHT", descFrame, "TOPRIGHT", 0, 0)
        descText:SetJustifyH("CENTER")
        descText:SetWordWrap(true)
        descText:SetText(tooltipDescription)
        descText:SetTextColor(1, 0.82, 0, 1)  -- Yellow like in reference image
        
        local descHeight = descText:GetStringHeight()
        descFrame:SetHeight(descHeight + 10)
        yOffset = yOffset - (descHeight + 20)  -- Adjust yOffset for next elements
        contentHeight = contentHeight + descHeight + 20
    end
    
    -- Banner section with family icon and "Possible Breeds" title
    local bannerFrame = PCL_PetCard.scrollChild.bannerFrame or CreateFrame("Frame", nil, PCL_PetCard.scrollChild, "BackdropTemplate")
    PCL_PetCard.scrollChild.bannerFrame = bannerFrame
    bannerFrame:SetSize(PET_CARD_WIDTH - 20, 35)  -- Increased height to accommodate larger icon, reduced padding
    bannerFrame:SetPoint("TOPLEFT", PCL_PetCard.scrollChild, "TOPLEFT", 10, yOffset)  -- Reduced left margin
    
    -- Style banner with subtle background
    bannerFrame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 1
    })
    bannerFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
    bannerFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
    
    -- Family icon and name (left side) - Enhanced with larger icon and colored text
    local familyIcon = bannerFrame.familyIcon or bannerFrame:CreateTexture(nil, "ARTWORK")
    bannerFrame.familyIcon = familyIcon
    familyIcon:SetSize(28, 28)  -- Slightly smaller, better proportion
    familyIcon:SetPoint("LEFT", bannerFrame, "LEFT", 5, 0)
    
    -- Use the correct pet type icon path (based on PetCollector reference)
    local familyName, iconKey, r, g, b = getFamilyDetails(petType or 8)
    local iconTexture = "Interface\\Icons\\Pet_Type_" .. (iconKey or "beast")
    familyIcon:SetTexture(iconTexture)
    familyIcon:SetTexCoord(0.1, 0.9, 0.1, 0.9)  -- Crop borders for cleaner look
    
    local familyText = bannerFrame.familyText or bannerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    bannerFrame.familyText = familyText
    familyText:SetPoint("LEFT", familyIcon, "RIGHT", 10, 0)
    familyText:SetText(PET_TYPE_SUFFIX[petType] or "Unknown")
    
    -- Set pet type colored text using the family details (already retrieved above)
    familyText:SetTextColor(r, g, b, 1)  -- Use the pet family color
    
    -- "Possible Breeds" title with collection status (right side)
    local breedsTitle = bannerFrame.breedsTitle or bannerFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    bannerFrame.breedsTitle = breedsTitle
    breedsTitle:SetPoint("RIGHT", bannerFrame, "RIGHT", -90, 0)
    
    -- Enhance title with breed collection information
    local breedsTitleText = "Possible Breeds"
    if collectionComparison and collectionComparison.isCollected then
        local ownedCount = #collectionComparison.ownedBreeds
        local totalCount = collectionComparison.totalAvailableBreeds
        if totalCount > 1 then  -- Only show breed count if there are multiple breeds
            breedsTitleText = string.format("Breeds (%d/%d)", ownedCount, totalCount)
            
            -- Color the title based on completion status
            if ownedCount >= totalCount then
                breedsTitle:SetTextColor(0, 1, 0, 1)  -- Green - complete
            elseif ownedCount > 0 then
                breedsTitle:SetTextColor(1, 1, 0, 1)  -- Yellow - partial
            else
                breedsTitle:SetTextColor(1, 0.4, 0.4, 1)  -- Light red - none collected
            end
        else
            breedsTitle:SetTextColor(0.8, 0.8, 0.8, 1)  -- Gray - single breed species
        end
    else
        breedsTitle:SetTextColor(0.5, 0.5, 0.5, 1)  -- Gray - not collected
    end
    
    breedsTitle:SetText(breedsTitleText)
    
    yOffset = yOffset - 40  -- Increased from 35 to account for larger banner
    contentHeight = contentHeight + 40
    
    -- Main content area - Compacted layout for narrower window
    local mainFrame = PCL_PetCard.scrollChild.mainFrame or CreateFrame("Frame", nil, PCL_PetCard.scrollChild)
    PCL_PetCard.scrollChild.mainFrame = mainFrame
    mainFrame:SetSize(PET_CARD_WIDTH - 20, 300)  -- Reduced padding, will adjust height based on content
    mainFrame:SetPoint("TOPLEFT", PCL_PetCard.scrollChild, "TOPLEFT", 10, yOffset)  -- Reduced left margin
    
    -- Column 1 (Left side) - 40% width (more compact)
    local leftColumn = mainFrame.leftColumn or CreateFrame("Frame", nil, mainFrame, "BackdropTemplate")
    mainFrame.leftColumn = leftColumn
    local leftWidth = (PET_CARD_WIDTH - 30) * 0.40  -- Adjusted for new padding (was 60, now 30)
    leftColumn:SetSize(leftWidth, 300)
    leftColumn:SetPoint("TOPLEFT", mainFrame, "TOPLEFT", 0, 0)
    
    -- Column 2 (Right side) - 55% width with 5% gap (more space for breeds)
    local rightColumn = mainFrame.rightColumn or CreateFrame("Frame", nil, mainFrame, "BackdropTemplate")
    mainFrame.rightColumn = rightColumn
    local rightWidth = (PET_CARD_WIDTH - 30) * 0.55  -- Adjusted for new padding (was 60, now 30)
    rightColumn:SetSize(rightWidth, 300)
    rightColumn:SetPoint("TOPRIGHT", mainFrame, "TOPRIGHT", 0, 0)
    
    -- LEFT COLUMN CONTENT
    
    -- Collected Header (Column 1)
    local collectedHeader = leftColumn.collectedHeader or leftColumn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    leftColumn.collectedHeader = collectedHeader
    collectedHeader:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 0, -10)
    if collectedCount and collectedCount > 0 then
        collectedHeader:SetText(string.format("Collected %d/3", collectedCount))
        collectedHeader:SetTextColor(1, 0.82, 0, 1)  -- Yellow
    else
        collectedHeader:SetText("Collected 0/3")
        collectedHeader:SetTextColor(0.6, 0.6, 0.6, 1)  -- Gray
    end
    
    -- Pet Collection List (Column 1) - With bordered frames
    local leftYOffset = -35
    if collectedCount and collectedCount > 0 then
        for i = 1, math.min(3, collectedCount) do
            local pet = collectedPets and collectedPets[i]
            if pet then
                local petFrame = leftColumn["petEntry" .. i] or CreateFrame("Frame", nil, leftColumn, "BackdropTemplate")
                leftColumn["petEntry" .. i] = petFrame
                petFrame:SetSize(leftWidth - 10, 22)  -- Slightly taller for border
                petFrame:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 5, leftYOffset)
                
                -- Add border styling to collected pet frames
                petFrame:SetBackdrop({
                    bgFile = "Interface\\Buttons\\WHITE8x8",
                    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                    edgeSize = 1,
                    insets = {left = 2, right = 2, top = 2, bottom = 2}
                })
                petFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.3)  -- Subtle dark background
                
                -- Color border based on pet quality
                local qualityColors = {
                    [1] = {0.6, 0.6, 0.6, 0.8}, -- Poor (gray)
                    [2] = {1, 1, 1, 0.8},       -- Common (white) 
                    [3] = {0.12, 1, 0, 0.8},    -- Uncommon (green)
                    [4] = {0, 0.44, 0.87, 0.8}, -- Rare (blue)
                    [5] = {0.64, 0.21, 0.93, 0.8}, -- Epic (purple)
                    [6] = {1, 0.5, 0, 0.8}      -- Legendary (orange)
                }
                local borderColor = qualityColors[pet.rarity] or qualityColors[1]
                petFrame:SetBackdropBorderColor(borderColor[1], borderColor[2], borderColor[3], borderColor[4])
                
                local petText = petFrame.text or petFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
                petFrame.text = petText
                petText:SetPoint("LEFT", petFrame, "LEFT", 4, 0)  -- Slight padding for border
                
                -- Format: "25 H/H" (level and breed)
                local qualityTextColors = {"", "|cff9d9d9d", "|cffffffff", "|cff1eff00", "|cff0070dd", "|cffa335ee", "|cffff8000"}
                local qualityColor = qualityTextColors[pet.rarity] or ""
                petText:SetText(string.format("%s%d %s|r", qualityColor, pet.level or 1, pet.breedLetters or "B/B"))
                
                leftYOffset = leftYOffset - 24  -- Account for slightly taller frames
            end
        end
    else
        -- Show "Not collected" message
        local notCollectedFrame = leftColumn.notCollectedFrame or CreateFrame("Frame", nil, leftColumn)
        leftColumn.notCollectedFrame = notCollectedFrame
        notCollectedFrame:SetSize(leftWidth - 10, 20)
        notCollectedFrame:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 5, leftYOffset)
        
        local notCollectedText = notCollectedFrame.text or notCollectedFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        notCollectedFrame.text = notCollectedText
        notCollectedText:SetPoint("LEFT", notCollectedFrame, "LEFT", 0, 0)
        notCollectedText:SetText("Not collected")
        notCollectedText:SetTextColor(0.6, 0.6, 0.6, 1)
        
        leftYOffset = leftYOffset - 22
    end
    
    -- Tradeable Section (Column 1) - Combined header and icon on single line
    leftYOffset = leftYOffset - 20  -- Add some spacing
    local tradeableFrame = leftColumn.tradeableFrame or CreateFrame("Frame", nil, leftColumn)
    leftColumn.tradeableFrame = tradeableFrame
    tradeableFrame:SetSize(leftWidth - 10, 25)
    tradeableFrame:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 5, leftYOffset)
    
    -- Tradeable text
    local tradeableHeader = tradeableFrame.header or tradeableFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    tradeableFrame.header = tradeableHeader
    tradeableHeader:SetPoint("LEFT", tradeableFrame, "LEFT", 0, 0)
    tradeableHeader:SetText("Tradeable")
    tradeableHeader:SetTextColor(1, 1, 1, 1)
    
    -- Tradeable icon on same line
    local tradeableIcon = tradeableFrame.icon or tradeableFrame:CreateTexture(nil, "ARTWORK")
    tradeableFrame.icon = tradeableIcon
    tradeableIcon:SetSize(16, 16)
    tradeableIcon:SetPoint("LEFT", tradeableHeader, "RIGHT", 8, 0)  -- Position next to text
    if isTradeable then
        tradeableIcon:SetTexture("Interface\\RaidFrame\\ReadyCheck-Ready")  -- Green checkmark
    else
        tradeableIcon:SetTexture("Interface\\RaidFrame\\ReadyCheck-NotReady")  -- Red X
    end
    
    -- Abilities Section (Column 1)
    leftYOffset = leftYOffset - 35  -- Reduced spacing since tradeable is now single line
    local abilitiesHeader = leftColumn.abilitiesHeader or leftColumn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    leftColumn.abilitiesHeader = abilitiesHeader
    abilitiesHeader:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 0, leftYOffset)
    abilitiesHeader:SetText("Abilities")
    abilitiesHeader:SetTextColor(1, 1, 1, 1)
    
    leftYOffset = leftYOffset - 25
    if abilities and #abilities > 0 then
        local abilitiesFrame = leftColumn.abilitiesFrame or CreateFrame("Frame", nil, leftColumn)
        leftColumn.abilitiesFrame = abilitiesFrame
        abilitiesFrame:SetSize(leftWidth - 10, 80)  -- 2 rows of 3 abilities
        abilitiesFrame:SetPoint("TOPLEFT", leftColumn, "TOPLEFT", 5, leftYOffset)
        
        -- Create ability icons (6 abilities, 2 rows of 3)
        for i = 1, math.min(6, #abilities) do
            local abilityFrame = abilitiesFrame["ability" .. i] or CreateFrame("Frame", nil, abilitiesFrame, "BackdropTemplate")
            abilitiesFrame["ability" .. i] = abilityFrame
            abilityFrame:SetSize(35, 35)
            
            local row = math.floor((i - 1) / 3)
            local col = (i - 1) % 3
            abilityFrame:SetPoint("TOPLEFT", abilitiesFrame, "TOPLEFT", col * 40, -(row * 40))
            
            abilityFrame:SetBackdrop({
                bgFile = "Interface\\Buttons\\WHITE8x8",
                edgeFile = "Interface\\Buttons\\WHITE8x8",
                edgeSize = 1
            })
            abilityFrame:SetBackdropColor(0, 0, 0, 0.8)
            abilityFrame:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
            
            local abilityIcon = abilityFrame.icon or abilityFrame:CreateTexture(nil, "ARTWORK")
            abilityFrame.icon = abilityIcon
            abilityIcon:SetSize(33, 33)
            abilityIcon:SetPoint("CENTER", abilityFrame, "CENTER", 0, 0)
            
            local abilityID = abilities[i]
            if abilityID then
                local _, _, abilityIconID = C_PetBattles.GetAbilityInfoByID(abilityID)
                if abilityIconID then
                    abilityIcon:SetTexture(abilityIconID)
                else
                    -- Fallback to pet icon if ability icon not found
                    abilityIcon:SetTexture(speciesIcon)
                end
                
                -- Add tooltip functionality
                abilityFrame:EnableMouse(true)
                abilityFrame:SetScript("OnEnter", function(self)
                    -- Use the FloatingPetBattleAbility_Show method for proper pet battle tooltips
                    if FloatingPetBattleAbility_Show then
                        -- Get pet stats for the ability tooltip (using level 25 stats)
                        local maxHealth, power, speed = 1000, 300, 300  -- Default fallback values
                        
                        -- Try to get actual pet stats if we have breed data
                        local breeds = GetPetBreeds(petData.speciesID)
                        if breeds and breeds[1] then
                            maxHealth = breeds[1].health or 1000
                            power = breeds[1].power or 300
                            speed = breeds[1].speed or 300
                        end
                        
                        -- Show the native Blizzard pet battle ability tooltip
                        FloatingPetBattleAbility_Show(abilityID, maxHealth, power, speed)
                        
                        -- Position the tooltip near our ability frame and customize it
                        if FloatingPetBattleAbilityTooltip then
                            FloatingPetBattleAbilityTooltip:ClearAllPoints()
                            FloatingPetBattleAbilityTooltip:SetPoint("LEFT", self, "RIGHT", 10, 0)
                            
                            -- Set 100% opacity
                            FloatingPetBattleAbilityTooltip:SetAlpha(1.0)
                            
                            -- Hide the close button (X)
                            if FloatingPetBattleAbilityTooltip.CloseButton then
                                FloatingPetBattleAbilityTooltip.CloseButton:Hide()
                            end
                        end
                    else
                        -- Fallback to GameTooltip if FloatingPetBattleAbility_Show is not available
                        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                        GameTooltip:SetFrameStrata("TOOLTIP")
                        GameTooltip:SetFrameLevel(9999)
                        
                        local name, icon, petType, noStrongWeakHints = C_PetBattles.GetAbilityInfoByID(abilityID)
                        if name then
                            GameTooltip:SetText(name, 1, 1, 1)
                            GameTooltip:AddLine("Ability ID: " .. abilityID, 0.8, 0.8, 0.8)
                        else
                            GameTooltip:SetText("Pet Ability " .. abilityID, 1, 1, 1)
                        end
                        GameTooltip:Show()
                    end
                end)
                
                abilityFrame:SetScript("OnLeave", function(self)
                    -- Hide both tooltip types
                    if FloatingPetBattleAbilityTooltip then
                        FloatingPetBattleAbilityTooltip:Hide()
                    end
                    GameTooltip:Hide()
                end)
            end
        end
    end
    
    -- RIGHT COLUMN CONTENT
    
    -- Stat Icons Header (Column 2) - Compacted layout
    local statIconsFrame = rightColumn.statIconsFrame or CreateFrame("Frame", nil, rightColumn)
    rightColumn.statIconsFrame = statIconsFrame
    statIconsFrame:SetSize(rightWidth - 10, 25)
    statIconsFrame:SetPoint("TOPLEFT", rightColumn, "TOPLEFT", 0, -10)
    
    -- Health Icon (Red) - Heart symbol
    local healthIcon = statIconsFrame.healthIcon or statIconsFrame:CreateTexture(nil, "ARTWORK")
    statIconsFrame.healthIcon = healthIcon
    healthIcon:SetSize(20, 20)
    healthIcon:SetPoint("CENTER", statIconsFrame, "LEFT", 55, 0)  -- Centered over health column
    healthIcon:SetTexture("Interface/Icons/PetBattle_Health")
    healthIcon:SetVertexColor(0.8, 0.2, 0.2, 1)  -- Red
    
    -- Power Icon (Orange) - Attack symbol
    local powerIcon = statIconsFrame.powerIcon or statIconsFrame:CreateTexture(nil, "ARTWORK")
    statIconsFrame.powerIcon = powerIcon
    powerIcon:SetSize(20, 20)
    powerIcon:SetPoint("CENTER", statIconsFrame, "LEFT", 100, 0)  -- Centered over power column
    powerIcon:SetTexture("Interface/Icons/PetBattle_Attack")
    powerIcon:SetVertexColor(0.8, 0.6, 0.2, 1)  -- Orange
    
    -- Speed Icon (Blue) - Speed symbol
    local speedIcon = statIconsFrame.speedIcon or statIconsFrame:CreateTexture(nil, "ARTWORK")
    statIconsFrame.speedIcon = speedIcon
    speedIcon:SetSize(20, 20)
    speedIcon:SetPoint("CENTER", statIconsFrame, "LEFT", 145, 0)  -- Centered over speed column
    speedIcon:SetTexture("Interface/Icons/PetBattle_Speed")
    speedIcon:SetVertexColor(0.2, 0.6, 0.8, 1)  -- Blue
    
    -- Breeds Table (Column 2)
    local breedsFrame = rightColumn.breedsFrame or CreateFrame("Frame", nil, rightColumn)
    rightColumn.breedsFrame = breedsFrame
    breedsFrame:SetSize(rightWidth - 10, 200)
    breedsFrame:SetPoint("TOPLEFT", statIconsFrame, "BOTTOMLEFT", 0, -10)
    
    -- Generate breed data and create table rows
    local breeds = GetPetBreeds(petData.speciesID)
    local rowHeight = 18
    local rightYOffset = 0
    
    -- Get user's collection data for breed comparison
    local collectionComparison = nil
    if PCLcore.CollectionComparison then
        collectionComparison = PCLcore.CollectionComparison:CompareSpeciesCollection(petData.speciesID)
    end
    
    -- Debug output (can be removed later)
    if PCL_SETTINGS and PCL_SETTINGS.debug then
        if #breeds > 0 then
            -- Found breeds for species
            if collectionComparison then
                -- User has X breeds of Y total breeds
            end
        else
            -- No breed data found for species
        end
    end
    
    -- If no breeds found, show a "No breed data" message
    if #breeds == 0 then
        local noDataText = breedsFrame.noDataText or breedsFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        breedsFrame.noDataText = noDataText
        noDataText:SetPoint("TOPLEFT", breedsFrame, "TOPLEFT", 0, -10)
        noDataText:SetText("No breed data available")
        noDataText:SetTextColor(0.6, 0.6, 0.6, 1)
        rightYOffset = rightYOffset - 25
    else
        -- Hide the no data text if breeds are found
        if breedsFrame.noDataText then
            breedsFrame.noDataText:Hide()
        end
    end
    
    for i, breedInfo in ipairs(breeds) do
        if i <= 10 then  -- Limit to reasonable number of breeds
            local rowFrame = breedsFrame["row" .. i] or CreateFrame("Frame", nil, breedsFrame)
            breedsFrame["row" .. i] = rowFrame
            rowFrame:SetSize(rightWidth - 20, rowHeight)
            rowFrame:SetPoint("TOPLEFT", breedsFrame, "TOPLEFT", 0, rightYOffset)
            
            -- Determine if user has this breed
            local hasThisBreed = false
            local breedCount = 0
            if collectionComparison and collectionComparison.isCollected then
                for _, ownedBreed in ipairs(collectionComparison.ownedBreeds) do
                    if ownedBreed.breedID == breedInfo.breedID then
                        hasThisBreed = true
                        breedCount = ownedBreed.count or 1
                        break
                    end
                end
            end
            
            -- Collection status indicator
            local statusIcon = rowFrame.statusIcon or rowFrame:CreateTexture(nil, "OVERLAY")
            rowFrame.statusIcon = statusIcon
            statusIcon:SetSize(12, 12)
            statusIcon:SetPoint("LEFT", rowFrame, "LEFT", -18, 0)
            
            if not collectionComparison or not collectionComparison.isCollected then
                -- Pet not collected at all - gray X
                statusIcon:SetTexture("Interface\\RaidFrame\\ReadyCheck-NotReady")
                statusIcon:SetVertexColor(0.5, 0.5, 0.5, 1)
            elseif hasThisBreed then
                -- User has this breed - green checkmark
                statusIcon:SetTexture("Interface\\RaidFrame\\ReadyCheck-Ready")
                statusIcon:SetVertexColor(0, 1, 0, 1)
            else
                -- User has pet but missing this breed - red X
                statusIcon:SetTexture("Interface\\RaidFrame\\ReadyCheck-NotReady")
                statusIcon:SetVertexColor(1, 0, 0, 1)
            end
            statusIcon:Show()
            
            -- Breed name (H/H, B/B, P/P, etc.) with collection count if owned
            local breedName = rowFrame.breedName or rowFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            rowFrame.breedName = breedName
            breedName:SetPoint("LEFT", rowFrame, "LEFT", 0, 0)
            
            local breedText = breedInfo.breedCode or "B/B"
            if hasThisBreed and breedCount > 1 then
                breedText = breedText .. " (" .. breedCount .. ")"
            end
            breedName:SetText(breedText)
            
            -- Color the breed name based on collection status
            if not collectionComparison or not collectionComparison.isCollected then
                breedName:SetTextColor(0.5, 0.5, 0.5, 1) -- Gray for uncollected pet
            elseif hasThisBreed then
                breedName:SetTextColor(0, 1, 0, 1) -- Green for owned breed
            else
                breedName:SetTextColor(1, 0.4, 0.4, 1) -- Light red for missing breed
            end
            
            -- Health stat (aligned under health icon) - Compacted layout
            local healthStat = rowFrame.healthStat or rowFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            rowFrame.healthStat = healthStat
            healthStat:SetPoint("LEFT", rowFrame, "LEFT", 35, 0)  -- Aligned with new health icon position
            healthStat:SetText(tostring(breedInfo.health or 1481))
            healthStat:SetTextColor(1, 1, 1, 1)
            healthStat:SetJustifyH("CENTER")
            healthStat:SetWidth(40)  -- Narrower width
            
            -- Power stat (aligned under power icon) - Compacted layout  
            local powerStat = rowFrame.powerStat or rowFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            rowFrame.powerStat = powerStat
            powerStat:SetPoint("LEFT", rowFrame, "LEFT", 80, 0)  -- Closer spacing
            powerStat:SetText(tostring(breedInfo.power or 276))
            powerStat:SetTextColor(1, 1, 1, 1)
            powerStat:SetJustifyH("CENTER")
            powerStat:SetWidth(40)  -- Narrower width
            
            -- Speed stat (aligned under speed icon) - Compacted layout
            local speedStat = rowFrame.speedStat or rowFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            rowFrame.speedStat = speedStat
            speedStat:SetPoint("LEFT", rowFrame, "LEFT", 125, 0)  -- Closer spacing
            speedStat:SetText(tostring(breedInfo.speed or 276))
            speedStat:SetTextColor(1, 1, 1, 1)
            speedStat:SetJustifyH("CENTER")
            speedStat:SetWidth(40)  -- Narrower width
            
            rightYOffset = rightYOffset - rowHeight
        end
    end
    
    -- Calculate final content height
    local finalMainHeight = math.max(math.abs(leftYOffset) + 80, math.abs(rightYOffset) + 50)
    mainFrame:SetHeight(finalMainHeight)
    
    yOffset = yOffset - finalMainHeight - 20
    contentHeight = contentHeight + finalMainHeight + 20
    
    -- Source section already positioned after model frame - removed duplicate
    -- Description section already positioned after model frame - removed duplicate
    
    -- Update scroll child height
    PCL_PetCard.scrollChild:SetHeight(contentHeight + 20)
end

--[[
  Show the pet card
]]
function PetCard:Show(petData)
    
    if not PCL_mainFrame then
        return
    end
    
    if not petData then
        return
    end
    
    
    -- Create or get the pet card frame
    if not PCL_PetCard then
        self:CreatePetCard()
    end
    
    -- Position the pet card to the right of the main window
    PCL_PetCard:ClearAllPoints()
    PCL_PetCard:SetPoint("TOPLEFT", PCL_mainFrame, "TOPRIGHT", 5, 0)  -- 5 pixels gap to the right
    
    -- Match the height of the main window
    local mainHeight = PCL_mainFrame:GetHeight()
    PCL_PetCard:SetHeight(mainHeight)
    
    -- Update the pet card content
    self:UpdateWindow(petData)
    
    -- Show the pet card
    PCL_PetCard:Show()
end

--[[
  Hide the pet card
]]
function PetCard:Hide()
    if PCL_PetCard then
        PCL_PetCard:Hide()
    end
    -- Also hide fullscreen if it's open
    if PCL_PetCard_Fullscreen then
        PCL_PetCard_Fullscreen:Hide()
    end
end

--[[
  Show pet card in fullscreen mode
]]
function PetCard:ShowFullscreen(petData)
    if not petData then
        return
    end
    
    -- Create fullscreen frame if it doesn't exist
    if not PCL_PetCard_Fullscreen then
        PCL_PetCard_Fullscreen = CreateFrame("Frame", "PCL_PetCard_Fullscreen", UIParent, "BackdropTemplate")
        PCL_PetCard_Fullscreen:SetSize(UIParent:GetWidth() * 0.8, UIParent:GetHeight() * 0.8)
        PCL_PetCard_Fullscreen:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
        PCL_PetCard_Fullscreen:SetFrameStrata("DIALOG")
        PCL_PetCard_Fullscreen:EnableMouse(true)
        PCL_PetCard_Fullscreen:SetMovable(true)
        PCL_PetCard_Fullscreen:RegisterForDrag("LeftButton")
        PCL_PetCard_Fullscreen:SetScript("OnDragStart", function(self) self:StartMoving() end)
        PCL_PetCard_Fullscreen:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end)
        
        -- Backdrop styling
        PCL_PetCard_Fullscreen:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 8,
            insets = {left = 8, right = 8, top = 8, bottom = 8}
        })
        PCL_PetCard_Fullscreen:SetBackdropColor(0.05, 0.05, 0.05, 0.95)
        PCL_PetCard_Fullscreen:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
        
        -- Title bar
        local titleFrame = CreateFrame("Frame", nil, PCL_PetCard_Fullscreen, "BackdropTemplate")
        PCL_PetCard_Fullscreen.titleFrame = titleFrame
        titleFrame:SetHeight(30)
        titleFrame:SetPoint("TOPLEFT", PCL_PetCard_Fullscreen, "TOPLEFT", 8, -8)
        titleFrame:SetPoint("TOPRIGHT", PCL_PetCard_Fullscreen, "TOPRIGHT", -8, -8)
        titleFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8"
        })
        titleFrame:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
        
        -- Title text
        local titleText = titleFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        PCL_PetCard_Fullscreen.titleText = titleText
        titleText:SetPoint("LEFT", titleFrame, "LEFT", 10, 0)
        titleText:SetText("Pet Details - Fullscreen View")
        titleText:SetTextColor(1, 0.82, 0, 1)
        
        -- Close button
        local closeButton = CreateFrame("Button", nil, titleFrame, "UIPanelCloseButton")
        PCL_PetCard_Fullscreen.closeButton = closeButton
        closeButton:SetPoint("RIGHT", titleFrame, "RIGHT", -5, 0)
        closeButton:SetScript("OnClick", function(self)
            PCL_PetCard_Fullscreen:Hide()
        end)
        
        -- Large model frame
        local modelFrame = CreateFrame("Frame", nil, PCL_PetCard_Fullscreen, "BackdropTemplate")
        PCL_PetCard_Fullscreen.modelFrame = modelFrame
        modelFrame:SetPoint("TOPLEFT", titleFrame, "BOTTOMLEFT", 10, -10)
        modelFrame:SetPoint("BOTTOMRIGHT", PCL_PetCard_Fullscreen, "BOTTOMRIGHT", -10, 10)
        modelFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8x8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 4,
            insets = {left = 4, right = 4, top = 4, bottom = 4}
        })
        modelFrame:SetBackdropColor(0.08, 0.08, 0.08, 0.95)
        modelFrame:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
        
        -- Large 3D model
        local petModel = CreateFrame("PlayerModel", nil, modelFrame)
        PCL_PetCard_Fullscreen.petModel = petModel
        petModel:SetPoint("TOPLEFT", modelFrame, "TOPLEFT", 4, -4)
        petModel:SetPoint("BOTTOMRIGHT", modelFrame, "BOTTOMRIGHT", -4, 4)
        
        -- Enhanced camera controls for fullscreen
        petModel:EnableMouse(true)
        petModel:SetScript("OnMouseWheel", function(self, delta)
            -- Use SetCamDistanceScale for PlayerModel frames
            local currentScale = self.cameraScale or 2.0
            currentScale = currentScale - (delta * 0.3)  -- More sensitive in fullscreen
            currentScale = math.max(0.2, math.min(8.0, currentScale))  -- Wider zoom range for fullscreen
            self:SetCamDistanceScale(currentScale)
            self.cameraScale = currentScale  -- Store current scale
        end)
        
        -- Enhanced rotation controls
        petModel:SetScript("OnMouseDown", function(self, button)
            if button == "LeftButton" then
                self.isRotating = true
                self.startX, self.startY = GetCursorPosition()
            elseif button == "RightButton" then
                self.isPanning = true
                self.startX, self.startY = GetCursorPosition()
            end
        end)
        
        petModel:SetScript("OnMouseUp", function(self, button)
            if button == "LeftButton" then
                self.isRotating = false
            elseif button == "RightButton" then
                self.isPanning = false
            end
        end)
        
        petModel:SetScript("OnUpdate", function(self)
            if self.isRotating then
                local currentX, currentY = GetCursorPosition()
                if self.startX and self.startY then
                    local deltaX = (currentX - self.startX) * 0.01
                    local deltaY = (currentY - self.startY) * 0.01
                    
                    local currentRotation = self.currentRotation or 0.3
                    local currentPitch = self.currentPitch or 0
                    
                    currentRotation = currentRotation + deltaX
                    currentPitch = math.max(-1.5, math.min(1.5, currentPitch + deltaY))
                    
                    self:SetRotation(currentRotation)
                    self:SetModelScale(1)  -- Reset scale to apply pitch
                    
                    self.currentRotation = currentRotation
                    self.currentPitch = currentPitch
                    self.startX, self.startY = currentX, currentY
                end
            end
        end)
        
        -- Instructions text
        local instructionsText = modelFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        PCL_PetCard_Fullscreen.instructionsText = instructionsText
        instructionsText:SetPoint("BOTTOMLEFT", modelFrame, "BOTTOMLEFT", 10, 10)
        instructionsText:SetText("Mouse wheel: Zoom | Left click + drag: Rotate | Drag title bar: Move window")
        instructionsText:SetTextColor(0.7, 0.7, 0.7, 1)
    end
    
    -- Update the pet model in fullscreen
    local speciesName, speciesIcon, petType, companionID = C_PetJournal.GetPetInfoBySpeciesID(petData.speciesID)
    PCL_PetCard_Fullscreen.titleText:SetText((speciesName or "Unknown Pet") .. " - Fullscreen View")
    
    if PCL_PetCard_Fullscreen.petModel and companionID and companionID > 0 then
        local success = pcall(function()
            PCL_PetCard_Fullscreen.petModel:SetCreature(companionID)
        end)
        
        if success then
            PCL_PetCard_Fullscreen.petModel:Show()
            C_Timer.After(0.1, function()
                if PCL_PetCard_Fullscreen.petModel then
                    PCL_PetCard_Fullscreen.petModel:SetCamDistanceScale(2.0)  -- Start zoomed out a bit more
                    PCL_PetCard_Fullscreen.petModel:SetRotation(0.3)
                    PCL_PetCard_Fullscreen.petModel.currentRotation = 0.3
                    PCL_PetCard_Fullscreen.petModel.currentPitch = 0
                    if PCL_PetCard_Fullscreen.petModel.RefreshCamera then
                        PCL_PetCard_Fullscreen.petModel:RefreshCamera()
                    end
                end
            end)
        end
    end
    
    PCL_PetCard_Fullscreen:Show()
end

--[[
  Check if pet card is shown
]]
function PetCard:IsShown()
    return PCL_PetCard and PCL_PetCard:IsShown()
end

--[[
  Show pet card as hover tooltip (positioned relative to anchor frame)
]]
function PetCard:ShowAsTooltip(petSpeciesID, anchorFrame)
    if not petSpeciesID or not anchorFrame then
        return
    end
    
    -- Cancel any pending hide timer
    if hoverTimer then
        hoverTimer:Cancel()
        hoverTimer = nil
    end
    
    -- Store current hover state
    currentHoveredPet = petSpeciesID
    currentAnchorFrame = anchorFrame
    
    
    -- If this is the same pet that's already showing, don't recreate it
    if PCL_PetCard and PCL_PetCard:IsShown() and PCL_PetCard.currentSpeciesID == petSpeciesID then
        return
    end
    
    -- Create pet data structure using actual source information
    local speciesName, speciesIcon, petType, companionID, tooltipSource, tooltipDescription, isWild, canBattle, isTradeable, isUnique, obtainable = C_PetJournal.GetPetInfoBySpeciesID(petSpeciesID)
    
    local petData = {
        speciesID = petSpeciesID,
        source = tooltipSource or "Unknown source",
        description = tooltipDescription,
        zone = "Various locations"  -- This could be enhanced with actual zone data if available
    }
    
    -- Create or update the pet card
    if not PCL_PetCard then
        self:CreatePetCard()
    end
    
    -- Store the anchor frame and species ID for potential pinning
    if PCL_PetCard then
        PCL_PetCard.currentAnchorFrame = anchorFrame
        PCL_PetCard.currentSpeciesID = petSpeciesID
        PCL_PetCard.isPinned = false  -- Reset pinned state for hover
        
        -- Update with pet data
        self:UpdateWindow(petData)
    end
    
    -- Position relative to the anchor frame (more centrally positioned)
    PCL_PetCard:ClearAllPoints()
    
    -- Try to center the card next to the anchor frame, slightly offset
    -- This positions it to the right of the anchor, but more vertically centered
    PCL_PetCard:SetPoint("LEFT", anchorFrame, "RIGHT", 15, 0)
    
    -- Make sure it stays on screen with better positioning logic
    local screenWidth = GetScreenWidth()
    local screenHeight = GetScreenHeight()
    local frameRight = PCL_PetCard:GetRight()
    local frameLeft = PCL_PetCard:GetLeft()
    local frameTop = PCL_PetCard:GetTop()
    local frameBottom = PCL_PetCard:GetBottom()
    
    -- If the frame goes off the right side of screen, position it to the left of anchor
    if frameRight and frameRight > screenWidth then
        PCL_PetCard:ClearAllPoints()
        PCL_PetCard:SetPoint("RIGHT", anchorFrame, "LEFT", -15, 0)
    end
    
    -- If the frame goes off the top of screen, adjust vertically
    if frameTop and frameTop > screenHeight then
        PCL_PetCard:ClearAllPoints()
        if frameRight and frameRight > screenWidth then
            PCL_PetCard:SetPoint("BOTTOMRIGHT", anchorFrame, "BOTTOMLEFT", -15, -50)
        else
            PCL_PetCard:SetPoint("BOTTOMLEFT", anchorFrame, "BOTTOMRIGHT", 15, -50)
        end
    end
    
    -- If the frame goes off the bottom of screen, adjust vertically upward
    if frameBottom and frameBottom < 0 then
        PCL_PetCard:ClearAllPoints()
        if frameRight and frameRight > screenWidth then
            PCL_PetCard:SetPoint("TOPRIGHT", anchorFrame, "TOPLEFT", -15, 50)
        else
            PCL_PetCard:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 15, 50)
        end
    end
    
    -- Set appropriate frame strata for tooltip behavior
    PCL_PetCard:SetFrameStrata("TOOLTIP")
    PCL_PetCard:SetFrameLevel(1000)
    
    -- Remove click functionality from the PetCard itself for hover tooltips
    PCL_PetCard:SetScript("OnMouseDown", nil)
    
    -- Show the frame
    PCL_PetCard:Show()
end


--[[
  Test the pet card with a sample pet
]]
function PetCard:Test()
    local sampleData = {
        speciesID = 39,  -- Mechanical Squirrel
        source = "Engineering",
        zone = "Various locations"
    }
    self:Show(sampleData)
end

--[[
  Test breed data functionality
]]
function PetCard:TestBreedData(speciesID)
    speciesID = speciesID or 40  -- Default to Westfall Chicken
    
    -- PCL Breed Data Test
    
    -- Check if breed data is loaded
    if not PCLcore.breedData then
        -- ERROR: PCLcore.breedData is not loaded
        return
    end
    
    if not PCLcore.breedData.species then
        -- ERROR: PCLcore.breedData.species is not loaded
        return
    end
    
    -- Check if this species has breed data
    local speciesData = PCLcore.breedData.species[speciesID]
    if not speciesData then
        -- No breed data found for species
        return
    end
    
    -- Species has X available breeds
    
    -- Test the breed functions
    local breeds = GetPetBreeds(speciesID)
    if #breeds > 0 then
        -- Breed calculation successful
        for i, breed in ipairs(breeds) do
            -- Breed info processed
        end
    else
        -- No breeds calculated (possible issue with breed calculation)
    end
    
    -- Test breed helper functions
    for _, breedID in ipairs(speciesData.breeds) do
        local breedName = PCLcore.GetBreedName(breedID)
        local modifiers = PCLcore.GetBreedModifiers(breedID)
        if modifiers then
            -- Breed modifier data processed
        end
    end
end

-- Export the PetCard module
PCLcore.PetCard = PetCard;

-- Add a test slash command
SLASH_PCLPETCARD1 = "/pcltest"
SlashCmdList["PCLPETCARD"] = function(msg)
    local speciesID = tonumber(msg)
    if not speciesID then
        speciesID = 39 -- Default to Mechanical Squirrel if no ID provided
    end
    
    -- Create simple pet data structure that the new UpdateWindow expects
    local petData = {
        speciesID = speciesID,
        source = "Test Source",
        zone = "Test Zone"
    }
    
    -- Show the pet card
    PetCard:Show(petData)
end

-- Add breed testing slash command
SLASH_PCLBREEDTEST1 = "/pclbreeds"
SlashCmdList["PCLBREEDTEST"] = function(msg)
    local speciesID = tonumber(msg)
    if not speciesID then
        speciesID = 39  -- Default to Mechanical Squirrel for testing
    end
    
    PetCard:TestBreedData(speciesID)
end

-- Add model variations testing slash command
SLASH_PCLMODELTEST1 = "/pclmodels"
SlashCmdList["PCLMODELTEST"] = function(msg)
    local speciesID = tonumber(msg)
    if not speciesID then
        speciesID = 4533  -- Meek Bloodlasher - has multiple variants
    end
    
    print("Testing model variations for species ID:", speciesID)
    
    -- Check if model variations data is loaded
    if not PCLcore or not PCLcore.PetModelVariations then
        print("ERROR: PCLcore.PetModelVariations not loaded")
        return
    end
    
    local variations = PCLcore.PetModelVariations[speciesID]
    if not variations then
        print("No model variations found for species", speciesID)
        return
    end
    
    print("Found model variations for species", speciesID)
    print("NPC ID:", variations.npc_id)
    print("Number of variation sets:", #variations.variations)
    
    for i, variation in ipairs(variations.variations) do
        print(string.format("  Variation %d: %s", i, variation.name or "Unnamed"))
        if variation.displays then
            for j, display in ipairs(variation.displays) do
                print(string.format("    Display %d: ID=%s, Probability=%.1f%%", 
                      j, display.id, display.probability))
            end
        end
    end
    
    -- Create simple pet data structure and show the card
    local petData = {
        speciesID = speciesID,
        source = "Model Variation Test",
        zone = "Test Zone"
    }
    
    -- Show the pet card to test the tab system
    PetCard:Show(petData)
end

-- Test comparison system command
SLASH_PCLTESTCOMPARE1 = "/pcltestcompare"
SlashCmdList["PCLTESTCOMPARE"] = function(msg)
    local speciesID = tonumber(msg)
    if not speciesID then
        speciesID = 39  -- Default to Mechanical Squirrel for testing
    end
    
    -- Testing Collection Comparison for Species
    
    if not PCLcore.CollectionComparison then
        -- Error: PCLcore.CollectionComparison not loaded
        return
    end
    
    local comparison = PCLcore.CollectionComparison:CompareSpeciesCollection(speciesID)
    
    -- Species and collection data processed
    
    if comparison.isCollected then
        -- Collection data processed
        
        if #comparison.ownedBreeds > 0 then
            local ownedText = ""
            for i, breed in ipairs(comparison.ownedBreeds) do
                if i > 1 then ownedText = ownedText .. ", " end
                ownedText = ownedText .. breed.breedLetters
                if breed.count > 1 then
                    ownedText = ownedText .. " (" .. breed.count .. ")"
                end
            end
            -- Owned breeds processed
        end
        
        if #comparison.missingBreeds > 0 then
            local missingText = ""
            for i, breed in ipairs(comparison.missingBreeds) do
                if i > 1 then missingText = missingText .. ", " end
                missingText = missingText .. breed.breedLetters
            end
            -- Missing breeds processed
        end
    end
end

-- PetCollector compatibility - safe interface that avoids DISPLAY global conflicts
PCLcore.PetCard.Display.Show = function(pet, locationIdx)
    if PetCard and PetCard.Show then
        PetCard:Show(pet, locationIdx)
    end
end

-- Alternative access method for PetCollector compatibility
_G["PCL_PetCard_Show"] = PCLcore.PetCard.Display.Show



-- * ------------------------------------------------------
-- * Variables
-- * ------------------------------------------------------
MCLcore.Main = {};
local MCL_Load = MCLcore.Main;
local init_load = true
local load_check = 0
local region = GetCVar('portal')


-- * -------------------------------------------------
-- * Initialise Database
-- * Cycles through data.lua, checks if in game mount journal has an entry for mount. Restarts function if mount does is not loaded yet.
-- * Function is designed to check if the ingame mount journal has loaded correctly before loading our own database.
-- * -----------------------------------------------

function IsRegionalFiltered(id)
    if MCLcore.regionalFilter[region] ~= nil then
        for k, v in pairs(MCLcore.regionalFilter[region]) do
            if v == id then
                return true
            end
        end
    end
    return false
end

function CountMounts()
    MCLcore.mountList = MCLcore.mountList or {}
    local count = 0
    for b, n in pairs(MCLcore.mountList) do
        if type(n) == "table" then
            for h, j in pairs(n) do
                if type(j) == "table" then
                    for k, v in pairs(j) do
                        -- Ensure v.mounts is a table before attempting to iterate over it
                        if type(v.mounts) == "table" then
                            for kk, vv in pairs(v.mounts) do
                                count = count + 1
                            end
                        end
                    end
                end
            end
        end
    end
    return count
end

-- Global for Addon Compartment
MCL_OnAddonCompartmentClick = function()
    MCL_Load:Toggle()
end

-- Save total mount count
local totalMountCount = CountMounts()

local function InitMounts()
    load_check = 0
    totalMountCount = 0
    for b,n in pairs(MCLcore.mountList) do
        for h,j in pairs(n) do
            if (type(j) == "table") then
                for k,v in pairs(j) do
                    for kk,vv in pairs(v.mounts) do
                        if not IsRegionalFiltered(vv) then
                            if not string.match(vv, "^m") then
                                totalMountCount = totalMountCount + 1
                                C_Item.RequestLoadItemDataByID(vv)
                                local mountName = C_MountJournal.GetMountFromItem(vv)
                                if mountName ~= nil then
                                    load_check = load_check + 1
                                end                            
                            end
                        end                                     
                    end
                end
            end
        end
    end
end


-- * -----------------------------------------------------
-- * Toggle the main window
-- * -----------------------------------------------------


MCLcore.dataLoaded = false

function MCL_Load:PreLoad()      
    if load_check >= totalMountCount then
        MCLcore.dataLoaded = true
        return true
    else   
        InitMounts()         
        return false
    end
end

-- Set a maximum number of initialization retries
local MAX_INIT_RETRIES = 3

-- Initialization function
function MCL_Load:Init(force)
    local function repeatCheck()
        local retries = 0
        if MCL_Load:PreLoad() then
            -- Initialization steps
            if MCLcore.MCL_MF == nil then
                -- Ensure Frames module is available
                if not MCLcore.Frames then
                    return false
                end
                MCLcore.MCL_MF = MCLcore.Frames:CreateMainFrame()
                MCLcore.MCL_MF:SetShown(false)
                
                -- Ensure Function module is available before calling methods
                if MCLcore.Function and MCLcore.Function.initSections then
                    MCLcore.Function:initSections()
                end
                
                -- Clean up any invalid pinned mounts during initialization
                if MCLcore.Function and MCLcore.Function.CleanupInvalidPinnedMounts then
                    MCLcore.Function:CleanupInvalidPinnedMounts()
                end
            end
            
            -- Ensure Function module is available before updating collection
            if MCLcore.Function and MCLcore.Function.UpdateCollection then
                MCLcore.Function:UpdateCollection()
            end
            init_load = false -- Ensure that the initialization does not repeat unnecessarily.
        else
            retries = retries + 1
            if retries < MAX_INIT_RETRIES then
                -- Retry the initialization process after a delay
                C_Timer.After(1, repeatCheck)
            end
        end
    end

    -- Force reinitialization if specifically requested
    if force then
        load_check = 0
        MCLcore.dataLoaded = false
    end

    -- Check if we need to attempt initialization
    if not MCLcore.dataLoaded then
        init_load = true
        repeatCheck()
    end
end

-- Toggle function
function MCL_Load:Toggle()
    -- Check preload status and if false, prevent execution.
    if MCLcore.dataLoaded == false then
        MCL_Load:Init()
        return
    end 
    if MCLcore.MCL_MF == nil then
        return -- Immune to function calls before the initialization process is complete, as the frame doesn't exist yet.
    else
        MCLcore.MCL_MF:SetShown(not MCLcore.MCL_MF:IsShown()) -- The addon's frame exists and can be toggled.
    end
end

local f = CreateFrame("Frame")
local login = true



-- * -------------------------------------------------
-- * Loads addon once Blizzard_Collections has loaded in.
-- * -------------------------------------------------


local function onevent(self, event, arg1, ...)
    if(login and ((event == "ADDON_LOADED" and name == arg1) or (event == "PLAYER_LOGIN"))) then
        login = nil
        f:UnregisterEvent("ADDON_LOADED")
        f:UnregisterEvent("PLAYER_LOGIN")
	    if not C_AddOns.IsAddOnLoaded("Blizzard_Collections") then
	        C_AddOns.LoadAddOn("Blizzard_Collections")
	    end
        
        -- Ensure Function module is available before calling AddonSettings
        if MCLcore.Function and MCLcore.Function.AddonSettings then
            MCLcore.Function:AddonSettings()
        end
        
        -- Initiate the addon when the required addon is loaded
        MCL_Load:Init()
        
        -- Initialize search functionality
        if MCLcore.InitializeSearch then
            MCLcore.InitializeSearch()
        end
        
        -- Initialize MountCard functionality
        if MCLcore.MountCard then
            MCLcore.MountCard:CreateMountCard()
        end
    end
end


-- function addon:MCL_MM() self.db.profile.minimap.hide = not self.db.profile.minimap.hide if self.db.profile.minimap.hide then icon:Hide("MCL-icon") else icon:Show("MCL-icon") end end
f:RegisterEvent("ADDON_LOADED")
f:RegisterEvent("PLAYER_LOGIN")
f:SetScript("OnEvent", onevent)


local _, MCLcore = ...;

-- Initialize search functionality when the addon loads
local function InitializeSearch()
    if not MCLcore.Search then
        -- Search functionality namespace
        MCLcore.Search = {}

        -- Search state
        MCLcore.Search.searchResults = {}
        MCLcore.Search.currentSearchTerm = ""
        MCLcore.Search.isSearchActive = false

        -- Search functionality
        function MCLcore.Search:PerformSearch(searchTerm)
            if not searchTerm or searchTerm == "" then
                self:ClearSearch()
                return
            end
            
            -- Remove leading and trailing whitespace
            searchTerm = searchTerm:gsub("^%s*(.-)%s*$", "%1")
            if searchTerm == "" then
                self:ClearSearch()
                return
            end
            
            self.currentSearchTerm = searchTerm:lower()
            self.isSearchActive = true
            self.searchResults = {}
            
            -- Search through all mounts in all sections
            for sectionIndex, section in ipairs(MCLcore.sectionNames) do
                if section.mounts then
                    -- Handle different mount data structures
                    local categories = section.mounts.categories or section.mounts
                    if categories then
                        for categoryName, categoryData in pairs(categories) do
                            if type(categoryData) == "table" then
                                -- Combine both mounts and mountID arrays for search
                                local mountList = {}
                                if categoryData.mounts then
                                    for _, mount in ipairs(categoryData.mounts) do
                                        table.insert(mountList, mount)
                                    end
                                end
                                if categoryData.mountID then
                                    for _, mount in ipairs(categoryData.mountID) do
                                        table.insert(mountList, mount)
                                    end
                                end
                                
                                for _, mountId in ipairs(mountList) do
                                    local mount_Id = MCLcore.Function:GetMountID(mountId)
                                    if mount_Id then
                                        local mountName, spellID, icon = C_MountJournal.GetMountInfoByID(mount_Id)
                                        local isCollected = IsMountCollected(mount_Id)
                                        
                                        -- Skip collected mounts if the setting is enabled
                                        if MCL_SETTINGS.hideCollectedMounts and isCollected then
                                            -- Skip this mount entirely
                                        else
                                            -- Search both mount name and item name (if applicable)
                                            local matchFound = false
                                            local matchedName = nil
                                            local searchTerm = self.currentSearchTerm
                                            
                                            -- Check mount name
                                            if mountName and mountName:lower():find(searchTerm, 1, true) then
                                                matchFound = true
                                                matchedName = mountName
                                            end
                                            
                                            -- If mount has an item ID, also check the item name
                                            if not matchFound and type(mountId) == "number" then
                                                local itemName = GetItemInfo(mountId)
                                                if itemName and itemName:lower():find(searchTerm, 1, true) then
                                                    matchFound = true
                                                    matchedName = itemName
                                                end
                                            end
                                            
                                            if matchFound then
                                                table.insert(self.searchResults, {
                                                    mountId = mountId,
                                                    mountName = mountName,
                                                    matchedName = matchedName,
                                                    icon = icon,
                                                    spellID = spellID,
                                                    section = section.name,
                                                    category = categoryData.name or categoryName,
                                                    isCollected = isCollected
                                                })
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            
            -- Display search results
            self:DisplaySearchResults()
        end        function MCLcore.Search:ClearSearch()
            self.currentSearchTerm = ""
            self.isSearchActive = false
            self.searchResults = {}
            
            -- Clear any highlighting
            self:ClearHighlighting()
            
            -- Properly destroy search results content frame
            self:DestroySearchResultsFrame()
            
            -- Clear search text in navigation frame
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.searchBox then
                MCLcore.MCL_MF_Nav.searchBox:SetText("")
                if MCLcore.MCL_MF_Nav.searchPlaceholder then
                    MCLcore.MCL_MF_Nav.searchPlaceholder:Show()
                end
            end
            
            -- Restore the previously selected tab using the proper SelectTab function
            if self.previouslySelectedTab then
                -- We need to call the SelectTab function from frames.lua
                -- Since it's local, we'll replicate its logic here
                if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                    -- Deselect all tabs first
                    for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                        if t.SetBackdropBorderColor then
                            t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                        end
                    end
                    -- Hide all tab contents
                    for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                        if t.content then
                            t.content:Hide()
                        end
                    end
                    -- Restore the selected tab
                    if self.previouslySelectedTab.SetBackdropBorderColor then
                        self.previouslySelectedTab:SetBackdropBorderColor(1, 0.82, 0, 1)
                    end
                    if self.previouslySelectedTab.content and MCL_mainFrame.ScrollFrame then
                        -- Always keep the main scroll child as the scroll child
                        MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                        self.previouslySelectedTab.content:Show()
                        MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
                    end
                    -- Update global reference
                    MCLcore.currentlySelectedTab = self.previouslySelectedTab
                end
                self.previouslySelectedTab = nil
            end
        end

        function MCLcore.Search:ClearSearchAndGoToOverview()
            self.currentSearchTerm = ""
            self.isSearchActive = false
            self.searchResults = {}
            
            -- Clear any highlighting
            self:ClearHighlighting()
            
            -- Properly destroy search results content frame
            self:DestroySearchResultsFrame()
            
            -- Clear search text in navigation frame
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.searchBox then
                MCLcore.MCL_MF_Nav.searchBox:SetText("")
                if MCLcore.MCL_MF_Nav.searchPlaceholder then
                    MCLcore.MCL_MF_Nav.searchPlaceholder:Show()
                end
            end
            
            -- Always go to Overview tab regardless of previous selection
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                -- Find the Overview tab (should be the first one)
                local overviewTab = nil
                for _, tab in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                    if tab.section and tab.section.name == "Overview" then
                        overviewTab = tab
                        break
                    end
                end
                
                if overviewTab then
                    -- Deselect all tabs first
                    for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                        if t.SetBackdropBorderColor then
                            t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                        end
                    end
                    -- Hide all tab contents using the proper HideAllTabContents function
                    if MCLcore.HideAllTabContents then
                        MCLcore.HideAllTabContents()
                    else
                        -- Fallback: Hide all tab contents manually
                        for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                            if t.content then
                                t.content:Hide()
                            end
                        end
                    end
                    -- Select the Overview tab
                    if overviewTab.SetBackdropBorderColor then
                        overviewTab:SetBackdropBorderColor(1, 0.82, 0, 1)
                    end
                    if overviewTab.content and MCL_mainFrame.ScrollFrame then
                        -- Always keep the main scroll child as the scroll child
                        MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                        overviewTab.content:Show()
                        MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
                    end
                    -- Update global reference
                    MCLcore.currentlySelectedTab = overviewTab
                end
            end
            
            -- Clear the previously selected tab since we're defaulting to Overview
            self.previouslySelectedTab = nil
        end
        function MCLcore.Search:DisplaySearchResults()
            if not MCL_mainFrame then return end
            
            -- Store the currently selected tab so we can restore it later
            if MCLcore.currentlySelectedTab and not self.previouslySelectedTab then
                self.previouslySelectedTab = MCLcore.currentlySelectedTab
            end
            
            -- Hide all tab contents first
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                    if t.content then
                        t.content:Hide()
                    end
                end
                -- Deselect all tabs visually
                for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                    if t.SetBackdropBorderColor then
                        t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                    end
                end
            end
            
            -- Hide all section frames that might be stored globally
            if MCLcore.sectionFrames then
                for _, contentFrame in ipairs(MCLcore.sectionFrames) do
                    if contentFrame and contentFrame.Hide then
                        contentFrame:Hide()
                    end
                end
            end
            
            -- Hide overview frame specifically
            if MCLcore.overview then
                MCLcore.overview:Hide()
            end
            
            -- Create or get search results content frame
            if not MCLcore.searchResultsContent then
                MCLcore.searchResultsContent = MCLcore.Frames:createContentFrame(MCL_mainFrame.ScrollChild, "Search Results")
                -- Ensure search results content is properly layered
                MCLcore.searchResultsContent:SetFrameStrata("MEDIUM")
                MCLcore.searchResultsContent:SetFrameLevel(10)
            end
            
            -- Update search results content
            self:UpdateSearchResultsContent()
            
            -- Show search results in main frame
            if MCL_mainFrame.ScrollFrame then
                -- Always keep the main scroll child as the scroll child
                MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                MCLcore.searchResultsContent:Show()
                MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
            end
        end        function MCLcore.Search:UpdateSearchResultsContent()
            if not MCLcore.searchResultsContent then return end
            
            local content = MCLcore.searchResultsContent
            
            -- Clear existing content more thoroughly
            -- First hide and remove all children except the title
            for i = content:GetNumChildren(), 1, -1 do
                local child = select(i, content:GetChildren())
                if child and child ~= content.title then
                    child:Hide()
                    child:SetParent(nil)
                end
            end
            
            -- Also clear any FontStrings that were created directly on the content frame
            -- We need to track and clear these separately since they're not children
            if content.searchFontStrings then
                for _, fontString in ipairs(content.searchFontStrings) do
                    if fontString then
                        fontString:Hide()
                        fontString:SetParent(nil)
                    end
                end
            end
            content.searchFontStrings = {}
            
            -- Update title
            content.title:SetText(string.format("Search Results: '%s' (%d found)", self.currentSearchTerm, #self.searchResults))
            
            if #self.searchResults == 0 then
                -- Show no results message
                if not content.noResultsText then
                    content.noResultsText = content:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
                    content.noResultsText:SetPoint("TOP", content.title, "BOTTOM", 0, -20)
                    content.noResultsText:SetTextColor(0.7, 0.7, 0.7, 1)
                    table.insert(content.searchFontStrings, content.noResultsText)
                end
                content.noResultsText:SetText("No mounts found matching your search.")
                content.noResultsText:Show()
                return
            else
                if content.noResultsText then
                    content.noResultsText:Hide()
                end
            end
            
            -- Group results by section, then by category
            local groupedResults = {}
            for _, result in ipairs(self.searchResults) do
                if not groupedResults[result.section] then
                    groupedResults[result.section] = {}
                end
                if not groupedResults[result.section][result.category] then
                    groupedResults[result.section][result.category] = {}
                end
                table.insert(groupedResults[result.section][result.category], result)
            end
            
            -- Calculate layout dimensions
            local currentWidth, _ = MCLcore.Frames:GetCurrentFrameDimensions()
            local availableWidth = currentWidth - 60
            
            -- Start with user's preferred mounts per row
            local mountsPerRow = MCL_SETTINGS.mountsPerRow or 12  -- Use setting or default to 12
            -- Ensure it's within bounds
            mountsPerRow = math.max(6, math.min(mountsPerRow, 24))
            
            -- Calculate mount size to fit exactly within available width
            local desiredSpacing = 4  -- Fixed spacing between mounts
            local minMountSize = 16  -- Absolute minimum mount size
            local maxMountSize = 48  -- Maximum mount size
            
            -- Try the preferred mounts per row first
            local totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
            local availableForMounts = availableWidth - totalSpacingWidth
            local mountSize = math.floor(availableForMounts / mountsPerRow)
            
            -- If mount size is too small, reduce mounts per row until we get acceptable size
            while mountSize < minMountSize and mountsPerRow > 6 do
                mountsPerRow = mountsPerRow - 1
                totalSpacingWidth = desiredSpacing * (mountsPerRow - 1)
                availableForMounts = availableWidth - totalSpacingWidth
                mountSize = math.floor(availableForMounts / mountsPerRow)
            end
            
            -- Ensure mount size is within bounds
            mountSize = math.max(minMountSize, math.min(mountSize, maxMountSize))
            
            -- Recalculate actual spacing to center the grid
            local actualMountWidth = mountSize * mountsPerRow
            local spacing = mountsPerRow > 1 and math.floor((availableWidth - actualMountWidth) / (mountsPerRow - 1)) or 0
            spacing = math.max(1, spacing)  -- Minimum 1px spacing
            
            local currentY = -80 -- Start below title
            local mountIndex = 0
            
            -- Display results grouped by section and category
            for sectionName, sectionData in pairs(groupedResults) do
                -- Create section header
                local sectionHeader = content:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
                sectionHeader:SetPoint("TOPLEFT", content, "TOPLEFT", 10, currentY)
                sectionHeader:SetText(sectionName)
                sectionHeader:SetTextColor(1, 0.82, 0, 1) -- Gold color like Blizzard UI
                table.insert(content.searchFontStrings, sectionHeader)
                currentY = currentY - 25
                
                for categoryName, categoryMounts in pairs(sectionData) do
                    -- Create category header
                    local categoryHeader = content:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
                    categoryHeader:SetPoint("TOPLEFT", content, "TOPLEFT", 20, currentY)
                    categoryHeader:SetText(categoryName .. " (" .. #categoryMounts .. ")")
                    categoryHeader:SetTextColor(0.8, 0.8, 1, 1) -- Light blue color
                    table.insert(content.searchFontStrings, categoryHeader)
                    currentY = currentY - 20
                    
                    -- Display mounts for this category
                    local categoryStartY = currentY
                    local categoryMountIndex = 0
                    
                    for _, result in ipairs(categoryMounts) do
                        local col = (categoryMountIndex % mountsPerRow)
                        local row = math.floor(categoryMountIndex / mountsPerRow)
                        
                        local x = spacing + col * (mountSize + spacing)
                        local y = categoryStartY - row * (mountSize + 10)
                          -- Create mount frame
                        local mountFrame = CreateFrame("Button", nil, content, "BackdropTemplate")
                        mountFrame:SetSize(mountSize, mountSize)
                        mountFrame:SetPoint("TOPLEFT", content, "TOPLEFT", x, y)
                        
                        -- Set mount icon
                        mountFrame.tex = mountFrame:CreateTexture(nil, "ARTWORK")
                        mountFrame.tex:SetAllPoints(mountFrame)
                        mountFrame.tex:SetTexture(result.icon)
                          -- Add pin functionality (required for pin/unpin operations)
                        mountFrame.pin = mountFrame:CreateTexture(nil, "OVERLAY")
                        mountFrame.pin:SetWidth(16)
                        mountFrame.pin:SetHeight(16)
                        mountFrame.pin:SetTexture("Interface\\AddOns\\OrzUI\\Media\\Modules\\MountCollectionLog\\pin.blp")
                        mountFrame.pin:SetPoint("TOPRIGHT", mountFrame, "TOPRIGHT", -2, -2)
                        mountFrame.pin:SetAlpha(0)
                        
                        -- Set mount properties for functionality
                        mountFrame.mountID = result.mountId
                        mountFrame.category = result.category
                        mountFrame.section = result.section
                        
                        -- Check if mount is already pinned and show pin icon if needed
                        local isPinned, pinIndex = MCLcore.Function:CheckIfPinned("m" .. result.mountId)
                        if isPinned then
                            mountFrame.pin:SetAlpha(1)
                        end                        -- Style based on collection status
                        -- Note: With hideCollectedMounts enabled, collected mounts won't be in search results
                        if result.isCollected then
                            mountFrame.tex:SetVertexColor(1, 1, 1, 1)
                            mountFrame:SetBackdrop({
                                bgFile = "Interface\\Buttons\\WHITE8x8",
                                edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                                edgeSize = 2
                            })
                            mountFrame:SetBackdropColor(0, 0.8, 0, 0.6)
                            mountFrame:SetBackdropBorderColor(0, 1, 0, 1)
                        else
                            mountFrame.tex:SetVertexColor(0.4, 0.4, 0.4, 0.7)
                            mountFrame:SetBackdrop({
                                bgFile = "Interface\\Buttons\\WHITE8x8",
                                edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                                edgeSize = 2
                            })
                            mountFrame:SetBackdropColor(0.8, 0, 0, 0.4)
                            mountFrame:SetBackdropBorderColor(0.8, 0.2, 0.2, 1)
                        end                        -- Add tooltip and click functionality
                        mountFrame:SetScript("OnEnter", function(self)
                            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                            
                            -- Check if this mount has an item ID (number) vs mount ID (string starting with "m")
                            -- If it's an item ID, show the item tooltip; otherwise show the mount spell tooltip
                            if type(result.mountId) == "number" then
                                -- This is an item ID, show item tooltip
                                GameTooltip:SetItemByID(result.mountId)
                            else
                                -- This is a mount ID or spell ID, show mount spell tooltip
                                GameTooltip:SetMountBySpellID(result.spellID)
                            end
                            
                            GameTooltip:AddLine(" ")
                            GameTooltip:AddLine("Found in: " .. result.section .. " > " .. result.category, 0.7, 0.7, 1, 1)
                            
                            -- Show what was matched if it's different from the mount name
                            if result.matchedName and result.matchedName ~= result.mountName then
                                GameTooltip:AddLine("Matched: " .. result.matchedName, 0.7, 1, 0.7, 1)
                            end
                            
                            GameTooltip:AddLine("Click to navigate to this mount's location", 1, 1, 0, 1)
                            GameTooltip:AddLine("Ctrl+Right-Click to pin/unpin this mount", 1, 1, 0, 1)
                            GameTooltip:Show()
                        end)
                        mountFrame:SetScript("OnLeave", function()
                            GameTooltip:Hide()
                        end)
                        
                        -- Set up proper mouse click functionality including pinning
                        MCLcore.Function:SetMouseClickFunctionality(mountFrame, result.mountId, result.mountName, nil, result.spellID, false)
                        
                        -- Override the OnMouseDown handler to include navigation for search results
                        local originalOnMouseDown = mountFrame:GetScript("OnMouseDown")
                        mountFrame:SetScript("OnMouseDown", function(self, button)
                            if button == "LeftButton" and not IsControlKeyDown() and not IsShiftKeyDown() then
                                -- Navigate to the mount's location for search results
                                MCLcore.Search:NavigateToMount(result)
                            else
                                -- Call the original OnMouseDown handler for other functionality
                                if originalOnMouseDown then
                                    originalOnMouseDown(self, button)
                                end
                            end
                        end)
                        
                        -- Ensure mouse interaction is enabled
                        mountFrame:EnableMouse(true)
                        mountFrame:SetFrameStrata("HIGH")
                        mountFrame:SetFrameLevel(10)
                        
                        categoryMountIndex = categoryMountIndex + 1
                    end
                    
                    -- Calculate how much Y space this category used
                    local categoryRows = math.ceil(#categoryMounts / mountsPerRow)
                    currentY = categoryStartY - categoryRows * (mountSize + 10) - 10 -- Add some spacing after category
                end
                
                -- Add extra spacing after each section
                currentY = currentY - 10
            end
        end
        function MCLcore.Search:NavigateToMount(result)
            -- Store the target section for navigation
            local targetSection = result.section
            
            -- Clear search state without restoring previous tab
            self.currentSearchTerm = ""
            self.isSearchActive = false
            self.searchResults = {}
            
            -- Clear any highlighting
            self:ClearHighlighting()
            
            -- Properly destroy search results content frame
            self:DestroySearchResultsFrame()
            
            -- Clear search box text
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.searchBox then
                MCLcore.MCL_MF_Nav.searchBox:SetText("")
                if MCLcore.MCL_MF_Nav.searchPlaceholder then
                    MCLcore.MCL_MF_Nav.searchPlaceholder:Show()
                end
            end
            
            -- Clear the previously selected tab reference
            self.previouslySelectedTab = nil
            
            -- Find and select the correct tab for this section
            if MCLcore.MCL_MF_Nav and MCLcore.MCL_MF_Nav.tabs then
                for i, tab in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                    if tab.section and tab.section.name == targetSection then
                        -- Use the proper tab selection logic (same as SelectTab function)
                        -- Deselect all tabs first
                        for _, t in ipairs(MCLcore.MCL_MF_Nav.tabs) do
                            if t.SetBackdropBorderColor then
                                t:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                            end
                        end
                        
                        -- Hide all tab contents using the proper HideAllTabContents function
                        if MCLcore.HideAllTabContents then
                            MCLcore.HideAllTabContents()
                        end
                        
                        -- Select the target tab
                        if tab.SetBackdropBorderColor then
                            tab:SetBackdropBorderColor(1, 0.82, 0, 1)
                        end
                        if tab.content and MCL_mainFrame.ScrollFrame then
                            -- Always keep the main scroll child as the scroll child
                            MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                            tab.content:Show()
                            MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
                        end
                        -- Update global reference
                        MCLcore.currentlySelectedTab = tab
                        break
                    end
                end
            end
            
            -- Store the mount to highlight for later
            MCLcore.Search.highlightMountId = result.mountId
            
            -- Schedule highlighting for next frame to ensure content is loaded
            C_Timer.After(0.1, function()
                MCLcore.Search:HighlightMount(result.mountId)
            end)
            
            -- Print info for user feedback
            print("|cff00CCFFMount Collection Log:|r Found '" .. result.mountName .. "' in " .. result.section .. " > " .. result.category)
        end

        function MCLcore.Search:ClearHighlighting()
            -- Clear any existing highlighting effects
            if MCLcore.highlightedMountFrame then
                if MCLcore.highlightedMountFrame.originalBorderColor then
                    MCLcore.highlightedMountFrame:SetBackdropBorderColor(
                        MCLcore.highlightedMountFrame.originalBorderColor[1],
                        MCLcore.highlightedMountFrame.originalBorderColor[2],
                        MCLcore.highlightedMountFrame.originalBorderColor[3],
                        MCLcore.highlightedMountFrame.originalBorderColor[4]
                    )
                end
                if MCLcore.highlightedMountFrame.highlightTimer then
                    MCLcore.highlightedMountFrame.highlightTimer:Cancel()
                end
                MCLcore.highlightedMountFrame = nil
            end
        end

        function MCLcore.Search:HighlightMount(mountId)
            -- Clear any existing highlighting
            self:ClearHighlighting()
            
            -- Find the mount frame in the current content
            local currentContent = MCL_mainFrame.ScrollFrame:GetScrollChild()
            if not currentContent then return end
            
            -- Look for mount frames that match our target mount
            local function FindMountFrame(parent)
                for i = 1, parent:GetNumChildren() do
                    local child = select(i, parent:GetChildren())
                    if child and child.mountID then
                        local mount_Id = MCLcore.Function:GetMountID(child.mountID)
                        local target_Id = MCLcore.Function:GetMountID(mountId)
                        if mount_Id and target_Id and mount_Id == target_Id then
                            return child
                        end
                    end
                    -- Recursively search children
                    local found = FindMountFrame(child)
                    if found then return found end
                end
            end
            
            local mountFrame = FindMountFrame(currentContent)
            if mountFrame then
                -- Store original border color
                local r, g, b, a = mountFrame:GetBackdropBorderColor()
                mountFrame.originalBorderColor = {r, g, b, a}
                
                -- Store reference for cleanup
                MCLcore.highlightedMountFrame = mountFrame
                
                -- Create pulsing highlight effect
                local pulseTimer
                local pulseCount = 0
                local maxPulses = 6
                
                pulseTimer = C_Timer.NewTicker(0.5, function()
                    pulseCount = pulseCount + 1
                    if pulseCount > maxPulses then
                        -- Restore original color and stop
                        if mountFrame.originalBorderColor then
                            mountFrame:SetBackdropBorderColor(
                                mountFrame.originalBorderColor[1],
                                mountFrame.originalBorderColor[2],
                                mountFrame.originalBorderColor[3],
                                mountFrame.originalBorderColor[4]
                            )
                        end
                        pulseTimer:Cancel()
                        MCLcore.highlightedMountFrame = nil
                        return
                    end
                    
                    -- Pulse between yellow and original color
                    if pulseCount % 2 == 1 then
                        mountFrame:SetBackdropBorderColor(1, 1, 0, 1) -- Bright yellow
                    else
                        mountFrame:SetBackdropBorderColor(
                            mountFrame.originalBorderColor[1],
                            mountFrame.originalBorderColor[2],
                            mountFrame.originalBorderColor[3],
                            mountFrame.originalBorderColor[4]
                        )
                    end
                end)
                
                mountFrame.highlightTimer = pulseTimer
                
                -- Scroll to the mount if needed
                local frameTop = currentContent:GetTop()
                local frameBottom = currentContent:GetBottom()
                local mountTop = mountFrame:GetTop()
                local mountBottom = mountFrame:GetBottom()
                
                if frameTop and frameBottom and mountTop and mountBottom then
                    local scrollFrame = MCL_mainFrame.ScrollFrame
                    local scrollTop = scrollFrame:GetTop()
                    local scrollBottom = scrollFrame:GetBottom()
                    
                    -- Check if mount is not visible in scroll area
                    if mountTop > scrollTop or mountBottom < scrollBottom then
                        -- Calculate scroll position to center the mount
                        local scrollHeight = scrollFrame:GetVerticalScrollRange()
                        local contentHeight = frameTop - frameBottom
                        local mountCenter = (mountTop + mountBottom) / 2
                        local targetScroll = (frameTop - mountCenter) / contentHeight * scrollHeight
                        
                        -- Clamp to valid scroll range
                        targetScroll = math.max(0, math.min(targetScroll, scrollHeight))
                        scrollFrame:SetVerticalScroll(targetScroll)
                    end
                end
            end
        end
        
        function MCLcore.Search:RecreateSearchResultsFrame()
            if not MCLcore.searchResultsContent then return end
            
            -- Hide and remove the old search results content frame
            MCLcore.searchResultsContent:Hide()
            MCLcore.searchResultsContent:SetParent(nil)
            MCLcore.searchResultsContent = nil
            
            -- Create new search results content frame with updated dimensions
            MCLcore.searchResultsContent = MCLcore.Frames:createContentFrame(MCL_mainFrame.ScrollChild, "Search Results")
            
            -- Update the content
            self:UpdateSearchResultsContent()
            
            -- Show the new frame
            if MCL_mainFrame.ScrollFrame then
                -- Always keep the main scroll child as the scroll child
                MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                MCLcore.searchResultsContent:Show()
                MCL_mainFrame.ScrollFrame:SetVerticalScroll(0)
            end
        end
        
        function MCLcore.Search:DestroySearchResultsFrame()
            if MCLcore.searchResultsContent then
                -- Hide and remove the search results content frame
                MCLcore.searchResultsContent:Hide()
                MCLcore.searchResultsContent:SetParent(nil)
                MCLcore.searchResultsContent = nil
                
                -- Ensure the main scroll child is set as the scroll child
                if MCL_mainFrame.ScrollFrame and MCL_mainFrame.ScrollChild then
                    MCL_mainFrame.ScrollFrame:SetScrollChild(MCL_mainFrame.ScrollChild)
                end
            end
        end
    end
end

-- Make InitializeSearch available globally so it can be called when addon loads
MCLcore = MCLcore or {}
MCLcore.InitializeSearch = InitializeSearch

-- Namespace
-------------------------------------------------------------

SLASH_MCL1 = "/mcl";

SlashCmdList["MCL"] = function(msg)
    if msg:lower() == "help" then
        print(MCLL["|cff00CCFFMount Collection Log Commands:\n|cffFF0000Show:|cffFFFFFF Shows your mount collection log\n|cffFF0000Icon:|cffFFFFFF Toggles the minimap icon\n|cffFF0000Config:|cffFFFFFF Opens the settings\n|cffFF0000Help:|cffFFFFFF Shows commands"])
    end
    if msg:lower() == "show" then
        MCLcore.Main.Toggle();
    end
    if msg:lower() == "icon" then
        MCLcore.Function.MCL_MM();
    end        
    if msg:lower() == "" then
        MCLcore.Main.Toggle();
    end
    if msg:lower() == "debug" then
        MCLcore.Function:GetCollectedMounts();
    end
    if msg:lower() == "config" or msg == "settings" then
        MCLcore.Frames:openSettings();
    end
    if msg:lower() == "refresh" then
        if MCLcore.Main and type(MCLcore.Main.Init) == "function" then
            MCLcore.Main:Init(true)  -- True to force re-initialization.
        end
    end
    if msg:lower() == "cleanup" or msg:lower() == "cleanpinned" then
        if MCLcore.Function and MCLcore.Function.CleanupInvalidPinnedMounts then
            print("|cff00CCFF[MCL]|r Starting cleanup of invalid pinned mounts...")
            MCLcore.Function:CleanupInvalidPinnedMounts()
            print("|cff00CCFF[MCL]|r Cleanup complete. Try viewing the Pinned tab now.")
        else
            print("|cffFF0000[MCL]|r Cleanup function not available.")
        end
    end
    if msg:lower() == "testmount" then
        -- Test a known mount ID to see what the API returns
        local testId = 230  -- Swift Palomino - a basic mount that should exist
        print("|cff00CCFF[MCL Debug]|r Testing mount ID", testId)
        local mountName, spellID, icon = C_MountJournal.GetMountInfoByID(testId)
        print(string.format("|cff00CCFF[MCL Debug]|r Result: mountName='%s', spellID=%s, icon=%s", 
            tostring(mountName), tostring(spellID), tostring(icon)))
            
        -- Also test one of the problematic IDs if MCL_PINNED exists
        if MCL_PINNED and #MCL_PINNED > 0 then
            local firstPinned = MCL_PINNED[1]
            if firstPinned and firstPinned.mountID then
                local mountId = firstPinned.mountID
                local mount_Id = nil
                if string.sub(tostring(mountId), 1, 1) == "m" then
                    mount_Id = tonumber(string.sub(tostring(mountId), 2, -1))
                end
                if mount_Id then
                    print("|cff00CCFF[MCL Debug]|r Testing pinned mount ID", mount_Id, "from", mountId)
                    local pMountName, pSpellID, pIcon = C_MountJournal.GetMountInfoByID(mount_Id)
                    print(string.format("|cff00CCFF[MCL Debug]|r Pinned Result: mountName='%s', spellID=%s, icon=%s", 
                        tostring(pMountName), tostring(pSpellID), tostring(pIcon)))
                end
            end
        end
    end
 end
