/// <summary>
        /// Returns a list of recipes from selected skill
        /// </summary>
        /// <param name="skillLine"></param>
        /// <param name="blockFrame">prevents tradeskill frame from showing</param>
        /// <returns></returns>
        public TradeSkill GetTradeSkill(SkillLine skillLine, bool blockFrame)
        {
            if (!ObjectManager.IsInGame)
            {
                throw new InvalidOperationException("Must Be in game to call GetTradeSkill()");
            }
            if (skillLine == 0 || !SupportedSkills.Contains(skillLine))
            {
                throw new InvalidOperationException(string.Format("The tradekill {0} can not be loaded", skillLine));
            }
            // if HB is not running then we need to pulse objectmanger for item counts
            if (!TreeRoot.IsRunning)
            {
                ObjectManager.Update();
            }
            WoWSkill wowSkill = ObjectManager.Me.GetSkill(skillLine);

            TradeSkill tradeSkill = new TradeSkill(wowSkill);

            //lets copy over to a local variable for performance
            bool   _isVisible = IsVisible;
            bool   loadSkill  = Skill != skillLine || !_isVisible;
            string lua        = string.Format("{0}{1}{2}{3}",
                                              blockFrame && loadSkill ? "if not TradeSkillFrame then LoadAddOn('Blizzard_TradeSkillUI') end local fs = {} local f = EnumerateFrames() while f do if f:IsEventRegistered('TRADE_SKILL_SHOW') == 1 and f:GetName() ~= 'UIParent' then f:UnregisterEvent('TRADE_SKILL_SHOW') table.insert (fs,f) end f = EnumerateFrames(f) end " : "",
                                              // have to hard code in mining since I need to cast 'Smelting' not 'Mining' XD
                                              // also using lua over SpellManager.Cast since its grabing name from DBC. one word, localization.
                                              loadSkill ? (skillLine == SkillLine.Mining ? "CastSpellByID(2656) " : string.Format("CastSpellByName('{0}') ", wowSkill.Name)) : "",
                                              // force cache load
                                              "for i=1, GetNumTradeSkills() do GetTradeSkillItemLink(i) for n=1,GetTradeSkillNumReagents(i) do GetTradeSkillReagentInfo(i,n) end end ",
                                              blockFrame && loadSkill ? "for k,v in pairs(fs) do v:RegisterEvent('TRADE_SKILL_SHOW') end CloseTradeSkill() " : ""
                                              );

            using (new FrameLock())
            {
                if (!string.IsNullOrEmpty(lua))
                {
                    Lua.DoString(lua);
                }

                int _recipeCount = RecipeCount;
                if (Skill != skillLine || _recipeCount <= 0)
                {// we failed to load tradeskill
                    throw new Exception(string.Format("Unable to load {0}", skillLine));
                }
                // array of pointers that point to each recipe structure.
                uint[] recipePtrArray = ObjectManager.Wow.ReadStructArray <uint>(RecipeOffset, RecipeCount);
                for (int index = 0; index < _recipeCount; index++)
                {
                    uint[] recipeData = ObjectManager.Wow.ReadStructArray <uint>(recipePtrArray[index], 9);
                    uint   id         = recipeData[(int)Recipe.RecipeIndex.RecipeID];
                    // check if its a header
                    if (id == uint.MaxValue)
                    {
                        continue; // no further info to get for header
                    }
                    tradeSkill.Recipes.Add(id, new Recipe(recipeData, tradeSkill, skillLine));
                }
                tradeSkill.InitIngredientList();
                tradeSkill.InitToolList();
            }
            return(tradeSkill);
        }
        /// <summary>
        /// Returns a list of recipes from selected skill
        /// </summary>
        /// <param name="skillLine"></param>
        /// <param name="blockFrame">prevents tradeskill frame from showing</param>
        /// <returns></returns>
        public TradeSkill GetTradeSkill(SkillLine skillLine, bool blockFrame)
        {
            if (!ObjectManager.IsInGame)
                throw new InvalidOperationException("Must Be in game to call GetTradeSkill()");
            if (skillLine == 0 || !SupportedSkills.Contains(skillLine))
                throw new InvalidOperationException(string.Format("The tradekill {0} can not be loaded", skillLine));
            // if HB is not running then we need to pulse objectmanger for item counts
            if (!TreeRoot.IsRunning)
                ObjectManager.Update();
            WoWSkill wowSkill = ObjectManager.Me.GetSkill(skillLine);

            TradeSkill tradeSkill = new TradeSkill(wowSkill);

            //lets copy over to a local variable for performance
            bool _isVisible = IsVisible;
            bool loadSkill = Skill != skillLine || !_isVisible;
            string lua = string.Format("{0}{1}{2}{3}",
                blockFrame && loadSkill ? "if not TradeSkillFrame then LoadAddOn('Blizzard_TradeSkillUI') end local fs = {} local f = EnumerateFrames() while f do if f:IsEventRegistered('TRADE_SKILL_SHOW') == 1 and f:GetName() ~= 'UIParent' then f:UnregisterEvent('TRADE_SKILL_SHOW') table.insert (fs,f) end f = EnumerateFrames(f) end " : "",
                // have to hard code in mining since I need to cast 'Smelting' not 'Mining' XD
                // also using lua over SpellManager.Cast since its grabing name from DBC. one word, localization.
                loadSkill ? (skillLine == SkillLine.Mining ? "CastSpellByID(2656) " : string.Format("CastSpellByName('{0}') ", wowSkill.Name)) : "",
                // force cache load
                "for i=1, GetNumTradeSkills() do GetTradeSkillItemLink(i) for n=1,GetTradeSkillNumReagents(i) do GetTradeSkillReagentInfo(i,n) end end ",
                blockFrame && loadSkill ? "for k,v in pairs(fs) do v:RegisterEvent('TRADE_SKILL_SHOW') end CloseTradeSkill() " : ""
            );
            using (new FrameLock())
            {
                if (!string.IsNullOrEmpty(lua))
                    Lua.DoString(lua);

                int _recipeCount = RecipeCount;
                if (Skill != skillLine || _recipeCount <= 0)
                {// we failed to load tradeskill
                    throw new Exception(string.Format("Unable to load {0}", skillLine));
                }
                // array of pointers that point to each recipe structure.
                uint[] recipePtrArray = ObjectManager.Wow.ReadStructArray<uint>(RecipeOffset, RecipeCount);
                for (int index = 0; index < _recipeCount; index++)
                {
                    uint[] recipeData = ObjectManager.Wow.ReadStructArray<uint>(recipePtrArray[index], 9);
                    uint id = recipeData[(int)Recipe.RecipeIndex.RecipeID];
                    // check if its a header
                    if (id == uint.MaxValue)
                    {
                        continue; // no further info to get for header
                    }
                    tradeSkill.Recipes.Add(id, new Recipe(recipeData, tradeSkill, skillLine));
                }
                tradeSkill.InitIngredientList();
                tradeSkill.InitToolList();
            }
            return tradeSkill;
        }