private void incDecMapping(MappingViewModel mapping, int step, IncDecWhat what)
        {
            var oldBinding = mapping.MidiBinding as AGenericMidiDefinition;

            if (oldBinding != null)
            {
                mapping.SetBinding(incDecGeneric(oldBinding, step, what));
            }
        }
        public void IncDecMappings(int step, IncDecWhat what)
        {
            foreach (var mapping in _mappings)
            {
                incDecMapping(mapping, step, what);
            }

            analyzeSelection(true);
            updateMenus(false, true);
        }
        private int incDec_note(int old, int step, IncDecWhat what)
        {
            if (what != IncDecWhat.Number)
            {
                step = 0;
            }

            int new_i = old + step;

            if (new_i < 0)
            {
                new_i = 0;
            }

            if (new_i > 127)
            {
                new_i = 127;
            }

            return(new_i);
        }
        // note: channels do not wrap around on purpose
        private int incDec_channel(int old, int step, IncDecWhat what)
        {
            if (what != IncDecWhat.Channel)
            {
                step = 0;
            }

            int new_i = old + step;

            if (new_i <= 1)
            {
                new_i = 1;
            }

            if (new_i > 16)
            {
                new_i = 16;
            }

            return(new_i);
        }
        /*
         * 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);
        }