示例#1
0
        private string GenerateDplCDisplayParameters(ControllerModel controller)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("void display_parameters(void)");
            sb.AppendLine("{");

            sb.AppendLine($"{ts}/* fasecycli */");
            sb.AppendLine($"{ts}/* --------- */");

            foreach (FaseCyclusModel fcm in controller.Fasen)
            {
                sb.Append(GetCoordinatesString(fcm as IOElementModel, fcm.GetDefine(), "us"));
            }

            sb.AppendLine();

            sb.AppendLine($"{ts}/* detectie */");
            sb.AppendLine($"{ts}/* -------- */");

            var ovdummydets = controller.OVData.GetAllDummyDetectors();
            var alldets     = controller.GetAllDetectors().Concat(ovdummydets);

            foreach (var dm in alldets.Where(x => !x.Dummy))
            {
                sb.Append(GetCoordinatesString(dm as IOElementModel, dm.GetDefine(), "is"));
            }

            if (alldets.Any(x => x.Dummy))
            {
                sb.AppendLine("#if (!defined AUTOMAAT_TEST)");
                foreach (var dm in alldets.Where(x => x.Dummy))
                {
                    sb.Append(GetCoordinatesString(dm as IOElementModel, dm.GetDefine(), "is"));
                }
                sb.AppendLine("#endif");
            }

            sb.AppendLine();

            sb.AppendLine($"{ts}/* overige uitgangen */");
            sb.AppendLine($"{ts}/* ----------------- */");

            foreach (var item in AllCCOLOutputElements.Where(x => !x.Dummy))
            {
                if (item.Element != null)
                {
                    sb.Append(GetCoordinatesString(item.Element, item.Naam, "us"));
                }
            }
            if (AllCCOLOutputElements.Any(x => x.Dummy))
            {
                sb.AppendLine("#if (!defined AUTOMAAT_TEST)");
                foreach (var item in AllCCOLOutputElements.Where(x => x.Dummy))
                {
                    if (item.Element != null)
                    {
                        sb.Append(GetCoordinatesString(item.Element, item.Naam, "us"));
                    }
                }
                sb.AppendLine("#endif");
            }

            foreach (var item in AllOutputModelElements)
            {
                sb.Append(GetCoordinatesString(item, _uspf + item.Naam, "us"));
            }

            sb.AppendLine();

            sb.AppendLine($"{ts}/* overige ingangen */");
            sb.AppendLine($"{ts}/* ---------------- */");


            foreach (var item in AllCCOLInputElements.Where(x => !x.Dummy))
            {
                if (item.Element != null)
                {
                    sb.Append(GetCoordinatesString(item.Element, item.Naam, "is"));
                }
            }

            foreach (var item in AllInputModelElements.Where(x => !x.Dummy))
            {
                sb.Append(GetCoordinatesString(item, _ispf + item.Naam, "is"));
            }


            if (AllCCOLInputElements.Any(x => x.Dummy) || AllInputModelElements.Any(x => x.Dummy))
            {
                sb.AppendLine("#if (!defined AUTOMAAT_TEST)");
            }
            if (AllCCOLInputElements.Any(x => x.Dummy))
            {
                foreach (var item in AllCCOLInputElements.Where(x => x.Dummy))
                {
                    if (item.Element != null)
                    {
                        sb.Append(GetCoordinatesString(item.Element, item.Naam, "is"));
                    }
                }
            }
            if (AllInputModelElements.Any(x => x.Dummy))
            {
                foreach (var item in AllInputModelElements.Where(x => x.Dummy))
                {
                    sb.Append(GetCoordinatesString(item, _ispf + item.Naam, "is"));
                }
            }
            if (AllCCOLInputElements.Any(x => x.Dummy) || AllInputModelElements.Any(x => x.Dummy))
            {
                sb.AppendLine("#endif");
            }

            sb.AppendLine();

            sb.AppendLine($"{ts}/* Gebruikers toevoegingen file includen */");
            sb.AppendLine($"{ts}/* ------------------------------------- */");
            sb.AppendLine($"{ts}#include \"{controller.Data.Naam}dpl.add\"");

            sb.AppendLine();
            sb.AppendLine("}");

            return(sb.ToString());
        }
