using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace CRVM.Entity
{


    [DataContract]
    public class SysParam
    {
        //构造函数定义为私有，只能从内部构造，防止外部直接通过new操作符构造一个新的实例
        private static SysParam _intance = null;
        [DataMember]
        public static SysParam Instance
        {
            get
            {
                if (_intance == null)
                    _intance = new SysParam();
                return _intance;
            }
        }
        private SysParam()
        {
            _channel = new EntityChannel[_channelCount];
            for (int i = 0; i < _channelCount; i++)
            {
                EntityChannel ch = new EntityChannel();
                _channel[i] = ch;
            }
        }
        private EntityChannel[] _channel;
        public EntityChannel[] channel
        {
            get { return _channel; }
            set { _channel = value; }
        }

        private readonly int _channelCount = 8;
        /// <summary>
        /// 总采集通道数量
        /// </summary>
        [DataMember]
        public int channelCount
        {
            get { return _channelCount; }
        }
        //private readonly int _SpeedChannelCount = 5;
        private readonly int _SpeedChannelCount = 6;
        /// <summary>
        /// 速度通道数
        /// </summary>
        [DataMember]
        public int SpeedChannelCount
        {
            get { return _SpeedChannelCount; }
        }
        /// <summary>
        /// 采样点数
        /// </summary>
        public int samplePoint { get; set; }
        /// <summary>
        /// 采样频率
        /// </summary>
        public int sampleFre { get; set; }
        /// <summary>
        /// 能量曲线对应显示宽度的数据点数，默认为300秒宽度。
        /// </summary>
        public int energyPoints
        {
            get
            {
                if (samplePoint > 0)
                    return Convert.ToInt32(300 * sampleFre / samplePoint);
                else
                    return 1500;
            }
        }
        /// <summary>
        /// 实时采集时，所显示的时域波形宽度范围对应的数据点数，默认为1秒宽度。
        /// </summary>
        public int timePoints
        {
            get
            {
                if (sampleFre > 0)
                    return sampleFre;
                else
                    return 5120;
            }
        }

        /// <summary>
        /// 板形辊每个脉冲代表的轧制距离，单位：mm_Per_pulse
        /// </summary>
        public double distanceSens { get; set; }
        /// <summary>
        /// 数据处理是否完成
        /// </summary>
        public bool isDatahandlered { get; set; }

        public bool isL2Connected { get; set; }//系统是否能正常连接到L2数据库

        #region 数据查询设置
        public DateTime searchStartTime { get; set; }//数据查询开始时间

        public DateTime searchEndTime { get; set; }//数据查询结束时间

        public bool searchAlarmChecked { get; set; }//数据查询报警选中
        #endregion

        public int OrigDataNum { get; set; }
        public string appPath { get; set; }
        public string IP { get; set; }
        public int Port { get; set; }

        #region 文件存储参数
        public string savePath { get; set; }
        public bool checkTXT { get; set; }//文本
        public bool checkBIT { get; set; }//二进制

        public int saveDaysAlarm { get; set; }
        public int saveDaysNoAlarm { get; set; }
        public bool isFileCleared { get; set; }
        public bool filePrepared { get; set; }
        public bool fileCreated { get; set; }
        #endregion

        #region 显示参数
        public bool BackgroundGridOn { get; set; }
        public bool rollLineVisible { get; set; }
        public int fontSize { get; set; }
        public Color colorTime { get; set; }
        public Color colorFre { get; set; }
        public Color colorEnergy { get; set; }
        public Color colorSpeed { get; set; }
        public Color colorAlarm { get; set; }
        public Color colorDefect { get; set; }
        public Color colorCut { get; set; }
        public Color colorWorkRoll { get; set; }
        public Color colorMidRoll { get; set; }
        public Color colorBackupRoll { get; set; }
        public Color colorBackgroud { get; set; }
        public Color colorFont { get; set; }
        #endregion

        #region 图表显示控制
        //时域图
        public bool checkBoxTime { get; set; }
        public bool checkBoxTimeAll { get; set; }
        public string comboBoxTimeAll { get; set; }
        public bool checkBoxTimeL { get; set; }
        public string comboBoxTimeL { get; set; }
        public bool checkBoxTimeM { get; set; }
        public string comboBoxTimeM { get; set; }
        public bool checkBoxTimeH { get; set; }
        public string comboBoxTimeH { get; set; }
        public bool checkBoxTimeFre { get; set; }
        public string comboBoxTimeFre { get; set; }
        public bool checkBoxTimeFilt { get; set; }
        public string ComboBoxTimeFilt { get; set; }
        public string textBoxf1 { get; set; }
        public string textBoxf2 { get; set; }
        //能量图
        public bool checkBoxEnergy { get; set; }
        public bool checkBoxEnergyAll { get; set; }
        public string comboBoxEnergyAll { get; set; }
        public bool checkBoxEnergyL { get; set; }
        public string comboBoxEnergyL { get; set; }
        public bool checkBoxEnergyM { get; set; }
        public string comboBoxEnergyM { get; set; }
        public bool checkBoxEnergyH { get; set; }
        public string comboBoxEnergyH { get; set; }
        public bool checkBoxEnergySpeed { get; set; }
        public string comboBoxEnergySpeed { get; set; }
        //排列方式
        public bool orderByChannel { get; set; }
        public bool orderBySingleColumn { get; set; }
        public bool orderByStandnoR2L { get; set; }//轧机出口在左侧
        public bool orderByStandnoL2R { get; set; }//轧机出口在右侧
        public bool orderByOther { get; set; }//不按机架排列
        #endregion

        #region 带通滤波、傅立叶算法

        public double[] filterAlgor(double[] array, int f1, int f2, int n, int m, int fs)
        {
            int i, j;
            double x, aa, fl, fh, w;
            double[] b = new double[200];// { };
            int xlen = n;
            //float[] filt = new float[xlen] { };
            double[] filt = new double[xlen];
            aa = Math.PI / m;
            fl = 2 * Math.PI * f1 / fs;
            fh = 2 * Math.PI * f2 / fs;
            w = 2 * Math.PI;

            for (j = 1; j < m; j++)
            {
                b[j] = (1 + Math.Cos(aa * j)) * (Math.Sin(fh * j) - Math.Sin(fl * j)) / (w * j);
            }
            for (i = 0; i < n; i++)
            {
                x = (2 * (fh - fl) / w) * array[i];
                //是否为循环卷积
                for (j = 0; j < m; j++)
                {
                    try
                    {
                        if ((j + i) < n)
                            x += b[j] * array[j + i];

                        if ((i - j) > 0)
                            x += b[j] * array[i - j];
                    }
                    catch (Exception exp)
                    {
                        string s = "i=" + i + ",j=" + j + exp.Message;
                    }
                }
                filt[i] = x;

            }
            return filt;
        }

        public int N2M(int n)
        {
            int x = 2;
            int num = 0;
            while (x <= n)
            {
                x = 2 * x;
                num++;
            }
            return num;
        }

        public void FFT(double[] AR, double[] AI, int N, int ni)
        {
            int i, j, k, L, M, IP, LE, L1, N1, N2;
            double SN, TR, TI, WR, WI, UR, UI, US;
            M = N2M(N);
            N = Convert.ToInt32(Math.Pow(2, M));
            N2 = N / 2;
            N1 = N - 1;
            SN = ni;
            j = 1;
            i = 1;
            while (i <= N1)
            {
                if (i < j)
                {
                    TR = AR[j - 1];
                    AR[j - 1] = AR[i - 1];
                    AR[i - 1] = TR;
                    TI = AI[j - 1];
                    AI[j - 1] = AI[i - 1];
                    AI[i - 1] = TI;
                }
                k = N2;
                while (k < j)
                {
                    j = j - k;
                    k = k / 2;
                }
                j = j + k;
                i++;
            }
            L = 1;
            while (L <= M)
            {
                LE = Convert.ToInt32(Math.Pow(2, L));
                L1 = LE / 2;
                UR = 1.0f;
                UI = 0.0f;
                WR = Math.Cos(Math.PI / L1);
                WI = SN * Math.Sin(Math.PI / L1);
                j = 1;
                while (j <= L1)
                {
                    i = j;
                    while (i <= N)
                    {
                        IP = i + L1;
                        TR = AR[IP - 1] * UR - AI[IP - 1] * UI;
                        TI = AI[IP - 1] * UR + AR[IP - 1] * UI;
                        AR[IP - 1] = AR[i - 1] - TR;
                        AI[IP - 1] = AI[i - 1] - TI;
                        AR[i - 1] = AR[i - 1] + TR;
                        AI[i - 1] = AI[i - 1] + TI;
                        i += LE;
                    }
                    US = UR;
                    UR = US * WR - UI * WI;
                    UI = UI * WR + US * WI;
                    j++;
                }
                L++;
            }
            if (SN == -1)
            {
                i = 1;
                while (i <= N)
                {
                    AR[i - 1] = AR[i - 1] / N;
                    AI[i - 1] = AI[i - 1] / N;
                    i++;
                }
            }
        }

        public double[] newFFT(double[] AR, double[] AI, int N)
        {
            int i, j, k, L, M, IP, LE, L1, N2;
            double SN, TR, TI, WR, WI, UR, UI, US;
            M = N2M(N);
            N = Convert.ToInt32(Math.Pow(2, M));
            N2 = N / 2;
            SN = 1;
            j = 1;
            i = 1;
            while (i < N)
            {
                if (i < j)
                {
                    TR = AR[j - 1];
                    AR[j - 1] = AR[i - 1];
                    AR[i - 1] = TR;
                    TI = AI[j - 1];
                    AI[j - 1] = AI[i - 1];
                    AI[i - 1] = TI;
                }
                k = N2;
                while (k < j)
                {
                    j = j - k;
                    k = k / 2;
                }
                j = j + k;
                i++;
            }
            L = 1;
            while (L <= M)
            {
                LE = Convert.ToInt32(Math.Pow(2, L));
                L1 = LE / 2;
                UR = 1;
                UI = 0;
                WR = Math.Cos(Math.PI / L1);
                WI = SN * Math.Sin(Math.PI / L1);
                j = 1;
                while (j <= L1)
                {
                    i = j;
                    while (i <= N)
                    {
                        IP = i + L1;
                        TR = AR[IP - 1] * UR - AI[IP - 1] * UI;
                        TI = AI[IP - 1] * UR + AR[IP - 1] * UI;
                        AR[IP - 1] = AR[i - 1] - TR;
                        AI[IP - 1] = AI[i - 1] - TI;
                        AR[i - 1] = AR[i - 1] + TR;
                        AI[i - 1] = AI[i - 1] + TI;
                        i += LE;
                    }
                    US = UR;
                    UR = US * WR - UI * WI;
                    UI = UI * WR + US * WI;
                    j++;
                }
                L++;
            }
            double[] temp = new double[N / 2];
            for (i = 0; i < N / 2; i++)
            {
                temp[i] = 2 * Math.Sqrt(AR[i] * AR[i] + AI[i] * AI[i]) / N;
            }
            return temp;
            //if (SN == -1)
            //{
            //    i = 1;
            //    while (i <= N)
            //    {
            //        AR[i - 1] = AR[i - 1] / N;
            //        AI[i - 1] = AI[i - 1] / N;
            //        i++;
            //    }
            //}
        }

        public bool DataIsMatch(string str, string pattern)
        {
            Regex reg = new Regex(pattern);
            if (reg.IsMatch(str))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        public string reTimeSpan { get; set; }
        public int reSampleFre { get; set; }
        public int reSamplePoint { get; set; }

        public double rollDiameterBU
        {
            get { return 1.2230; }
        }
        public double rollDiameterBL
        {
            get { return 1.2230; }
        }
        public double rollDiameterMU
        {
            get { return 0.5363; }
        }
        public double rollDiameterML
        {
            get { return 0.5363; }
        }
        public double rollDiameterWU
        {
            get { return 0.4040; }
        }
        public double rollDiameterWL
        {
            get { return 0.4040; }
        }

        public List<string> onlineList = new List<string>();

        #region 报警铃声设置
        public bool isStand1Ring { get; set; }
        public bool isStand2Ring { get; set; }
        public bool isStand3Ring { get; set; }
        public bool isStand4Ring { get; set; }
        public bool isStand5Ring { get; set; }
        public bool isStand6Ring { get; set; }

        public short ringFre { get; set; }
        public short ringType { get; set; }

        public bool alarming1 { get; set; }
        public bool alarming2 { get; set; }
        public bool alarming3 { get; set; }
        public bool alarming4 { get; set; }
        public bool alarming5 { get; set; }
        public bool alarming6 { get; set; }

        public int alarmingType { get; set; }//0:正常 1：设备异常 2：共振报警

        public bool alarmingS1 { get; set; }//达到报警线的80% 
        public bool alarmingS2 { get; set; }//达到报警线的80% 
        public bool alarmingS3 { get; set; }//达到报警线的80% 
        public bool alarmingS4 { get; set; }//达到报警线的80% 
        public bool alarmingS5 { get; set; }//达到报警线的80% 

        public bool[,] ringflag = new bool[5, 3];
        #endregion

        public bool isOpenAlarm = false;
    }
}
