private void ShoutNews_Callback(object state)
        {
            object[]       states = (object[])state;
            TownCrierEntry tce    = (TownCrierEntry)states[0];
            int            index  = (int)states[1];

            if (index < 0 || index >= tce.Lines.Length)
            {
                if (m_NewsTimer != null)
                {
                    m_NewsTimer.Stop();
                }

                m_NewsTimer = null;
            }
            else
            {
                PublicOverheadMessage(MessageType.Regular, 0x3B2, false, tce.Lines[index]);
                states[1] = index + 1;
            }
        }
        public TownCrierEntry GetRandomEntry()
        {
            if (m_Entries == null || m_Entries.Count == 0)
            {
                return(GlobalTownCrierEntryList.Instance.GetRandomEntry());
            }

            for (int i = m_Entries.Count - 1; m_Entries != null && i >= 0; --i)
            {
                if (i >= m_Entries.Count)
                {
                    continue;
                }

                TownCrierEntry tce = m_Entries[i];

                if (tce.Expired)
                {
                    RemoveEntry(tce);
                }
            }

            if (m_Entries == null || m_Entries.Count == 0)
            {
                return(GlobalTownCrierEntryList.Instance.GetRandomEntry());
            }

            TownCrierEntry entry = GlobalTownCrierEntryList.Instance.GetRandomEntry();

            if (entry == null || Utility.RandomBool())
            {
                entry = m_Entries[Utility.Random(m_Entries.Count)];
            }

            return(entry);
        }
        public void RemoveEntry(TownCrierEntry tce)
        {
            if (m_Entries == null)
            {
                return;
            }

            m_Entries.Remove(tce);

            if (m_Entries.Count == 0)
            {
                m_Entries = null;
            }

            if (m_Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty)
            {
                if (m_AutoShoutTimer != null)
                {
                    m_AutoShoutTimer.Stop();
                }

                m_AutoShoutTimer = null;
            }
        }
        public TownCrierGump(Mobile from, ITownCrierEntryList owner) : base(50, 50)
        {
            m_From  = from;
            m_Owner = owner;

            from.CloseGump(typeof(TownCrierGump));

            AddPage(0);

            List <TownCrierEntry> entries = owner.Entries;

            owner.GetRandomEntry(); // force expiration checks

            int count = 0;

            if (entries != null)
            {
                count = entries.Count;
            }

            AddImageTiled(0, 0, 300, 38 + (count == 0 ? 20 : (count * 85)), 0xA40);
            AddAlphaRegion(1, 1, 298, 36 + (count == 0 ? 20 : (count * 85)));

            AddHtml(8, 8, 300 - 8 - 30, 20, "<basefont color=#FFFFFF><center>TOWN CRIER MESSAGES</center></basefont>", false, false);

            AddButton(300 - 8 - 30, 8, 0xFAB, 0xFAD, 1, GumpButtonType.Reply, 0);

            if (count == 0)
            {
                AddHtml(8, 30, 284, 20, "<basefont color=#FFFFFF>The crier has no news.</basefont>", false, false);
            }
            else
            {
                for (int i = 0; i < entries.Count; ++i)
                {
                    TownCrierEntry tce = (TownCrierEntry)entries[i];

                    TimeSpan toExpire = tce.ExpireTime - DateTime.UtcNow;

                    if (toExpire < TimeSpan.Zero)
                    {
                        toExpire = TimeSpan.Zero;
                    }

                    StringBuilder sb = new StringBuilder();

                    sb.Append("[Expires: ");

                    if (toExpire.TotalHours >= 1)
                    {
                        sb.Append((int)toExpire.TotalHours);
                        sb.Append(':');
                        sb.Append(toExpire.Minutes.ToString("D2"));
                    }
                    else
                    {
                        sb.Append(toExpire.Minutes);
                    }

                    sb.Append(':');
                    sb.Append(toExpire.Seconds.ToString("D2"));

                    sb.Append("] ");

                    for (int j = 0; j < tce.Lines.Length; ++j)
                    {
                        if (j > 0)
                        {
                            sb.Append("<br>");
                        }

                        sb.Append(tce.Lines[j]);
                    }

                    AddHtml(8, 35 + (i * 85), 254, 80, sb.ToString(), true, true);

                    AddButton(300 - 8 - 26, 35 + (i * 85), 0x15E1, 0x15E5, 2 + i, GumpButtonType.Reply, 0);
                }
            }
        }