示例#2
0
        private string GenerateSysHDetectors(ControllerModel controller)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("/* detectie */");
            sb.AppendLine("/* -------- */");

            int pad1 = "ISMAX".Length;

            if (controller.Fasen.Any() && controller.Fasen.SelectMany(x => x.Detectoren).Any())
            {
                pad1 = controller.Fasen.SelectMany(x => x.Detectoren).Max(x => x.GetDefine().Length);
            }
            if (controller.Detectoren.Any())
            {
                int _pad1 = controller.Detectoren.Max(x => x.GetDefine().Length);
                pad1 = _pad1 > pad1 ? _pad1 : pad1;
            }
            if (controller.SelectieveDetectoren.Any())
            {
                int _pad1 = controller.SelectieveDetectoren.Max(x => x.GetDefine().Length);
                pad1 = _pad1 > pad1 ? _pad1 : pad1;
            }
            var ovdummies = controller.OVData.GetAllDummyDetectors();

            if (ovdummies.Any())
            {
                pad1 = ovdummies.Max(x => x.GetDefine().Length);
            }
            pad1 = pad1 + $"{ts}#define  ".Length;

            int pad2 = controller.Fasen.Count.ToString().Length;

            int index = 0;

            foreach (var dm in controller.GetAllDetectors())
            {
                if (!dm.Dummy)
                {
                    sb.Append($"{ts}#define {dm.GetDefine()} ".PadRight(pad1));
                    sb.AppendLine($"{index.ToString()}".PadLeft(pad2));
                    ++index;
                }
            }

            int autom_index = index;

            /* Dummies */
            if (controller.Fasen.Any() && controller.Fasen.SelectMany(x => x.Detectoren).Where(x => x.Dummy).Any() ||
                controller.Detectoren.Any() && controller.Detectoren.Where(x => x.Dummy).Any() ||
                ovdummies.Any())
            {
                sb.AppendLine("#if (!defined AUTOMAAT && !defined AUTOMAAT_TEST) || defined VISSIM || defined _VRIWINTEST");
                foreach (var dm in controller.GetAllDetectors(x => x.Dummy))
                {
                    sb.Append($"{ts}#define {dm.GetDefine()} ".PadRight(pad1));
                    sb.AppendLine($"{index.ToString()}".PadLeft(pad2));
                    ++index;
                }
                foreach (var dm in ovdummies)
                {
                    sb.Append($"{ts}#define {dm.GetDefine()} ".PadRight(pad1));
                    sb.AppendLine($"{index.ToString()}".PadLeft(pad2));
                    ++index;
                }
                sb.Append($"{ts}#define DPMAX1 ".PadRight(pad1));
                sb.Append($"{index.ToString()} ".PadLeft(pad2));
                sb.AppendLine("/* aantal detectoren testomgeving */");
                sb.AppendLine("#else");
                sb.Append($"{ts}#define DPMAX1 ".PadRight(pad1));
                sb.Append($"{autom_index.ToString()} ".PadLeft(pad2));
                sb.AppendLine("/* aantal detectoren automaat omgeving */");
                sb.AppendLine("#endif");
            }
            else
            {
                sb.Append($"{ts}#define DPMAX1 ".PadRight(pad1));
                sb.Append($"{index.ToString()} ".PadLeft(pad2));
                sb.AppendLine("/* aantal detectoren */");
            }

            return(sb.ToString());
        }
        private string GenerateDplCExtraDefines(ControllerModel controller)
        {
            var sb = new StringBuilder();

            sb.AppendLine("/* aantal ingangs-/uitgangs signalen */");
            sb.AppendLine("/* --------------------------------- */");
            var usmaxplus = 0;
            var ismaxplus = 0;

            foreach (var fcm in controller.Fasen)
            {
                if (fcm.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < fcm.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {fcm.GetDefine()}_{i} (USMAX + {usmaxplus})");
                        ++usmaxplus;
                    }
                }
            }

            foreach (var item in AllCCOLOutputElements)
            {
                if (item.Element?.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < item.Element.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {item.Naam}_{i} (USMAX + {usmaxplus})");
                        ++usmaxplus;
                    }
                }
            }

            foreach (var item in AllOutputModelElements)
            {
                if (item.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < item.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {_uspf}{item.Naam}_{i} (USMAX + {usmaxplus})");
                        ++usmaxplus;
                    }
                }
            }

            var alldets = controller.GetAllDetectors().Concat(controller.PrioData.GetAllDummyDetectors());

            foreach (var dm in alldets)
            {
                if (dm.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < dm.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {dm.GetDefine()}_{i} (ISMAX + {ismaxplus})");
                        ++ismaxplus;
                    }
                }
            }

            foreach (var item in AllCCOLInputElements)
            {
                if (item.Element?.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < item.Element.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {item.Naam}_{i} (ISMAX + {ismaxplus})");
                        ++ismaxplus;
                    }
                }
            }

            foreach (var item in AllInputModelElements)
            {
                if (item.BitmapCoordinaten?.Count > 1)
                {
                    for (var i = 1; i < item.BitmapCoordinaten.Count; ++i)
                    {
                        sb.AppendLine($"{ts}#define {_ispf}{item.Naam}_{i} (ISMAX + {ismaxplus})");
                        ++ismaxplus;
                    }
                }
            }

            sb.AppendLine();

            sb.AppendLine($"{ts}#define USDPLMAX (USMAX + {usmaxplus})");
            sb.AppendLine($"{ts}#define ISDPLMAX (ISMAX + {ismaxplus})");

            return(sb.ToString());
        }
