using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Runtime.InteropServices;
using SlimDX;

// ========================================================================
//
//                          Warning.cs
//
// Author: Sarah Nimitz, Trevor White           Date: May 2, 2016
// Purpose: Represents a warning created by the National Weather Service.
//          It will include information such as warning type, station
//          issuing the warning, event tracking number (ETN), starting time
//          of the warning, expiration time of the warning, concatenation
//          of all text (severe weather statements) associated with this
//          warning, a list of all associated SevereWeatherStatement
//          objects, and the vertices of the warning geometry. It also
//          contains additonal functions to assist in rendering out the
//          warning geometry using SlimDX.
// 
// ========================================================================

namespace NWSWarnings
{
    // ================================================================
    // An enumeration type that represents the type of warning that is
    // represented by a warning or severe weather statement.
    // ================================================================
    public enum WarningType
    {
        SpecialMarine,
        FlashFlood,
        SevereThunderstorm,
        Tornado,
        TornadoReported,
        TornadoEmergency,
        Unknown
    }

    public class Warning
    {
        // ================================================================
        // Creates a Warning object.
        //
        // @params initStation - A 4-character string that represents the
        //                          station that has issued the warning.
        // @params initTrackingNumber - An integer that represents the
        //                              4-digit ETN of the warning.
        // ================================================================
        public Warning(string initStation, int initTrackingNumber)
        {
            station = initStation;
            trackingNumber = initTrackingNumber;
            statements = new List<SevereWeatherStatement>();
            text = "";
        }
        // ================================================================
        // Creates a Warning object.
        //
        // @params initStation - A 4-character string that represents the
        //                          station that has issued the warning.
        // @params initTrackingNumber - An integer that represents the
        //                              4-digit ETN of the warning.
        // @params initType - Initial WarningType of the Warning object.
        // ================================================================
        public Warning(string initStation, int initTrackingNumber, WarningType initType)
        {
            station = initStation;
            trackingNumber = initTrackingNumber;
            type = initType;
            statements = new List<SevereWeatherStatement>();
            text = "";
        }

        // ================================================================
        //
        // ================================================================
        [StructLayout(LayoutKind.Sequential)]
        public struct CVertex
        {
            public Vector3 Position;
            public int Color;

            public CVertex(Vector3 position, int color)
            {
                this.Position = position;
                this.Color = color;
            }
        }

        // ================================================================
        // A WarningType that currently represents the current type of
        // the warning represented by the Warning object.
        // ================================================================
        private WarningType type;
        public WarningType Type
        {
            get { return this.type; }
            set
            {
                if (value.GetType().Equals(typeof(WarningType)))
                    type = value;
                else
                    // TO-DO: Error
                    return;
            }
        }

        // ================================================================
        // A 4-character string that represents the weather station that
        // has issued this warning.
        // ================================================================
        private string station;
        public string Station
        {
            get { return this.station; }
            private set { station = value; }
        }

        // ================================================================
        // An integer that represents the 4-digit event tracking number (ETN)
        // of this warning.
        // ================================================================
        private int trackingNumber;
        public int TrackingNumber
        {
            get { return this.trackingNumber; }
            private set { trackingNumber = value; }
        }


        // ================================================================
        // A DateTime object that represents the current expiration time
        // of this warning.
        // ================================================================
        private DateTime time;
        public DateTime Time
        {
            get { return this.time; }
            set
            {
                time = value;
            }
        }


        // ================================================================
        // A DateTime object that represents the start time of this warning.
        // ================================================================
        private DateTime start;
        public DateTime Start
        {
            get { return this.start; }
            set
            {
                start = value;
            }
        }


        // ================================================================
        // An array of strings that represents the movements of the
        // associated weather system.
        // This is in the format:
        //      * Time in Zulu the system was last observed
        //      * Degree (from North) of movement
        //      * Speed (in knots) the system is moving
        //      * Latitude of location
        //      * Longitude of location
        //      * [Any additional Lat/Lon pairs]
        // ================================================================
        private string[] movement;
        public string[] Movement
        {
            get { return this.movement; }
            set
            {
                if (value == null)
                    // TO-DO: Error
                    return;

                int tempTime = Convert.ToUInt16(value[0]);
                if (tempTime >= 2400 && tempTime < 0)
                    // TO-DO: Error
                    return;

                int tempDeg = Convert.ToUInt16(value[1]);
                if (tempDeg >= 360 && tempDeg < 0)
                    // TO-DO: Error
                    return;

                int tempSpeed = Convert.ToUInt16(value[2]);
                if (tempSpeed < 0)
                    // TO-DO: Error
                    return;

                movement = value;
            }
        }

        // ================================================================
        // A list of all vertices that form the current geometry of this
        // warning.
        // ================================================================
        private List<PointF> vertices;
        public List<PointF> Vertices
        {
            get { return this.vertices; }
            set
            {
                if (value == null)
                    // TO-DO: Error
                    return;
                foreach (PointF pf in value)
                {
                    if (pf == null)
                        // TO-DO: Error
                        return;
                }

                vertices = value;
            }
        }
        // ================================================================
        // This function will be called at render time to get geometry that SlimDX can handle.
        // ================================================================
        public List<CVertex> GetRenderPolygons(double LatPixelScale, double LonPixelScale, Color ForeColor, float StrokeWidth, float BorderWidth)
        {
            // CVertex usage
            //     CVertex cv = new CVertex(new SlimDX.Vector3(this.x2, this.y2, 1.0F), Color.Red.ToArgb());

            // Triangles will be sent to DirectX to render; should always be wound clockwise.
            return null;
        }

        // ================================================================
        // A string that contains a concatinated list of all severe weather
        // statements' texts associated with this warning, from most recent
        // to its creation.
        // ===============================================================
        private string text;
        public string Text
        {
            get { return this.text; }
            set
            {
                if (value == null)
                    // TO-DO: Error
                    return;

                text = value;
            }
        }

        // ================================================================
        // A list that contains all SevereWeatherStatement objects that are
        // associated with this Warning object.
        // ================================================================
        private List<SevereWeatherStatement> statements;
        public List<SevereWeatherStatement> Statements
        {
            get { return this.statements; }
        }
    }
}
