/// <summary>
        /// Gets the type of signal and srips this identifier from the signal label.
        /// </summary>
        /// <param name="signalLabel">The signal label.</param>
        /// <returns>The type of signal label</returns>
        public static EdfPlusSignalType GetAndStripEdfplusSignalType(ref string signalLabel)
        {
            EdfPlusSignalType type = GetEdfPlusSignalType(signalLabel);

            if (type == EdfPlusSignalType.Unknown)
            {
                return(type);
            }

            string signalTypeStr = EdfPlusSignalTypeHelper.GetEdfPlusSignalTypeName(type);

            signalLabel = signalLabel.Remove(0, signalTypeStr.Length);
            signalLabel = signalLabel.TrimStart();
            int idx = 0;

            while (idx >= 0)
            {
                idx = signalLabel.IndexOf(signalTypeStr, idx);
                if ((idx < 0) || (!IsOperator(signalLabel[idx - 1])))
                {
                    idx = -1;
                    continue;
                }
                signalLabel = signalLabel.Remove(idx, signalTypeStr.Length);
                while (((idx < signalLabel.Length - 1) && (signalLabel[idx] == ' ')))
                {
                    signalLabel = signalLabel.Remove(idx, 1);
                }
            }
            return(type);
        }
        /// <summary>
        /// Check if the label is a valid EDF+ label.
        /// </summary>
        /// <param name="signalLabel">The signal label.</param>
        /// <param name="physicalDimension">The physical dimension.</param>
        /// <returns><c>true</c> if signal label is a valid EDF+ label; otherwise <c>false</c></returns>
        public static bool ValidEdfPlusLabel(string signalLabel, string physicalDimension = null)
        {
            string            s    = signalLabel;
            EdfPlusSignalType type = GetAndStripEdfplusSignalType(ref s);

            // If the signal type string is repeated, the result is false
            if (!string.IsNullOrEmpty(s) && s.IndexOf(EdfPlusSignalTypeHelper.GetEdfPlusSignalTypeName(type), StringComparison.InvariantCulture) >= 0)
            {
                return(false);
            }

            switch (type)
            {
            case EdfPlusSignalType.EEG:
                if (!IsEEGDerivation(s))
                {
                    return(false);
                }
                break;

            case EdfPlusSignalType.ECG:
                if (!IsECGDerivation(s))
                {
                    return(false);
                }
                break;

            case EdfPlusSignalType.Unknown:
                return(false);
            }

            int signalType = (int)type;

            if (string.IsNullOrEmpty(physicalDimension) ||
                (EdfPlusSignalTypeHelper.EdfPlusSignalTypeBaseDim[signalType, 0] == string.Empty))
            {
                return(true);
            }

            int i = 0;

            while (i < EdfPlusSignalTypeHelper.EdfPlusSignalTypeBaseDim.GetUpperBound(1))
            {
                if (EdfPlusSignalTypeHelper.EdfPlusSignalTypeBaseDim[signalType, i] != string.Empty)
                {
                    if (SameBaseDimension(physicalDimension, EdfPlusSignalTypeHelper.EdfPlusSignalTypeBaseDim[signalType, i]))
                    {
                        return(true);
                    }
                }
                i++;
            }

            return(false);
        }
        /// <summary>
        /// Gets the type of the edf plus signal.
        /// </summary>
        /// <param name="signalLabel">The signal label.</param>
        /// <returns></returns>
        public static EdfPlusSignalType GetEdfPlusSignalType(string signalLabel)
        {
            EdfPlusSignalType i = EdfPlusSignalType.Distance;

            while (i < EdfPlusSignalType.Unknown)
            {
                // Check if the signallabel start with the EDF+ signal type name
                if (signalLabel.ToUpper().IndexOf(EdfPlusSignalTypeHelper.GetEdfPlusSignalTypeName(i).ToUpper()) == 0)
                {
                    return(i);
                }
                i++;
            }
            return(EdfPlusSignalType.Unknown);
        }
        /// <summary>
        /// Simplifies the EDF+ label.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <returns>The simplified label.</returns>
        public static string EdfPlusMakeSimpleLabel(string label)
        {
            string s;

            // Check format "EEG C3-M2-(O2-M1)+M2-M1"
            if (ValidEdfPlusLabel(label))
            {
                s = label;
                EdfPlusSignalType signalType = GetAndStripEdfplusSignalType(ref s);
                return(s != string.Empty
                 ? EdfPlusSignalTypeHelper.GetEdfPlusSignalTypeName(signalType) + " " + MakeSimpleLabel(s)
                 : label);
            }
            s = MakeSimpleCombinedLabel(label);
            return(s != label ? s : MakeSimpleLabel(label));
        }
 /// <summary>
 /// Gets the name of the edf plus signal type.
 /// </summary>
 /// <param name="signalType">Type of the signal.</param>
 /// <returns>The name of the signal type.</returns>
 public static string GetEdfPlusSignalTypeName(EdfPlusSignalType signalType)
 {
     int i = Convert.ToInt32(signalType);
       return EdfPlusSignalTypeNames[i];
 }
        /// <summary>
        /// Makes a simple label from a combination label.
        /// </summary>
        /// <param name="label">The label.</param>
        /// <returns></returns>
        public static string MakeSimpleCombinedLabel(string label)
        {
            // if null or empty, return the label itself
            if (string.IsNullOrEmpty(label) || label.Trim().Equals(string.Empty))
            {
                return(label);
            }

            List <string> list = new List <string>();

            // The following regular expression splits a string like "EEG Fpz-Cz-(EEG Pz-O2)+EEG Fpz-Cz-(EEG Pz-Oz)"
            // into 4 substrings ("EEG Fpz-Cz" , "-(EEG Pz-O2)", "+EEG Fpz-Cz" and "-(EEG Pz-Oz)".
            // It either matches a x(...) string or a string matching up to x(.... or end of line.

            Regex regex = new Regex(@"([+-]?\(.+?\))|(.+?((?=[+-]?[()])|$))");

            MatchCollection matches = regex.Matches(label);

            if (matches.Count > 0)
            {
                foreach (Match m in matches)
                {
                    if (m.Value.StartsWith("("))
                    {
                        list.Add("+" + m.Value);
                    }
                    else if (m.Value.EndsWith(")"))
                    {
                        list.Add(m.Value);
                    }
                    else if (m.Value.StartsWith("+") || m.Value.StartsWith("-"))
                    {
                        list.Add(string.Format("{0}({1})", m.Value[0], m.Value.Substring(1)));
                    }
                    else
                    {
                        list.Add(string.Format("+({0})", m.Value));
                    }
                }
            }

            if (list.Count == 0)
            {
                throw new AssertionException();
            }

            // Check if all signal parts are of the same type
            EdfPlusSignalType signalType = EdfPlusSignalType.Unknown;

            foreach (EdfPlusSignalType t in list.Select(subString => GetEdfPlusSignalType(list[0].Substring(2, list[0].Length - 3))))
            {
                if (t == EdfPlusSignalType.Unknown)
                {
                    return(label);
                }

                switch (signalType)
                {
                case EdfPlusSignalType.Unknown:
                    signalType = t;
                    break;

                default:
                    if (t != signalType)
                    {
                        return(label);
                    }
                    break;
                }
            }

            string s = string.Empty;

            foreach (string t in list)
            {
                string T = t.Substring(2, t.Length - 3);
                GetAndStripEdfplusSignalType(ref T);
                s = string.Format("{0}{1}({2})", s, t.Substring(0, 1), T);
            }
            s = MakeSimpleLabel(s);
            return(string.Format("{0} {1}", EdfPlusSignalTypeHelper.GetEdfPlusSignalTypeName(signalType), s));
        }
        /// <summary>
        /// Gets the name of the edf plus signal type.
        /// </summary>
        /// <param name="signalType">Type of the signal.</param>
        /// <returns>The name of the signal type.</returns>
        public static string GetEdfPlusSignalTypeName(EdfPlusSignalType signalType)
        {
            int i = Convert.ToInt32(signalType);

            return(EdfPlusSignalTypeNames[i]);
        }