示例#4
0
        private string GenerateTabCControlParametersDetectors(ControllerModel controller)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("/* detectie */");
            sb.AppendLine("/* -------- */");

            int defmax  = 0;
            int namemax = 0;
            int?dbmax   = 0;
            int?dhmax   = 0;
            int?ogmax   = 0;
            int?bgmax   = 0;
            int?tflmax  = 0;

            var ovdummydets = controller.OVData.GetAllDummyDetectors();
            var alldets     = controller.GetAllDetectors().Concat(ovdummydets);

            var nondummydets   = alldets.Where(x => !x.Dummy);
            var detectorModels = nondummydets as DetectorModel[] ?? nondummydets.ToArray();

            foreach (var dm in alldets.Where(x => !x.Dummy))
            {
                if (dm.GetDefine()?.Length > defmax)
                {
                    defmax = dm.GetDefine().Length;
                }
                if (dm.Naam?.Length > namemax)
                {
                    namemax = dm.Naam.Length;
                }
                if (dm.TDB != null && dm.TDB > dbmax)
                {
                    dbmax = dm.TDB;
                }
                if (dm.TDH != null && dm.TDH > dhmax)
                {
                    dhmax = dm.TDH;
                }
                if (dm.TOG != null && dm.TOG > ogmax)
                {
                    ogmax = dm.TOG;
                }
                if (dm.TBG != null && dm.TBG > bgmax)
                {
                    bgmax = dm.TBG;
                }
                if (dm.TFL != null && dm.TFL > tflmax)
                {
                    tflmax = dm.TFL;
                }
            }
            dbmax  = dbmax.ToString().Length;
            dhmax  = dhmax.ToString().Length;
            ogmax  = ogmax.ToString().Length;
            bgmax  = bgmax.ToString().Length;
            tflmax = tflmax.ToString().Length;

            int pad1 = "D_code[] ".Length + defmax;
            int pad2 = "= \"\"; ".Length + namemax;
            int pad3 = "TDB_max[] ".Length + defmax;
            int pad4 = "= ; ".Length + Math.Max(dbmax ?? 0, bgmax ?? 0);
            int pad5 = "TDH_max[] ".Length + defmax;
            int pad6 = pad1 + pad2;
            var pad7 = "TFL_max[] = ;".Length + defmax + tflmax;

            foreach (var dm in alldets)
            {
                if (!dm.Dummy)
                {
                    AppendDetectorTabString(sb, dm, pad1, pad2, pad3, pad4, pad5, pad6);
                }
            }

            if (detectorModels.Any(x => x.TFL != null || x.CFL != null))
            {
                sb.AppendLine("#if !defined NO_DDFLUTTER");
                foreach (var dm in detectorModels)
                {
                    AppendDetectorFlutterTabString(sb, dm, pad7);
                }
                sb.AppendLine("#endif // !defined NO_DDFLUTTER");
            }

            /* Dummies */
            var dummydets = alldets.Where(x => x.Dummy);

            detectorModels = dummydets as DetectorModel[] ?? dummydets.ToArray();
            if (detectorModels.Any())
            {
                dbmax = dhmax = ogmax = bgmax = tflmax = defmax = namemax = 0;
                foreach (var dm in detectorModels)
                {
                    if (dm.GetDefine()?.Length > defmax)
                    {
                        defmax = dm.GetDefine().Length;
                    }
                    if (dm.Naam?.Length > namemax)
                    {
                        namemax = dm.Naam.Length;
                    }
                    if (dm.TDB != null && dm.TDB > dbmax)
                    {
                        dbmax = dm.TDB;
                    }
                    if (dm.TDH != null && dm.TDH > dhmax)
                    {
                        dhmax = dm.TDH;
                    }
                    if (dm.TOG != null && dm.TOG > ogmax)
                    {
                        ogmax = dm.TOG;
                    }
                    if (dm.TBG != null && dm.TBG > bgmax)
                    {
                        bgmax = dm.TBG;
                    }
                    if (dm.TFL != null && dm.TFL > tflmax)
                    {
                        tflmax = dm.TFL;
                    }
                }
                dbmax  = dbmax.ToString().Length;
                dhmax  = dhmax.ToString().Length;
                ogmax  = ogmax.ToString().Length;
                bgmax  = bgmax.ToString().Length;
                tflmax = tflmax.ToString().Length;
                pad1   = "D_code[] ".Length + defmax;
                pad2   = "= \"\"; ".Length + namemax;
                pad3   = "TDB_max[] ".Length + defmax;
                pad4   = "= ; ".Length + Math.Max(dbmax ?? 0, bgmax ?? 0);
                pad5   = "TDH_max[] ".Length + defmax;
                pad6   = pad1 + pad2;
                pad7   = "TFL_max[] = ;".Length + defmax + tflmax;

                sb.AppendLine("#if (!defined AUTOMAAT && !defined AUTOMAAT_TEST) || defined PRACTICE_TEST");
                foreach (var dm in detectorModels)
                {
                    AppendDetectorTabString(sb, dm, pad1, pad2, pad3, pad4, pad5, pad6);
                }
                if (detectorModels.Any(x => x.TFL != null || x.CFL != null))
                {
                    sb.AppendLine("#if !defined NO_DDFLUTTER");
                    foreach (var dm in detectorModels)
                    {
                        AppendDetectorFlutterTabString(sb, dm, pad7);
                    }
                    sb.AppendLine("#endif // !defined NO_DDFLUTTER");
                }
                sb.AppendLine("#endif");
            }

            return(sb.ToString());
        }
