using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Mesnac.Action.ChemicalWeighing
{
    /// <summary>
    /// PLC参数写入项
    /// </summary>
    public class PlcWriteItem
    {
        #region 构造方法

        public PlcWriteItem()
        {
            this.EquipBrand = String.Empty;
            this.DataFieldName = string.Empty;
            this.EquipRunName = string.Empty;
            this.DataType = string.Empty;
            this.PlcShifting = 0;
            this.DefaultValue = 0;
            this.ValueLen = 1;
            this.Multiply = 1;
            this.SetValue = null;
        }

        #endregion

        #region 公有属性

        /// <summary>
        /// 所属PLC设备品牌
        /// </summary>
        public string EquipBrand { get; set; }
        /// <summary>
        /// 数据库字段名
        /// </summary>
        public string DataFieldName { get; set; }
        /// <summary>
        /// Plc别名
        /// </summary>
        public string EquipRunName { get; set; }
        /// <summary>
        /// 偏移值
        /// </summary>
        public int PlcShifting { get; set; }
        /// <summary>
        /// 默认值
        /// </summary>
        public int DefaultValue { get; set; }
        /// <summary>
        /// 长度
        /// </summary>
        public int ValueLen { get; set; }
        /// <summary>
        /// 数据处理方式
        /// </summary>
        public string DataType { get; set; }
        /// <summary>
        /// 乘数
        /// </summary>
        public int Multiply { get; set; }
        /// <summary>
        /// 原始值
        /// </summary>
        public object SetValue { get; set; }

        #endregion

        #region 公有方法

        #region 获取PLC写入项数据

        /// <summary>
        /// 获取PLC写入项数据
        /// </summary>
        /// <returns>返回PLC写入项Int16数组</returns>
        public Int16[] WriteData()
        {
            Int16[] result = null;
            Int16[] newResult = new Int16[ValueLen];
            for (int i = 0; i < newResult.Length; i++)
            {
                newResult[i] = 0;
            }
            if (string.IsNullOrWhiteSpace(DataType))
            {
                result = WriteData_Null();
            }
            else if (DataType.Equals("string", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_string();
            }
            else if (DataType.Equals("DateTime", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_DateTime();
            }
            else if (DataType.Equals("Time", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_Time();
            }
            else if (DataType.Equals("Int32", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_Int32();
            }
            else if (DataType.Equals("float", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_float();
            }
            else if (DataType.Equals("Int16", StringComparison.CurrentCultureIgnoreCase))
            {
                result = WriteData_Int16();
            }
            else
            {
                result = WriteData_Null();
            }
            if (result.Length <= ValueLen)
            {
                Array.Copy(result, newResult, result.Length);
            }
            else
            {
                Array.Copy(result, newResult, ValueLen);
            }
            return newResult;
        }

        #endregion

        #region 清空PLC写入项数据

        /// <summary>
        /// 清空PLC写入项数据
        /// </summary>
        public void ClearData()
        {
            this.SetValue = null;
        }

        #endregion

        #endregion

        #region 辅助方法

        #region 乘法,遍历参数数组中的每个元素,让每个元素乘以this.Multiply

        /// <summary>
        /// 乘法,遍历参数数组中的每个元素,让每个元素乘以this.Multiply
        /// </summary>
        /// <param name="buff">参数数组</param>
        /// <returns>返回各元素乘以this.Multiply后的数组</returns>
        private Int16[] MultiplyData(double[] buff)
        {
            Int16[] result = new Int16[buff.Length];
            for (int i = 0; i < buff.Length; i++)
            {
                //result[i] = (int)(buff[i] * this.Multiply);
                result[i] = (Int16)Math.Round(buff[i] * this.Multiply);
            }
            return result;
        }

        private Int16[] MultiplyData(Int16[] buff)
        {
            Int16[] result = new Int16[buff.Length];
            for (int i = 0; i < buff.Length; i++)
            {
                result[i] = (Int16)(buff[i] * this.Multiply);
            }
            return result;
        }

        #endregion

        #region 写入Null值

        /// <summary>
        /// 对空PLC写入项进行数据处理
        /// </summary>
        /// <returns>返回空数据的PLC写入项数组</returns>
        private Int16[] WriteData_Null()
        {
            double[] buff = new double[ValueLen];
            double ivalue = 0;
            if (SetValue != null && SetValue != DBNull.Value && double.TryParse(SetValue.ToString(), out ivalue))
            {
                buff[0] = ivalue;
            }
            else
            {
                buff[0] = 0.0;
            }
            return MultiplyData(buff);
        }

        #endregion

        #region 写入Int32类型值

        /// <summary>
        /// 对Int32类型的PLC写入项进行数据处理,此处要注意不同类型PLC的处理方式
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_Int32()
        {
            Int16[] buff = new Int16[ValueLen];
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = 0;
            }
            Int32 ivalue = 0;
            if (ValueLen / 2 == 1)
            {
                if (SetValue != null && SetValue != DBNull.Value && Int32.TryParse(SetValue.ToString(), out ivalue))
                {
                    Int16[] intValues = new Int16[2];
                    if (this.EquipBrand.Equals("Siemens", StringComparison.CurrentCultureIgnoreCase))
                    {
                        intValues = Mesnac.Basic.DataProcessor.ToSiemensPLCInt16Array(ivalue);
                    }
                    else
                    {
                        intValues = Mesnac.Basic.DataProcessor.ToPLCInt16Array(ivalue);
                    }
                    buff[0] = intValues[0];
                    buff[1] = intValues[1];
                }
            }
            else
            {
                if (SetValue is Int32[])
                {
                    Int32[] setValues = SetValue as Int32[];
                    for (int i = 0; i < setValues.Length; i++)
                    {
                        if (i * 2 >= ValueLen)
                        {
                            break;
                        }
                        Int16[] intValues = new Int16[2];
                        if (this.EquipBrand.Equals("Siemens", StringComparison.CurrentCultureIgnoreCase))
                        {
                            intValues = Mesnac.Basic.DataProcessor.ToSiemensPLCInt16Array(setValues[i]);
                        }
                        else
                        {
                            intValues = Mesnac.Basic.DataProcessor.ToPLCInt16Array(setValues[i]);
                        }
                        buff[i * 2] = intValues[0];
                        buff[i * 2 + 1] = intValues[1];
                    }
                }
            }
            return buff;
        }

        #endregion

        #region 写入float类型值

        /// <summary>
        /// 对float类型的PLC写入项进行数据处理,此处要注意不同类型PLC的处理方式
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_float()
        {
            Int16[] buff = new Int16[ValueLen];
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = 0;
            }
            float fvalue = 0.0f;
            if (ValueLen / 2 == 1)
            {
                if (SetValue != null && SetValue != DBNull.Value && float.TryParse(SetValue.ToString(), out fvalue))
                {
                    Int16[] intValues = new Int16[2];
                    if (this.EquipBrand.Equals("Siemens", StringComparison.CurrentCultureIgnoreCase))
                    {
                        intValues = Mesnac.Basic.DataProcessor.ToSiemensPLCInt16Array(fvalue);
                    }
                    else
                    {
                        intValues = Mesnac.Basic.DataProcessor.ToPLCInt16Array(fvalue);
                    }
                    buff[0] = intValues[0];
                    buff[1] = intValues[1];
                }
            }
            else
            {
                if (SetValue is float[])
                {
                    float[] setValues = SetValue as float[];
                    for (int i = 0; i < setValues.Length; i++)
                    {
                        if (i * 2 >= ValueLen)
                        {
                            break;
                        }
                        Int16[] intValues = new Int16[2];
                        if (this.EquipBrand.Equals("Siemens", StringComparison.CurrentCultureIgnoreCase))
                        {
                            intValues = Mesnac.Basic.DataProcessor.ToSiemensPLCInt16Array(setValues[i]);
                        }
                        else
                        {
                            intValues = Mesnac.Basic.DataProcessor.ToPLCInt16Array(setValues[i]);
                        }
                        buff[i * 2] = intValues[0];
                        buff[i * 2 + 1] = intValues[1];
                    }
                }
            }
            return buff;
        }

        #endregion

        #region 写入Int16类型值

        /// <summary>
        /// 对Int16类型的PLC写入项进行数据处理
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_Int16()
        {
            Int16[] buff = new Int16[ValueLen];
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = 0;
            }
            Int16 ivalue = 0;
            if (ValueLen == 1)
            {
                if (SetValue != null && SetValue != DBNull.Value && Int16.TryParse(SetValue.ToString(), out ivalue))
                {
                    buff[0] = ivalue;
                }
            }
            else
            {
                if (SetValue is Int16[])
                {
                    Int16[] setValues = SetValue as Int16[];
                    for (int i = 0; i < setValues.Length; i++)
                    {
                        if (i >= ValueLen)
                        {
                            break;
                        }
                        buff[i] = setValues[i];
                    }
                }
            }
            return buff;
        }

        #endregion

        #region 写入String类型值

        /// <summary>
        /// 把字符串解析为PLC地址块数据
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_string()
        {
            string ss = string.Empty;
            if (SetValue != null && SetValue != DBNull.Value)
            {
                ss = SetValue.ToString();
            }

            Int16[] buff = Mesnac.Basic.DataProcessor.ToPLCInt16Array(ss);

            #region 补够长度

            Int16[] buffResult = new Int16[this.ValueLen];
            Array.Copy(buff, buffResult, buff.Length);

            #endregion


            return MultiplyData(buffResult);
        }

        #endregion

        #region 写入DateTime类型值

        /// <summary>
        /// 处理日期时间写入项
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_DateTime()
        {
            string ss = string.Empty;
            if (SetValue != null && SetValue != DBNull.Value)
            {
                ss = SetValue.ToString();
            }
            DateTime dtNow = DateTime.Now;
            if (!DateTime.TryParse(ss, out dtNow))
            {
                dtNow = DateTime.Now;
            }
            //double[] buff = new double[] { dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second };
            Int16[] buff = Mesnac.Basic.DataProcessor.ToPLCInt16Array(dtNow);
            return MultiplyData(buff);
        }

        #endregion

        #region 写入Time类型值

        /// <summary>
        /// 处理时间写入项
        /// </summary>
        /// <returns></returns>
        private Int16[] WriteData_Time()
        {
            string ss = string.Empty;
            if (SetValue != null && SetValue != DBNull.Value)
            {
                ss = SetValue.ToString();
            }

            Int16[] buff = Mesnac.Basic.DataProcessor.ToPLCInt16ArrayFromTimeStr(ss);
            return MultiplyData(buff);
        }

        #endregion

        #endregion
    }
}