using DALI.ToolKit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace DALI.ToolKit.IO
{
    public class Input 
    {
        static readonly DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0);

        public static DateTime DateTimeFromUnixMilliSeconds(long timestamp)
        {
            return unixEpoch.AddMilliseconds(timestamp);
        }

        List<DaliStroke> traces = new List<DaliStroke>();

        public Input(XmlNode node, XmlNamespaceManager manager, Dictionary<string, DaliStroke> pool)
        {
            Id = String.Empty;

            var attr = node.Attributes["xml:id"];
            if (attr != null)
                Id = attr.InnerText;

            var attrTimeOffset = node.Attributes["timeOffset"];
            if (attrTimeOffset != null)
            {
                long timeOffsetParsed;
                if (Int64.TryParse(attrTimeOffset.InnerText, out timeOffsetParsed))
                    TimeOffset = timeOffsetParsed;
            }

            /** discard annotations */
            /*foreach (XmlNode annotation in node.SelectNodes("i:annotation", manager))
            {
                var key = annotation.Attributes["type"].InnerText;
                annotations.Add(new Annotation(key, annotation.InnerText));
            }
            */
            /* discard traceview */
           /* foreach (XmlNode view in node.SelectNodes("i:traceView", manager))
            {
                var dataref = view.Attributes["traceDataRef"].InnerText;
                if (pool.ContainsKey(dataref))
                    traces.Add(pool[dataref]);
                else
                    refs.Add(new Reference() { ReferenceId = dataref });

            }*/
            foreach (XmlNode trace in node.SelectNodes("i:trace", manager))
            {
                var traceType = trace.Attributes["type"];
                var traceErased = trace.Attributes["erased"];
                bool isPenUpTrace = traceType != null && String.Equals(traceType.Value, "penUp");
                bool isErasedTrace = traceErased != null && String.Equals(traceErased.Value, "true");


                if (trace.Attributes["timeOffset"] != null)
                {
                    long timeOffsetParsed;
                    if (Int64.TryParse(trace.Attributes["timeOffset"].InnerText, out timeOffsetParsed))
                    {
                        var timeOffset = DateTimeFromUnixMilliSeconds(timeOffsetParsed);
                        traces.Add(InkmlExtensions.ToTrace(trace.InnerText, timeOffset));
                    }
                }
                else
                {
                    traces.Add(InkmlExtensions.ToTrace(trace.InnerText));
                }

            }         
        }

        public Input(string id, IEnumerable<DaliStroke> traces)
        {
            Id = id;

            this.traces = new List<DaliStroke>(traces);
        }

        private string id;
        public string Id
        {
            get
            {
                return id;
            }
            set
            {
                id = value;

            }
        }

        private long timeOffset;
        public long TimeOffset
        {
            get
            {
                return timeOffset;
            }
            set
            {
                timeOffset = value;
            }
        }

        public IList<DaliStroke> Traces
        {
            get { return traces; }
            set
            {
                traces.Clear();
                foreach (var trace in value)
                    traces.Add(trace);
            }
        }

        public event EventHandler DeleteRequested;

        // ICommand extract;
        // public ICommand Extract
        // {
        //    get
        //    {
        //        if (extract == null)
        //            extract = new RelayCommand(() =>
        //            {
        //                strokefeatures.Clear();
        //                foreach (var trace in traces)
        //                {
        //                    strokefeatures.Add(extractor.Extract(getPoints(trace)).ToList());
        //                }


        //                features = extractor.Extract(getPoints()).ToList();

        //                RaisePropertyChanged(vm => vm.Features);
        //                RaisePropertyChanged(vm => vm.StrokeFeatures);

        //            });
        //        return extract;
        //    }
        // }
    }
}