示例#5
0
        private string GenerateTabCControlParametersIOTypes(ControllerModel c)
        {
            var sb = new StringBuilder();

            sb.AppendLine("/* Typen ingangen */");
            sb.AppendLine("/* -------------- */");

            var ds = new List <string>();
            DetectorTypeEnum prev = DetectorTypeEnum.Kop;

            foreach (DetectorModel dm in c.GetAllDetectors())
            {
                if (c.Data.CCOLVersie >= CCOLVersieEnum.CCOL9)
                {
                    if (prev != DetectorTypeEnum.VecomDetector &&
                        (dm.Type == DetectorTypeEnum.VecomDetector || dm.Type == DetectorTypeEnum.OpticomIngang))
                    {
                        sb.AppendLine("#ifndef NO_CVN_50");
                    }
                    if ((prev == DetectorTypeEnum.VecomDetector || prev == DetectorTypeEnum.OpticomIngang) &&
                        dm.Type != DetectorTypeEnum.VecomDetector)
                    {
                        sb.AppendLine("#else");
                        foreach (var d in ds)
                        {
                            sb.AppendLine($"{ts}IS_type[{_dpf}{d}] = DS_type;");
                        }
                        ds.Clear();
                        sb.AppendLine("#endif");
                    }
                }
                sb.Append($"{ts}IS_type[{_dpf}{dm.Naam}] = ");
                switch (dm.Type)
                {
                case DetectorTypeEnum.Knop:
                case DetectorTypeEnum.KnopBinnen:
                case DetectorTypeEnum.KnopBuiten:
                    sb.AppendLine("DK_type;");
                    break;

                case DetectorTypeEnum.File:
                case DetectorTypeEnum.Verweg:
                    sb.AppendLine("DL_type | DVER_type;");
                    break;

                case DetectorTypeEnum.Kop:
                    sb.AppendLine("DL_type | DKOP_type;");
                    break;

                case DetectorTypeEnum.Lang:
                    sb.AppendLine("DL_type | DLNG_type;");
                    break;

                case DetectorTypeEnum.OpticomIngang:
                case DetectorTypeEnum.VecomDetector:
                    // TODO: it is possible to use DKOP and DVER to mark in- and uitmelding: use? how?
                    if (c.Data.CCOLVersie >= CCOLVersieEnum.CCOL9)
                    {
                        sb.AppendLine("DSI_type;");
                        ds.Add(dm.Naam);
                    }
                    else
                    {
                        sb.AppendLine("DS_type;");
                    }
                    break;

                case DetectorTypeEnum.Overig:
                    sb.AppendLine("DL_type;");
                    break;

                case DetectorTypeEnum.WisselStandDetector:
                case DetectorTypeEnum.WisselDetector:
                case DetectorTypeEnum.WisselStroomKringDetector:
                case DetectorTypeEnum.Radar:
                    sb.AppendLine("DL_type | DKOP_type;");
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Unknown detector type while generating tab.c: " + dm.Type.ToString());
                }
                prev = dm.Type;
            }

            sb.AppendLine();
            sb.AppendLine("/* Typen uitgangen */");
            sb.AppendLine("/* --------------- */");

            foreach (FaseCyclusModel fc in c.Fasen)
            {
                sb.Append($"{ts}US_type[{_fcpf}{fc.Naam}] = ");
                switch (fc.Type)
                {
                case Models.Enumerations.FaseTypeEnum.Auto:
                    sb.AppendLine("MVT_type;");
                    break;

                case Models.Enumerations.FaseTypeEnum.OV:
                    sb.AppendLine("OV_type;");
                    break;

                case Models.Enumerations.FaseTypeEnum.Fiets:
                    sb.AppendLine("FTS_type;");
                    break;

                case Models.Enumerations.FaseTypeEnum.Voetganger:
                    sb.AppendLine("VTG_type;");
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Unknown vehicle type while generating tab.c: " + fc.Type.ToString());
                }
            }

            if (c.Data.CCOLVersie > CCOLVersieEnum.CCOL8 &&
                AllCCOLInputElements.Any(x => x.Multivalent))
            {
                sb.AppendLine();
                sb.AppendLine($"{ts}/* Multivalente ingangen */");
                sb.AppendLine($"#if !defined NO_VLOG_300");
                foreach (var i in AllCCOLInputElements.Where(x => x.Multivalent))
                {
                    sb.AppendLine($"{ts}IS_type[{i.Naam}] = ISM_type;");
                }
                sb.AppendLine("#endif /* NO_VLOG_300 */");
            }
            if (c.Data.CCOLVersie > CCOLVersieEnum.CCOL8 &&
                AllCCOLOutputElements.Any(x => x.Multivalent))
            {
                sb.AppendLine();
                sb.AppendLine($"{ts}/* Multivalente ingangen */");
                sb.AppendLine($"#if !defined NO_VLOG_300");
                foreach (var i in AllCCOLOutputElements.Where(x => x.Multivalent))
                {
                    sb.AppendLine($"{ts}US_type[{i.Naam}] = USM_type;");
                }
                sb.AppendLine("#endif /* NO_VLOG_300 */");
            }

            return(sb.ToString());
        }
