using System.Collections.Generic;

namespace InABox.DigitalMatter
{
    public enum GPSStatus
    {
        Valid,
        ThreeDimensional,
        NoSignal
    }

    public class DMGPSField : DMField
    {
        public override byte Type => 0x00;

        public uint TimeStamp { get; set; }
        public int Latitude { get; set; }
        public int Longitude { get; set; }
        public short Altitude { get; set; }
        public ushort Speed { get; set; }
        public byte SpeedAccuracy { get; set; }
        public byte Heading { get; set; }
        public byte PDOP { get; set; }
        public byte GPSAccuracy { get; set; }
        public byte Status { get; set; }

        public GPSStatus[] StatusFlags()
        {
            var result = new List<GPSStatus>();
            var flags = IDMBuffer.DecodeByte(Status, 1, 8);
            if (flags[0])
                result.Add(GPSStatus.Valid);
            if (flags[1])
                result.Add(GPSStatus.ThreeDimensional);
            if (flags[2])
                result.Add(GPSStatus.NoSignal);
            return result.ToArray();
        }

        public override bool IsValid()
        {
            return Status != 0;
        }


        public override string ToString()
        {
            return string.Format("{0:dd MMM yy hh-mm-ss} Lat: {1:F6} Lng: {2:F6} Status: {3}", TimeStampToDateTime(TimeStamp),
                (double)Latitude / 10000000.0F, (double)Longitude / 10000000.0F, string.Join(",", StatusFlags()));
        }

        protected override void DoDecode(IDMReadBuffer buffer)
        {
            TimeStamp = buffer.TakeUInt32();
            Latitude = buffer.TakeInt32();
            Longitude = buffer.TakeInt32();
            Altitude = buffer.TakeInt16();
            Speed = buffer.TakeByte();
            SpeedAccuracy = buffer.TakeByte();
            Heading = buffer.TakeByte();
            PDOP = buffer.TakeByte();
            GPSAccuracy = buffer.TakeByte();
            Status = buffer.TakeByte();
        }

        protected override void DoEncode(IDMWriteBuffer buffer)
        {
            buffer.AddUInt32(TimeStamp);
            buffer.AddInt32(Latitude);
            buffer.AddInt32(Longitude);
            buffer.AddInt16(Altitude);
            buffer.AddUInt16(Speed);
            buffer.AddByte(SpeedAccuracy);
            buffer.AddByte(Heading);
            buffer.AddByte(PDOP);
            buffer.AddByte(GPSAccuracy);
            buffer.AddByte(Status);
        }
    }
}