static void PrintStatistic(ConstructTooltipUIData data, ItemStatistics stat, bool allTime)
        {
            string span;

            if (!allTime)
            {
                span = "Last " + new TimeSpan(TimedItemStatistics.PeriodsToGameHours(stat.Periods), 0, 0).ToHumanReadableString() + " average:";
            }
            else
            {
                span = "Since world load:";
            }

            data.menu.Items.Add(new Line(Color.white, 2, -1, 10, 2));

            data.menu.Items.Add(new Label(new LabelData(span, TextAnchor.MiddleLeft, 17, LabelData.ELocalizationType.Sentence), -1));
            data.menu.Items.Add(new Label(new LabelData("Created " + PrintSingleStat(stat.AverageProduced) + ", Used " + PrintSingleStat(stat.AverageConsumed), TextAnchor.MiddleLeft, 13, LabelData.ELocalizationType.Sentence), -1));
            data.menu.Items.Add(new Label(new LabelData(PrintSingleStat(stat.AverageProducers) + " producers, " + PrintSingleStat(stat.AverageConsumers) + " consumers", TextAnchor.MiddleLeft, 13, LabelData.ELocalizationType.Sentence), -1));
            data.menu.Items.Add(new Label(new LabelData("Stock " + PrintSingleStat(stat.AverageInventoryAdded) + " added, " + PrintSingleStat(stat.AverageInventoryRemoved) + " removed", TextAnchor.MiddleLeft, 13, LabelData.ELocalizationType.Sentence), -1));

            if (stat.TradedIn != 0 || stat.TradedOut != 0)
            {
                data.menu.Items.Add(new Label(new LabelData("Trade +" + PrintSingleStat(stat.AverageTradedIn) + " / -" + PrintSingleStat(stat.AverageTradedOut), TextAnchor.MiddleLeft, 13, LabelData.ELocalizationType.Sentence), -1));
            }

            if (stat.UsedForFood != 0)
            {
                data.menu.Items.Add(new Label(new LabelData("Food Use: " + PrintSingleStat(stat.AverageUsedForFood), TextAnchor.MiddleLeft, 13, LabelData.ELocalizationType.Sentence), -1));
            }
        }
        public TimedItemStatistics()
        {
            GamePeriodLengthInMinutes = ServerManager.ServerSettings.Time.GameTimeScale * RealLifePeriodLengthInSeconds / 60;
            MaxPeriods          = (int)(PeriodDays * 24 * 60 / GamePeriodLengthInMinutes) + 1;
            timedItemStatistics = new ItemStatistics[MaxPeriods];
            AllTimeStatistics   = new ItemStatistics();
            averages            = new List <ItemStatistics>();

            CurrentPeriod = GetPeriod();
            for (int i = 0; i < MaxPeriods; ++i)
            {
                timedItemStatistics[i] = new ItemStatistics();
            }
            CurrentStatistics = timedItemStatistics[CurrentPeriod];

            nextAverages = new int[]
            {
                1,
                // 6,
                // 12,
                24
                // 48,
                //MaxPeriods
            };
        }
        public ItemStatistics Average(int lastPeriods)
        {
            if (lastPeriods <= 0)
            {
                return(new ItemStatistics());
            }

            if (lastPeriods > MaxPeriods)
            {
                lastPeriods = MaxPeriods;
            }

            PerformPeriodUpdate();

            ItemStatistics stats = new ItemStatistics(CurrentStatistics);

            while (--lastPeriods > 0)
            {
                int adjusted_period = _currentPeriod - lastPeriods;
                if (adjusted_period < 0)
                {
                    adjusted_period = MaxPeriods + adjusted_period;
                }

                stats += timedItemStatistics[adjusted_period];
            }

            return(stats);
        }
        public ItemStatistics(ItemStatistics other)
        {
            _producers = other._producers;
            _consumers = other._consumers;

            Produced         = other.Produced;
            Consumed         = other.Consumed;
            Producers        = other.Producers;
            Consumers        = other.Consumers;
            InventoryAdded   = other.InventoryAdded;
            InventoryRemoved = other.InventoryRemoved;
            UsedForFood      = other.UsedForFood;
            TradedIn         = other.TradedIn;
            TradedOut        = other.TradedOut;

            Periods = other.Periods;
        }
        public List <ItemStatistics> Averages()
        {
            PerformPeriodUpdate();

            if (!Dirty && averages != null)
            {
                return(averages);
            }

            averages = new List <ItemStatistics>();

            ItemStatistics stats = new ItemStatistics(CurrentStatistics);

            int lastPeriods = 0;

            int nextAverage = 0;

            while (nextAverage < nextAverages.Length)
            {
                if (stats.Periods >= nextAverages[nextAverage])
                {
                    ++nextAverage;
                    averages.Add(new ItemStatistics(stats));
                }

                int adjusted_period = _currentPeriod - (++lastPeriods);
                if (adjusted_period < 0)
                {
                    adjusted_period = MaxPeriods + adjusted_period;
                }

                stats += timedItemStatistics[adjusted_period];
            }

            Dirty = false;
            return(averages);
        }