示例#6
0
        public static Tuple <bool, string> ApplyCombinatieTemplate(ControllerModel c, CombinatieTemplateModel t)
        {
            var alert = "";

            // check options
            foreach (var opt in t.Opties)
            {
                switch (opt.Type)
                {
                case CombinatieTemplateOptieTypeEnum.Fase:
                    var fc = c.Fasen.FirstOrDefault(x => x.Naam == opt.Replace);
                    if (fc == null)
                    {
                        return(new Tuple <bool, string>(false, $"Fase {opt.Replace} komt niet voor in deze regeling; template niet toegepast."));
                    }
                    break;
                }
            }

            // gather and check items
            var items = new List <Tuple <object, object> >();

            foreach (var i in t.Items)
            {
                var             o   = i.GetObject();
                var             ok  = true;
                FaseCyclusModel fc1 = null;
                FaseCyclusModel fc2 = null;
                FaseCyclusModel fc3 = null;
                foreach (var opt in t.Opties)
                {
                    switch (opt.Type)
                    {
                    case CombinatieTemplateOptieTypeEnum.Fase:
                        var tfc = c.Fasen.FirstOrDefault(x => x.Naam == opt.Replace);
                        if (tfc != null)
                        {
                            var r = ChangeStringOnObject(o, opt.Search, opt.Replace);
                            if (r > 0)
                            {
                                if (fc1 == null)
                                {
                                    fc1 = tfc;
                                }
                                else if (fc2 == null)
                                {
                                    fc2 = tfc;                       // as of yet: unused
                                }
                                else if (fc3 == null)
                                {
                                    fc3 = tfc;                       // as of yet: unused
                                }
                            }
                        }
                        break;

                    case CombinatieTemplateOptieTypeEnum.Int:
                        ChangeIntOnObject(o, int.Parse(opt.Search), int.Parse(opt.Replace));
                        break;

                    case CombinatieTemplateOptieTypeEnum.String:
                        ChangeStringOnObject(o, opt.Search, opt.Replace);
                        break;
                    }
                }
                switch (i.Type)
                {
                case CombinatieTemplateItemTypeEnum.Detector:
                    if (c.GetAllDetectors().Any(x => x.Naam == ((DetectorModel)o).Naam))
                    {
                        alert += $"De regeling bevat reeds een detector met de naam {((DetectorModel)o).Naam}.\n";
                    }
                    else if (fc1 != null)
                    {
                        items.Add(new Tuple <object, object>(o, fc1));
                    }
                    else
                    {
                        alert += $"Detector {((DetectorModel)o).Naam} uit de template heeft geen waarde voor de fase; deze wordt niet toegevoegd.\n";
                    }
                    break;

                case CombinatieTemplateItemTypeEnum.Naloop:
                case CombinatieTemplateItemTypeEnum.Meeaanvraag:
                case CombinatieTemplateItemTypeEnum.Gelijkstart:
                case CombinatieTemplateItemTypeEnum.LateRelease:
                    var ise = (IInterSignaalGroepElement)o;
                    if (Integrity.TLCGenControllerChecker.IsFasenConflicting(c, ise.FaseVan, ise.FaseNaar))
                    {
                        return(new Tuple <bool, string>(false, $"Fasen {ise.FaseVan} en {ise.FaseNaar} hebben een conflict; template niet toegepast."));
                    }
                    switch (o)
                    {
                    case NaloopModel nl:
                        if (c.InterSignaalGroep.Nalopen.Any(x => x.FaseVan == nl.FaseVan && x.FaseNaar == nl.FaseNaar))
                        {
                            alert += $"De regeling bevat reeds een naloop van {nl.FaseVan} naar {nl.FaseNaar}.\n";
                            ok     = false;
                        }
                        break;

                    case MeeaanvraagModel ma:
                        if (c.InterSignaalGroep.Meeaanvragen.Any(x => x.FaseVan == ma.FaseVan && x.FaseNaar == ma.FaseNaar))
                        {
                            alert += $"De regeling bevat reeds een meeaanvraag van {ma.FaseVan} naar {ma.FaseNaar}.\n";
                            ok     = false;
                        }
                        break;

                    case GelijkstartModel gs:
                        if (c.InterSignaalGroep.Gelijkstarten.Any(x => x.FaseVan == gs.FaseVan && x.FaseNaar == gs.FaseNaar))
                        {
                            alert += $"De regeling bevat reeds een gelijkstart van {gs.FaseVan} naar {gs.FaseNaar}.\n";
                            ok     = false;
                        }
                        break;

                    case LateReleaseModel lr:
                        if (c.InterSignaalGroep.LateReleases.Any(x => x.FaseVan == lr.FaseVan && x.FaseNaar == lr.FaseNaar))
                        {
                            alert += $"De regeling bevat reeds een late release van {lr.FaseVan} naar {lr.FaseNaar}.\n";
                            ok     = false;
                        }
                        break;
                    }
                    if (ok)
                    {
                        items.Add(new Tuple <object, object>(o, null));
                    }
                    break;

                case CombinatieTemplateItemTypeEnum.Rateltikker:
                    if (!c.Signalen.Rateltikkers.Any(x => x.FaseCyclus == ((RatelTikkerModel)o).FaseCyclus))
                    {
                        items.Add(new Tuple <object, object>(o, null));
                    }
                    else
                    {
                        alert += $"De regeling bevat reeds rateltikker voor fase {((RatelTikkerModel)o).FaseCyclus}.\n";
                    }
                    break;
                }
            }

            // apply
            foreach (var i in items)
            {
                switch (i.Item1)
                {
                case DetectorModel d:
                    var fc = (FaseCyclusModel)i.Item2;
                    fc.Detectoren.Add(d);
                    Messenger.Default.Send(new Messaging.Messages.DetectorenChangedMessage(c, new List <DetectorModel> {
                        d
                    }, null));
                    break;

                case NaloopModel nl:
                    c.InterSignaalGroep.Nalopen.Add(nl);
                    Messenger.Default.Send(new Messaging.Messages.InterSignaalGroepChangedMessage(nl.FaseVan, nl.FaseNaar, nl, isnew: true));
                    break;

                case MeeaanvraagModel ma:
                    c.InterSignaalGroep.Meeaanvragen.Add(ma);
                    Messenger.Default.Send(new Messaging.Messages.InterSignaalGroepChangedMessage(ma.FaseVan, ma.FaseNaar, ma, isnew: true));
                    break;

                case GelijkstartModel gs:
                    c.InterSignaalGroep.Gelijkstarten.Add(gs);
                    Messenger.Default.Send(new Messaging.Messages.InterSignaalGroepChangedMessage(gs.FaseVan, gs.FaseNaar, gs, isnew: true));
                    break;

                case LateReleaseModel lr:
                    c.InterSignaalGroep.LateReleases.Add(lr);
                    Messenger.Default.Send(new Messaging.Messages.InterSignaalGroepChangedMessage(lr.FaseVan, lr.FaseNaar, lr, isnew: true));
                    break;

                case RatelTikkerModel rt:
                    c.Signalen.Rateltikkers.Add(rt);
                    // Trick to force rebuilding list in UI
                    Messenger.Default.Send(new Messaging.Messages.DetectorenChangedMessage(c, null, null));
                    break;
                }
            }
            return(new Tuple <bool, string>(true, alert));
        }