using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace FLY.Thick.Base.Common
{
    //格式
    //时间,                           报警码,    总长0,    留白0,     总长1,    留白1,     总长2,    留白2
    //2016-12-30 12:20:30,           0,      300.1,      18.1,      700.1,      18.1,      400.5,      18.1
    //2016-12-30 12:20:30,           0,      299.8,      18.0,      700.5,      18.1,      401.0,      17.7

    public class FlyData_CoatingSegmentHistory : FLY.Thick.RemoteHistory.IFlyData, INotifyPropertyChanged
    {
        private DateTime time;
        public DateTime Time
        { 
            get {
                return time;
            }
            set 
            {
                time = value;
                NotifyPropertyChanged("Time");
            }
        }
        int errno;
        /// <summary>
        /// 报警码, 0 没错误， 1总长报警，2留白报警，3数量错
        /// </summary>
        public int Errno 
        {
            get 
            {
                return errno;
            }
            set 
            {
                errno = value;
                NotifyPropertyChanged("Errno");
            }
        }
        int partcount = 1;
        /// <summary>
        /// 段数，prfile设定，不是测的！！！
        /// </summary>
        public int PartCount
        {
            get {
                return partcount;
            }
            set 
            {
                if (partcount != value)
                {
                    partcount = value;
                    NotifyPropertyChanged("PartCount");
                }
            }
        }
        ObservableCollection<CoatingSegmentPart> coatingPart = new ObservableCollection<CoatingSegmentPart>();

        public ObservableCollection<CoatingSegmentPart> CoatingPart 
        {
            get 
            {
                return coatingPart;
            }
        }


        public string GetHeader()
        {
            string str = "时间,报警码";

            for (int i = 0; i < PartCount; i++)
            {
                str += ",总长" + i.ToString();
                str += ",留白" + i.ToString();
            }
            return str;
        }
        public override string ToString()
        {
            string str;
            str = Time.ToString("yyyy/MM/dd HH:mm:ss") + "," + Errno.ToString();
            for (int i = 0; i < PartCount; i++)
            {
                if (i < CoatingPart.Count)
                {
                    str += "," + CoatingPart[i].Total.ToString("F1");
                    str += "," + CoatingPart[i].Distance.ToString("F1");
                }
                else
                {
                    str += ",,";
                }
            }
            return str;
        }
        public bool TryParse(string header_str, string str)
        {
            CoatingPart.Clear();
            int idx = 0;

            //通过header_str, 解析PartCount
            string[] items_header = header_str.Split(new char[] { ',' });
            if (items_header.Length < 4)
                return false;
            //看最后一个 是“留白x”
            Regex r = new Regex(@"留白\d+");
            Match m = r.Match(items_header.Last());
            if (!m.Success)
                return false;

            r = new Regex(@"\d+");
            PartCount = int.Parse(r.Match(m.Value).Value) + 1;

            //正文
            string[] items = str.Split(new char[] { ',' });
            if (items.Length < (2 + PartCount * 2))
                return false;

            DateTime dt;
            int numi;
            double numd;

            if (!DateTime.TryParse(items[idx], out dt))
                return false;
            idx++;

            Time = dt;

            if (!int.TryParse(items[idx], out numi))
                return false;
            idx++;

            Errno = numi;

            for (int i = 0; i < PartCount; i++)
            {
                if (string.IsNullOrWhiteSpace(items[idx]))
                {
                    idx += 2;
                }

                CoatingSegmentPart cp = new CoatingSegmentPart();


                if (!double.TryParse(items[idx], out numd))
                    return false;
                idx++;

                cp.Total = numd;

                if (!double.TryParse(items[idx], out numd))
                    return false;
                idx++;

                cp.Distance = numd;
                CoatingPart.Add(cp);
            }
            return true;
        }

        /// <summary>
        /// 最少12个字节转换
        /// </summary>
        /// <param name="value">需要转换的字符串</param>
        /// <param name="offset">在字符串的偏移</param>
        /// <param name="count">转换的字符数</param>
        /// <returns></returns>
        public bool TryParse(byte[] value, int offset, out int count)
        {
            int idx = offset;
            count = 8 + 4 + 4 + 4;
            if (value.Length - offset < count)
                return false;

            CoatingPart.Clear();
            Time = new DateTime(BitConverter.ToInt64(value, idx));
            idx += 8;
            Errno = BitConverter.ToInt32(value, idx);
            idx += 4;
            PartCount = BitConverter.ToInt32(value, idx);
            idx += 4;
            int c = BitConverter.ToInt32(value, idx);
            idx += 4;

            count += c * 16;
            if (value.Length - offset < count)
                return false;

            for (int i = 0; i < c; i++)
            {
                CoatingSegmentPart p = new CoatingSegmentPart();
                p.TryParse(value, idx);
                idx += 16;
                CoatingPart.Add(p);
            }
            return true;
        }
        public byte[] ToBytes()
        {
            List<byte> buf = new List<byte>();
            buf.AddRange(BitConverter.GetBytes(Time.Ticks));
            buf.AddRange(BitConverter.GetBytes(Errno));
            buf.AddRange(BitConverter.GetBytes(PartCount));
            int cnt = (PartCount < CoatingPart.Count) ? PartCount : CoatingPart.Count;

            buf.AddRange(BitConverter.GetBytes(cnt));
            for (int i = 0; i < cnt; i++)
                buf.AddRange(CoatingPart[i].ToByte());

            return buf.ToArray();
        }

        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyname));
            }
        }
        #endregion
    }
}
