using System;
using System.Text.RegularExpressions;
using Aitex.Core.RT.Log;
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.OcrReaders
{
    public interface IReaderMsg
    {
        string package(params object[] args);
        /// 
        /// return value, completed
        /// 
        /// 
        /// 
        bool unpackage(string type, string[] items);
        bool background { get; } 
    }
    public class handler : IHandler  
    {
        public int ID { get; set; }
        public int Unit { get; set; }
        public bool IsBackground { get { return _imp.background; } }
        
        private static int retry_time = 1;
        private int retry_count = retry_time;
        private IReaderMsg _imp  ;
                
        private object[] _objs = null;
        public handler(IReaderMsg imp, params object[] objs)
        {
            _imp = imp; 
            this._objs = objs;
        }
        public bool Execute(ref TPort port) where TPort : ICommunication
        {
            retry_count = retry_time;
            //return port.Write(string.Format("{0}\r", _imp.package(this._objs)));
            return port.Write(string.Format("{0}\r\n", _imp.package(this._objs)));
        }
        /// 
        /// return value: bhandle
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public bool OnMessage(ref TPort port, string message, out bool completed) where TPort : ICommunication
        {
            completed = false;
            try
            {
                string msg = message.Trim();
                if (msg.IndexOf("Welcome") >= 0)
                {
                    return true;
                }
                msg = msg.Replace("User:","");
                if (string.IsNullOrWhiteSpace(msg))
                {
                    return true;
                }
                if (msg.Length <= 2)
                {
                    if (!msg.Equals("1"))  //0: command failed
                    {
                        if (retry_count-- <= 0)
                        {
                            string warning = string.Format("retry over {0} times", retry_time);
                            //LOG.Warning(warning);
                            if (!IsBackground)
                                throw (new ExcuteFailedException(warning));
                            else
                            {
                                completed = true;
                                return true;
                            }
                            
                        }
                        port.Write(string.Format("{0}\r\n", _imp.package(this._objs)));
                    }
                    if (!IsBackground)
                    {
                        _imp.unpackage("", null);
                        completed = true;
                    }
       
                    return true;
                }
                if (IsBackground)
                {
                    msg = message.TrimStart('[');
                    msg = msg.TrimEnd(']');
                    string[] data = Regex.Split(msg, ",");
                    completed = _imp.unpackage("", data);
                    //              if (!completed)
                    //              {
                    //                  port.Write(string.Format("{0}\r", _imp.package(this._objs)));  //read failed. retry
                    //              }
                }
                return true;
            }
            catch (ExcuteFailedException e)
            {
                throw (e);
            }
            catch (Exception ex)
            {
                LOG.WriteExeption(ex);
                throw (new InvalidPackageException(message));
            }
        }
    }
    public class ReadHandler : IReaderMsg   //common move
    {
        public bool background { get; private set; }
        private OcrReader _device ;
        public ReadHandler(OcrReader device)
        {
            _device = device;
            background = true;
        }
        public string package(params object[] args)
        {
            return string.Format("SM\"READ\"0 ");
        }
        public bool unpackage(string type, string[] items)
        {
            if (_device.ReadLaserMaker)
            {
                _device.LaserMaker = items[0];
            }
            else
            { 
                _device.T7Code = items[0];
            }
            _device.ReadOK = double.Parse(items[2]) > 0;
            return true;
        }
    }
    public class OnlineHandler : IReaderMsg   //common move
    {
        public bool background { get; private set; }
        private OcrReader _device ;
        private bool _online = false;
        public OnlineHandler(OcrReader device)
        {
            _device = device;
            background = false;
        }
        public string package(params object[] args)
        {
            _online = (bool)args[0];
            if(_online)
                return string.Format("SO1");
            return string.Format("SO0");
        }
        public bool unpackage(string type, string[] items)
        {
            return true;
        }
    }
    public class GetJobHandler : IReaderMsg   
    {
        public bool background { get; private set; }
        private OcrReader _device ;
        public GetJobHandler(OcrReader device)
        {
            _device = device;
            background = true;
        }
        public string package(params object[] args)
        {
            return string.Format("GF");
        }
        public bool unpackage(string type, string[] items)
        {
            _device.JobName = (string)items[0];
            return true;
        }
    }
    public class LoadJobHandler : IReaderMsg   //common move
    {
        public bool background { get; private set; }
        private OcrReader _device ;
        private string _job;
        public LoadJobHandler(OcrReader device)
        {
            _device = device;
            background = false;
        }
        public string package(params object[] args)
        {
            _job = (string)args[0];    //full path
      //      _job = _job.Substring(_job.LastIndexOf("\\") + 1);  //remove dir
      //      _job = _job.Substring(0, _job.LastIndexOf("."));  //remove expand
            return string.Format("LF{0}.job",_job);
        }
        public bool unpackage(string type, string[] items)
        {
            _device.JobName = _job;
            return true;
        }
    }
}