internal virtual pTab Add(string name, object tag, int insertPosition)
        {
            if (Tabs.Find(t => t.Tag == tag) != null)
            {
                return(null);
            }

            Vector2 position = new Vector2(BottomLeft.X + (Tabs.Count % MaxTabsWide) * secondRowOffset + (Tabs.Count / MaxTabsWide) * 10 * (RightToLeft?-1:1),
                                           BottomLeft.Y + 6 - (14 * (1 + Tabs.Count / MaxTabsWide)));

            float depth = baseDepth - Tabs.Count * 0.0002f - (Tabs.Count / MaxTabsWide) * 0.0001F;

            pTab tab = createTab(name, tag, position, depth);

            tab.OnClick += tab_OnClick;

            if (defaultTab == null)
            {
                defaultTab = tab;
            }

            Sprites.AddRange(tab.SpriteCollection);
            SpriteManager.Add(tab.SpriteCollection);

            if (insertPosition < 0)
            {
                insertPosition = 0;
            }

            Tabs.Insert(insertPosition > Tabs.Count ? Tabs.Count : insertPosition, tab);

            Resort();

            return(tab);
        }
        internal void SetSelected(pTab tab, bool silent)
        {
            if (SelectedTab == tab)
            {
                return;
            }

            if (tab != null && !tab.AllowSelection)
            {
                return;
            }

            pTab lastSelected = SelectedTab;

            SelectedTab = tab;

            foreach (pTab ta in Tabs)
            {
                if (ta == SelectedTab)
                {
                    ta.tabBackground.FadeColour(Color.White, 100);
                    ta.tabBackground.HoverEffect = null;
                    ta.Alerting = false;

                    ta.tabText.FadeColour(Color.Black, 20);
                    ta.tabText.TextShadow  = false;
                    ta.tabText.TextChanged = true;

                    ta.SpriteCollection.ForEach(p => p.Depth += 0.001F);
                    SpriteManager.RemoveRange(ta.SpriteCollection);
                    SpriteManager.Add(ta.SpriteCollection);
                }
                else
                {
                    if (ta == lastSelected)
                    {
                        ta.tabBackground.HoverEffect = hoverEffect;

                        ta.tabBackground.FadeColour(TabColour, 20);
                        ta.tabText.FadeColour(Color.White, 20);
                        ta.tabText.TextShadow  = true;
                        ta.tabText.TextChanged = true;

                        ta.SpriteCollection.ForEach(p => p.Depth -= 0.001F);
                        SpriteManager.RemoveRange(ta.SpriteCollection);
                        SpriteManager.Add(ta.SpriteCollection);
                    }
                }
            }

            if (!silent && OnTabChanged != null)
            {
                OnTabChanged(SelectedTab != null ? SelectedTab.Tag : null, null);
            }
        }
        internal pTab SetSelected(object tag, bool silent, bool unselectIfNotExisting = false)
        {
            pTab tab = GetFromTag(tag);

            if (tab == null && !unselectIfNotExisting)
            {
                return(null);
            }

            SetSelected(tab, silent);
            return(tab);
        }
        public void SetAlert(object tag)
        {
            pTab t = GetFromTag(tag);

            if (t == null || t == SelectedTab)
            {
                return;
            }

            t.Alerting = true;
            t.tabBackground.FadeColour(TabColourAlert, 100);
            t.tabBackground.HoverEffect = hoverEffectAlerted;
        }
        internal virtual void Resort()
        {
            for (int i = 0; i < Tabs.Count; i++)
            {
                pTab    t        = Tabs[i];
                Vector2 position = new Vector2(BottomLeft.X + (i % MaxTabsWide) * pTab.TAB_WIDTH * (RightToLeft ? -1 : 1) + ((i / MaxTabsWide) % 2) * secondRowOffset,
                                               BottomLeft.Y + 6 - 14 - (separationHeight * (i / MaxTabsWide)));

                float depth = baseDepth - i * 0.0002f - (i / MaxTabsWide) * 0.0001F;

                t.SpriteCollection[0].HoverPriority = (int)(-100 + depth * 100);
                for (int j = 0; j < t.SpriteCollection.Count; j++)
                {
                    pSprite sprite = t.SpriteCollection[j];

                    sprite.InitialPosition = position;
                    sprite.MoveTo(position, 300, EasingTypes.OutElasticQuarter);
                    sprite.Depth = depth + 0.0001f * j + (SelectedTab == t ? 0.001f : 0);
                }
            }

            SpriteManager.ResortDepth();
        }
        public virtual void Remove(pTab t)
        {
            if (t == null)
            {
                return;
            }

            int index = Tabs.IndexOf(t);

            if (index < 0 || index >= Tabs.Count)
            {
                return;
            }

            Tabs.Remove(t);

            t.SpriteCollection.ForEach(p =>
            {
                Sprites.Remove(p);
                p.AlwaysDraw = false;
                p.FadeOut(200);
            });

            if (SelectedTab == t && Tabs.Count > 0)
            {
                if (index < Tabs.Count && Tabs[index].AllowSelection)
                {
                    SetSelected(Tabs[index], false);
                }
                else if (index > 0)
                {
                    SetSelected(Tabs[index - 1], false);
                }
            }

            Resort();
        }