using System;

namespace McMaster.MultiVis.BackEnd
{
    public class MultiVisMeasurementNetworkParser : IDataParser
    {
        // 0     1  2       3         4          5               6          7                8           9           10        11        12        13       14
        // plot, 2, run_no, frame_no, sensor_no, measurement_id, origin_id, time,            x_pos,      y_pos,      var_x,    cov_xy,   cov_yx,   var_y,   <EOL>
        // plot, 2, 1,      1,        0,         1,              1,         1294754983.4030, -1825.9523, -6508.7564, 383.8955, -97.5964, -97.5964, 63.3847, <EOL>
        public virtual bool TryParse(string xiRawData, out object xoData)
        {
            Assert.NonEmptyString(xiRawData, "xiRawData");

            xoData = null;

            bool result = false;

            string [] values = xiRawData.Split(new char [] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if(values.Length > 0 && values[0].Trim().CompareTo("plot") == 0)
            {
                bool eol = false;
                bool eot = false;
                bool eos = false;

                bool hasFields = values.Length > 2 && values[2].Trim().CompareTo("fields") == 0;

                if(!hasFields)
                {
                    eol = values[values.Length-1].CompareTo(DataProvider.kEol) == 0;

                    if(!eol)
                    {
                        eot = values[values.Length-1].CompareTo(DataProvider.kEot) == 0;

                        if(!eot)
                        {
                            eos = values[values.Length-1].CompareTo(DataProvider.kEos) == 0;
                        }
                    }
                }

                if(eol || eot || eos || hasFields)
                {
                    Data.Measurement measurement = new Data.Measurement();

                    measurement.timestamp = DateTime.Now;

                    if(eol || eot)
                    {
                        if(values.Length > 9)
                        {
                            int transmitterNumber;

                            if(int.TryParse(values[4], out transmitterNumber))
                            {
                                measurement.transmitterNumber = transmitterNumber;
                            }

                            if(eol)
                            {
                                long timestamp;

                                if(long.TryParse(values[4], out timestamp))
                                {
                                    measurement.rawTimestamp = timestamp;
                                }

                                double value;

                                if(double.TryParse(values[8], out value))
                                {
                                    measurement.xPos = value;
                                }

                                if(double.TryParse(values[9], out value))
                                {
                                    measurement.yPos = value;
                                }

                                measurement.operation = EDataOperation.eUpdateData;
                            }
                            else
                            {
                                measurement.operation = EDataOperation.eRemoveData;
                            }

                            xoData = measurement;

                            result = true;
                        }
                    }
                    else if(hasFields)
                    {
                        measurement.operation = EDataOperation.eAddData;

                        xoData = measurement;

                        result = true;
                    }
                    else if(eos)
                    {
                        measurement.operation = EDataOperation.eClearData;

                        xoData = measurement;

                        result = true;
                    }
                }
            }

            return result;
        }

        public virtual bool TryParse(byte [] xiRawData, out object xoData)
        {
            Assert.NonNullReference(xiRawData, "xiRawData");

            xoData = null;

            bool result = false;

            return result;
        }
    }
}
