private void GetChannelGroups()
        {
            foreach (var item in tabChannel.Items)
            {
                if (item is TabItem)
                {
                    TabItem ti = item as TabItem;
                    if (ti.Content is ucChannel)
                    {
                        ucChannel    uc = ti.Content as ucChannel;
                        ChannelGroup cg = channelGroups.First(x => x.Clock.ID == uc.ID);
                        uc.SetObj(cg);
                    }
                }
            }

            for (int i = 0; i < channelGroups.Count; i++)
            {
                for (int j = i + 1; j < channelGroups.Count; j++)
                {
                    var cgi = channelGroups[i];
                    var cgj = channelGroups[j];
                    if (cgi.VIO.ID == cgj.Clock.ID || cgi.VIO.ID == cgj.Data.ID || cgi.VIO.ID == cgj.VIO.ID)
                    {
                        throw new Exception("VIO has duplicated channel no. - " + cgi.VIO.ID + "!");
                    }
                }
            }
        }
        private List <ChannelGroup> ParseChannelGroups(string ChnsOfClock, string ChnsOfData)
        {
            List <ChannelGroup> values = new List <ChannelGroup>();

            string[] clockChannels = ChnsOfClock.Split(',');
            string[] dataChannels  = ChnsOfData.Split(',');
            if (clockChannels.Length > 0 && dataChannels.Length > 0 && clockChannels.Length == dataChannels.Length)
            {
                int channel = 0;
                for (int i = 0; i < clockChannels.Length; i++)
                {
                    ChannelGroup value = new ChannelGroup();

                    if (int.TryParse(clockChannels[i], out channel))
                    {
                        if (channel >= 1 && channel <= 32)
                        {
                            value.Clock.ID = channel;
                        }
                        else
                        {
                            throw new Exception(ChnsOfClock + "should be within 1 ~ 32!");
                        }
                    }
                    else
                    {
                        throw new Exception(ChnsOfClock + " should be unsigned integer!");
                    }

                    if (int.TryParse(dataChannels[i], out channel))
                    {
                        if (channel >= 1 && channel <= 32)
                        {
                            value.Data.ID = channel;
                        }
                        else
                        {
                            throw new Exception(ChnsOfData + "should be within 1 ~ 32!");
                        }
                    }
                    else
                    {
                        throw new Exception(ChnsOfData + " should be unsigned integer!");
                    }

                    values.Add(value);
                }
                return(values);
            }
            else
            {
                throw new Exception("Invalid ChannelOfClock - " + ChnsOfClock + " and ChannelOfData - " + ChnsOfData + "!");
            }
        }
        private Tuple <List <Mode>, List <ChannelGroup>, List <TimingSet> > ParsePAT(string filePAT)
        {
            try
            {
                List <Mode>         availableModes         = new List <Mode>();
                List <ChannelGroup> availableChannelGroups = new List <ChannelGroup>();
                List <TimingSet>    availableTimingSets    = new List <TimingSet>();

                using (FileStream fs = new FileStream(filePAT, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (StreamReader sr = new StreamReader(fs))
                    {
                        bool   valid = false;
                        string line  = string.Empty;
                        while ((line = sr.ReadLine()) != null)
                        {
                            if (line == string.Empty)
                            {
                                continue;
                            }
                            else if (line.ToUpper().Trim().StartsWith("//MIPI-CHANNEL"))
                            {
                                line = line.Split(':')[1].Trim();
                                string[] channelGroups = line.Split('|');
                                foreach (var channelgroup in channelGroups)
                                {
                                    int    iClock = 0;
                                    int    iData  = 0;
                                    string sClock = channelgroup.Split(',')[0];
                                    string sData  = channelgroup.Split(',')[1];
                                    if (!int.TryParse(sClock, out iClock))
                                    {
                                        throw new Exception("Invalid channel in " + line);
                                    }
                                    if (!int.TryParse(sData, out iData))
                                    {
                                        throw new Exception("Invalid channel in " + line);
                                    }
                                    ChannelGroup cg = new ChannelGroup();
                                    cg.Clock.ID = iClock;
                                    cg.Data.ID  = iData;
                                    availableChannelGroups.Add(cg);
                                }
                            }
                            else if (line.ToUpper().Trim().StartsWith("//MIPI-TS"))
                            {
                                line = line.Split(':')[1].Trim();
                                string[] timingSets = line.Split(',');
                                foreach (var timingset in timingSets)
                                {
                                    int id = 0;
                                    if (!int.TryParse(timingset, out id))
                                    {
                                        throw new Exception("Invalid timing set in " + line);
                                    }
                                    TimingSet ts = new TimingSet()
                                    {
                                        ID = id
                                    };
                                    availableTimingSets.Add(ts);
                                }
                            }
                            else if (line.ToUpper().Trim().StartsWith("//MIPI-START"))
                            {
                                valid = true;
                            }
                            else if (line.ToUpper().Trim().StartsWith("//MIPI-END"))
                            {
                                break;
                            }
                            else
                            {
                                if (valid)
                                {
                                    line = line.Substring(2);
                                    string name   = line.Split(':')[0].Trim();
                                    string start  = line.Split(':')[1].Trim().Split('-')[0].Trim();
                                    string end    = line.Split(':')[1].Trim().Split('-')[1].Trim();
                                    int    iStart = 0;
                                    if (!int.TryParse(start, out iStart))
                                    {
                                        throw new Exception("Invalid line in " + line);
                                    }
                                    int iEnd = 0;
                                    if (!int.TryParse(end, out iEnd))
                                    {
                                        throw new Exception("Invalid line in " + line);
                                    }
                                    Mode mode = new Mode()
                                    {
                                        Name = name, LineStart = iStart, LineEnd = iEnd
                                    };
                                    availableModes.Add(mode);
                                }
                            }
                        }
                        sr.Close();
                    }
                }

                if (availableModes.Count == 0)
                {
                    throw new Exception("No available mode detected!");
                }

                if (availableChannelGroups.Count == 0)
                {
                    throw new Exception("No available channel detected!");
                }

                if (availableTimingSets.Count == 0)
                {
                    throw new Exception("No available timing set detected!");
                }

                return(Tuple.Create(availableModes, availableChannelGroups, availableTimingSets));
            }
            catch (Exception ex)
            {
                throw new Exception("Invalid format in " + filePAT + ", please check the header section!\n\n" + ex.Message);
            }
        }
        public void SetObj(ChannelGroup cg)
        {
            int    iValue = 0;
            double dValue = 0;

            if (int.TryParse(txtVioID.Text.Trim(), out iValue))
            {
                if (iValue >= 1 && iValue <= 32)
                {
                    if (cg.Clock.ID == iValue || cg.Data.ID == iValue)
                    {
                        throw new Exception("Channel No. of VIO should not be same as clock's and data's!");
                    }
                    else
                    {
                        cg.VIO.ID = iValue;
                    }
                }
                else
                {
                    throw new Exception("Channel No. of VIO should be within 1 - 32!");
                }
            }
            else
            {
                throw new Exception("Channel No. of VIO should be integer!");
            }

            if (double.TryParse(txtClockVil.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Clock.Vil = dValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s vil should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s vil should be double!");
            }

            if (double.TryParse(txtClockVih.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Clock.Vih = dValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s vih should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s vih should be double!");
            }

            if (double.TryParse(txtClockVol.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Clock.Vol = dValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s vol should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s vol should be double!");
            }

            if (double.TryParse(txtClockVoh.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Clock.Voh = dValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s voh should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s voh should be double!");
            }

            if (double.TryParse(txtDataVil.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Data.Vil = dValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s vil should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s vil should be double!");
            }

            if (double.TryParse(txtDataVih.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Data.Vih = dValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s vih should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s vih should be double!");
            }

            if (double.TryParse(txtDataVol.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Data.Vol = dValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s vol should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s vol should be double!");
            }

            if (double.TryParse(txtDataVoh.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.Data.Voh = dValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s voh should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s voh should be double!");
            }

            if (double.TryParse(txtVioVil.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.VIO.Vil = dValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s vil should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s vil should be double!");
            }

            if (double.TryParse(txtVioVih.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.VIO.Vih = dValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s vih should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s vih should be double!");
            }

            if (double.TryParse(txtVioVol.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.VIO.Vol = dValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s vol should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s vol should be double!");
            }

            if (double.TryParse(txtVioVoh.Text.Trim(), out dValue))
            {
                if (dValue >= 0 && dValue <= 6)
                {
                    cg.VIO.Voh = dValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s voh should be within 0v - 6v!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s voh should be double!");
            }

            if (int.TryParse(txtClockStart.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.Clock.Start = iValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s percentage of start should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s percentage of start should be integer!");
            }

            if (int.TryParse(txtClockStop.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.Clock.Stop = iValue;
                }
                else
                {
                    throw new Exception(cg.Clock.ID + "'s percentage of stop should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.Clock.ID + "'s percentage of stop should be integer!");
            }

            if (int.TryParse(txtDataStart.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.Data.Start = iValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s percentage of start should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s percentage of start should be integer!");
            }

            if (int.TryParse(txtDataStrob.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.Data.Strob = iValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s percentage of Strob should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s percentage of Strob should be integer!");
            }

            if (int.TryParse(txtDataStop.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.Data.Stop = iValue;
                }
                else
                {
                    throw new Exception(cg.Data.ID + "'s percentage of stop should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.Data.ID + "'s percentage of stop should be integer!");
            }

            if (int.TryParse(txtVioStart.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.VIO.Start = iValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s percentage of start should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s percentage of start should be integer!");
            }

            if (int.TryParse(txtVioStop.Text.Trim(), out iValue))
            {
                if (iValue >= 0 && iValue <= 100)
                {
                    cg.VIO.Stop = iValue;
                }
                else
                {
                    throw new Exception(cg.VIO.ID + "'s percentage of stop should be within 0 - 100!");
                }
            }
            else
            {
                throw new Exception(cg.VIO.ID + "'s percentage of stop should be integer!");
            }

            if (rdbPattern.IsChecked == true)
            {
                cg.VIO.DrivePattern = DrivePattern.Pattern;
            }
            else
            {
                cg.VIO.DrivePattern = DrivePattern.Drive;
                cg.VIO.VIO_HL       = (int)cboDrive.SelectedValue;
            }
        }
 public void Set(ChannelGroup channelGroup)
 {
     ID = channelGroup.Clock.ID;
     lblClockID.Text = channelGroup.Clock.ID.ToString();
     lblDataID.Text  = channelGroup.Data.ID.ToString();
 }