/*
 *****************************************************************************
 *                                                                           *
 *              IMPINJ CONFIDENTIAL AND PROPRIETARY                          *
 *                                                                           *
 * This source code is the sole property of Impinj, Inc. Reproduction or     *
 * utilization of this source code in whole or in part is forbidden without  *
 * the prior written consent of Impinj, Inc.                                 *
 *                                                                           *
 * (c) Copyright Impinj, Inc. 2015. All rights reserved.                     *
 *                                                                           *
 *****************************************************************************/
using System.Collections.Generic;

namespace Impinj
{
    /// <summary>
    /// Class for managing the tag information presented to OxyPlot graph
    /// </summary>
    public class TagInfo
    {
        // Private data members
        string _tid;
        OxyPlot.OxyColor _color;
        Queue<TagRead> _tagReads = new Queue<TagRead>();

        // Public data accessors
        public OxyPlot.OxyColor Color { get { return _color; } }
        public string Tid { get { return _tid; } }
        public int NumReads { get { return _tagReads.Count; } }

        // Constructors
        public TagInfo(string tid)
        {
            _tid = tid;
            _color = generateNextColor();
        }

        public TagInfo(TagInfo other, double averageTimeDelta)
        {
            _tid = other.Tid;
            _color = other._color;
            foreach (TagRead tr in other._tagReads)
            {
                _tagReads.Enqueue(new TagRead
                {
                    Timestamp = tr.Timestamp + averageTimeDelta,
                    RSSI = tr.RSSI
                });
            }
        }

        // Add a new tag read to the TagRead queue for this tag
        public void AddRead(TagRead tagRead)
        {
            _tagReads.Enqueue(tagRead);
        }

        // Remove tag read entries that are older than the specified amount
        public void EvictTagReadsOlderThan(double limit)
        {
            while (0 < _tagReads.Count && _tagReads.Peek().Timestamp < limit)
            {
                _tagReads.Dequeue();
            }
        }

        // Pull the next color from the list
        private static OxyPlot.OxyColor generateNextColor()
        {
            _currColorIndex++;
            if (_currColorIndex >= _colors.Length)
            {
                _currColorIndex = 0;
            }
            return _colors[_currColorIndex];
        }

        // A set of distinct colors that are iterated through to obtain the
        // presentation color for each new tag
        private static OxyPlot.OxyColor[] _colors = {
            OxyPlot.OxyColors.Red,
            OxyPlot.OxyColors.Green,
            OxyPlot.OxyColors.Blue,
            OxyPlot.OxyColors.Purple,
            OxyPlot.OxyColors.Orange,
            OxyPlot.OxyColors.Teal,
            OxyPlot.OxyColors.Black,
            OxyPlot.OxyColors.Gray,
            OxyPlot.OxyColors.Brown,
            OxyPlot.OxyColors.Navy,
            OxyPlot.OxyColors.Crimson,
            OxyPlot.OxyColors.DarkGreen
        };
        private static int _currColorIndex = -1;

        // Return an Enumerable handle to the tag read data
        public IEnumerable<TagRead> Reads
        {
            get
            {
                return new List<TagRead>(_tagReads);
            }
        }
    }
}
