/// <summary>
        /// The divide.
        /// </summary>
        /// <param name="congenericTrack">
        /// The congeneric track.
        /// </param>
        /// <param name="paramPauseTreatment">
        /// The param pause treatment.
        /// параметр как учитывать паузу :
        /// игнорировать, звуковой след предыдущего звука, вырожденныый звук
        /// </param>
        /// <param name="paramEqualFM">
        /// The param equal fm.
        /// как сравнивать ф-мотивы с секвентым переносом, либо нет
        /// </param>
        /// <returns>
        /// The <see cref="FmotivChain"/>.
        /// </returns>
        public FmotivChain Divide(CongenericScoreTrack congenericTrack, ParamPauseTreatment paramPauseTreatment, ParamEqualFM paramEqualFM)
        {
            // сохраняем имя цепи фмотивов как имя монотрека
            var priorityDiscover = new PriorityDiscover();
            var fmotivDivider = new FmotivDivider();
            var fmotivIdentifier = new FmotivIdentifier();

            // подсчет приоритетов
            priorityDiscover.Calculate(congenericTrack);

            // разбиение
            FmotivChain chain = fmotivDivider.GetDivision(congenericTrack, paramPauseTreatment);

            // нахождение одинаковых
            return fmotivIdentifier.GetIdentification(chain, paramPauseTreatment, paramEqualFM);
        }
        public void PriorityDiscoverTest()
        {
            var notes = new List<ValueNote> { note, bnote, anote };
            var notes1 = new List<ValueNote> { note, note, note };
            var notes2 = new List<ValueNote> { anote, note, bnote, note, bnote };
            var notes3 = new List<ValueNote> { note, dnote, note, note };
            var notes4 = new List<ValueNote> { сnote, сnote, сnote, ccnote, ccnote, ccnote };
            var notes5 = new List<ValueNote> { сccnote, сccnote, сccnote, сccnote, сccnote, сccnote, сccnote, note, note };

            var measure = new Measure(notes, attributes);
            var measure1 = new Measure(notes1, attributes1);
            var measure2 = new Measure(notes2, attributes2);
            var measure3 = new Measure(notes3, attributes3);
            var measure4 = new Measure(notes4, attributes1);
            var measure5 = new Measure(notes5, attributes);

            var prioritydiscover = new PriorityDiscover();

            Assert.AreEqual(-1, measure.NoteList[0].Priority);
            Assert.AreEqual(-1, measure.NoteList[1].Priority);
            Assert.AreEqual(-1, measure.NoteList[2].Priority);

            prioritydiscover.Calculate(measure);
            prioritydiscover.Calculate(measure1);
            prioritydiscover.Calculate(measure2);
            prioritydiscover.Calculate(measure3);
            prioritydiscover.Calculate(measure4);
            prioritydiscover.Calculate(measure5);

            Assert.AreEqual(0, measure.NoteList[0].Priority);
            Assert.AreEqual(2, measure.NoteList[1].Priority);
            Assert.AreEqual(1, measure.NoteList[2].Priority);

            Assert.AreEqual(0, measure1.NoteList[0].Priority);
            Assert.AreEqual(1, measure1.NoteList[1].Priority);
            Assert.AreEqual(1, measure1.NoteList[2].Priority);

            Assert.AreEqual(0, measure2.NoteList[0].Priority);
            Assert.AreEqual(1, measure2.NoteList[1].Priority);
            Assert.AreEqual(1, measure2.NoteList[2].Priority);
            Assert.AreEqual(1, measure2.NoteList[3].Priority);
            Assert.AreEqual(1, measure2.NoteList[4].Priority);

            Assert.AreEqual(0, measure3.NoteList[0].Priority);
            Assert.AreEqual(1, measure3.NoteList[1].Priority);
            Assert.AreEqual(2, measure3.NoteList[2].Priority);
            Assert.AreEqual(2, measure3.NoteList[3].Priority);

            Assert.AreEqual(0, measure4.NoteList[0].Priority);
            Assert.AreEqual(1, measure4.NoteList[1].Priority);
            Assert.AreEqual(1, measure4.NoteList[2].Priority);
            Assert.AreEqual(1, measure4.NoteList[3].Priority);
            Assert.AreEqual(2, measure4.NoteList[4].Priority);
            Assert.AreEqual(2, measure4.NoteList[5].Priority);

            Assert.AreEqual(0, measure5.NoteList[0].Priority);
            Assert.AreEqual(3, measure5.NoteList[1].Priority);
            Assert.AreEqual(2, measure5.NoteList[2].Priority);
            Assert.AreEqual(3, measure5.NoteList[3].Priority);
            Assert.AreEqual(3, measure5.NoteList[4].Priority);
            Assert.AreEqual(3, measure5.NoteList[5].Priority);
            Assert.AreEqual(3, measure5.NoteList[6].Priority);
            Assert.AreEqual(1, measure5.NoteList[7].Priority);
            Assert.AreEqual(2, measure5.NoteList[8].Priority);

            Assert.AreEqual(-1, note.Priority);
            Assert.AreEqual(-1, bnote.Priority);
            Assert.AreEqual(-1, anote.Priority);
        }
        public void PriorityMinDurationTest()
        {
            var pd = new PriorityDiscover();

            var notes = new List<ValueNote> { note, bnote, dnote, anote };
            var measure = new Measure(notes, attributes);

            // минимальнвя длительность ноты в такте measure 1/16 = 0.0625 у ноты dnote
            Assert.IsTrue(Math.Abs(pd.MinDuration(measure) - 0.0625) < 0.00001);

            // когда такт передается пустой, должен выкинуться эксепшн
            measure.NoteList.Clear();
            try
            {
                Assert.IsTrue(Math.Abs(pd.MinDuration(measure) - 0.0625) < 0.00001);
                Assert.Fail("нет эксепшна при пустом такте");
            }
            catch (Exception e)
            {
                if (e.Message != "LibiadaMusic.OIP: обнаружен пустой такт при выявлении приоритета!")
                {
                    Assert.Fail();
                }
            }
        }
        public void PriorityMaskCalculationThirdTest()
        {
            var pd = new PriorityDiscover();

            var notes = new List<ValueNote> { note, bnote, dnote, anote };
            var measure = new Measure(notes, attributes3);
            pd.CalculatePriorityMask(measure);

            // так как минимальная длительность ноты в такте 1/16 то маска приоритетов должна разложиться (посчитаться) до 1/32
            // размер 13/16, поэтому будет считаться приоритет для 26/32 нот
            Assert.AreEqual(0, pd.PriorityMask.NoteList[0].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[1].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[2].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[3].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[4].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[5].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[6].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[7].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[8].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[9].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[10].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[11].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[12].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[13].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[14].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[15].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[16].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[17].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[18].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[19].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[20].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[21].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[22].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[23].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[24].Priority);
            Assert.AreEqual(3, pd.PriorityMask.NoteList[25].Priority);

            // проверка длительностей
            foreach (var lnote in pd.PriorityMask.NoteList)
            {
                Assert.AreEqual(1, lnote.Duration.Numerator);
                Assert.AreEqual(32, lnote.Duration.Denominator);
            }
        }
        public void PriorityMaskCalculationFourthTest()
        {
            var pd = new PriorityDiscover();

            var notes = new List<ValueNote> { note, anote };
            var measure = new Measure(notes, attributes1);
            pd.CalculatePriorityMask(measure);

            // так как минимальная длительность ноты в такте 1/4 то маска приоритетов должна разложиться (посчитаться) до 1/4
            // размер 3/4, поэтому будет считаться приоритет для 3/4 нот
            Assert.AreEqual(0, pd.PriorityMask.NoteList[0].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[1].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[2].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[3].Priority);
            Assert.AreEqual(1, pd.PriorityMask.NoteList[4].Priority);
            Assert.AreEqual(2, pd.PriorityMask.NoteList[5].Priority);

            // проверка длительностей
            foreach (var lnote in pd.PriorityMask.NoteList)
            {
                Assert.AreEqual(1, lnote.Duration.Numerator);
                Assert.AreEqual(8, lnote.Duration.Denominator);
            }
        }