/*
         * Note1:
         *   "Mapping.MidiBinding" comes without type by some reason.
         *   Workaound inspects the types explicitelly
         *   We could use AGenericMidiDefinition.Parse but then we had to generte the string by hand
         *
         * Note2:
         *   "Type" is not C#. Its about traktor "in"/"out"
         *
         */
        private AGenericMidiDefinition incDecGeneric(AGenericMidiDefinition old, int step, IncDecWhat what)
        {
            if (old is ComboMidiDefinition)
            {
                var specific = (ComboMidiDefinition)old;

                return(new ComboMidiDefinition(
                           incDecGeneric(specific.MidiDefinition1, step, what),
                           incDecGeneric(specific.MidiDefinition2, step, what)));
            }

            // at this stage we always have a channel
            int old_channel = old.Channel;
            int new_channel = incDec_channel(old_channel, step, what);

            if (old is NoteMidiDefinition)
            {
                var specific     = (NoteMidiDefinition)old;
                var keyConverter = new MidiLib.Utils.KeyConverter();

                int    old_value = keyConverter.ToKeyIPN(specific.KeyText);
                int    new_value = incDec_note(old_value, step, what);
                string new_note  = keyConverter.GetKeyTextIPN(new_value);

                return(new NoteMidiDefinition(old.Type, new_channel, new_note));
            }

            if (old is ControlChangeMidiDefinition)
            {
                var specific = (ControlChangeMidiDefinition)old;

                int new_value = incDec_note(specific.Cc, step, what);

                return(new ControlChangeMidiDefinition(old.Type, new_channel, new_value));
            }

            // this should never be reached!
            return(null);
        }
        ////////////


        private void applyMidiRange()
        {
            var templateBinding = _mappings.First().MidiBinding as AGenericMidiDefinition;

            var isCC = templateBinding is ControlChangeMidiDefinition;

            var keyConverter = new MidiLib.Utils.KeyConverter();

            int number = isCC ? (templateBinding as ControlChangeMidiDefinition).Cc : keyConverter.ToKeyIPN((templateBinding as NoteMidiDefinition).KeyText);

            AGenericMidiDefinition newBinding;

            foreach (var m in _mappings)
            {
                if (m.MidiBinding != null && m.MidiBinding.Equals(templateBinding))
                {
                    continue;
                }

                number++;

                if (isCC)
                {
                    newBinding = new ControlChangeMidiDefinition(templateBinding.Type, templateBinding.Channel, number);
                }
                else
                {
                    newBinding = new NoteMidiDefinition(templateBinding.Type, templateBinding.Channel, keyConverter.GetKeyTextIPN(number));
                }

                m.SetBinding(newBinding);
            }

            analyzeSelection();
            updateMenus();
        }
        private void incDecNote(MappingViewModel mapping, int step)
        {
            var oldBinding = mapping.MidiBinding as NoteMidiDefinition;

            var keyConverter = new MidiLib.Utils.KeyConverter();
            var oldKey       = keyConverter.ToKeyIPN(oldBinding.KeyText);
            int newKey       = oldKey + step;

            mapping.SetBinding(new NoteMidiDefinition(oldBinding.Type, oldBinding.Channel, keyConverter.GetKeyTextIPN(newKey)));
        }