;;;SimulateMidi
;use the PC keyboard rows asdfghjkl;'# and qwertyuiop[] as a piano keyboard (naturals/accidentals), mimicking the effect of MIDI in. The assignments are for UK keyboard, the script needs updating to allow for re-assigning MIDI keys to PC keypresses.
(define-once SimulateMidi::active #f)
(define-once SimulateMidi::alist-uk  '(("a" . 0) 
                                    ("w" . 1) 
                                    ("s" . 2)
                                    ("e" . 3)
                                    ("d" . 4)
                                    ("f" . 5)
                                    ("t" . 6)
                                    ("g" . 7)
                                    ("y" . 8)
                                    ("h" . 9)
                                    ("u" . 10)
                                    ("j" . 11)
                                    ("k" . 12)
                                    ("o" . 13)
                                    ("l" . 14)
                                    ("p" . 15)
                                    ("semicolon" . 16)
                                    ("apostrophe" . 17)
                                    ("bracketright" . 18)
                                    ("numbersign" . 19)))
(define-once SimulateMidi::alist SimulateMidi::alist-uk)
(if (not SimulateMidi::alist)
    (set! SimulateMidi::alist SimulateMidi::alist-uk))
(let ((startmidiin (d-GetBooleanPref "startmidiin")))

(define (append-to-scm filename)
  (define port (open-file filename "a")) 
    ;not needed (seek port 0 SEEK_END)
    (display "(define SimulateMidi::alist '" port)
    (write SimulateMidi::alist port)
    (display ")" port)
    (close-port port))


(define (setup-keys)
    (d-WarningDialog (_ "Dismiss this dialog then press 20 keys for the 20 notes c'' - g'''. Esc to cancel."))
    (set! SimulateMidi::alist '())
    (let loop ((count 0))
    (define  key (d-GetKeypress))
        (if (equal? key "Escape")
            (begin
                (set! SimulateMidi::alist SimulateMidi::alist-uk))
            (begin
                (set! SimulateMidi::alist (assoc-set! SimulateMidi::alist key count))
                (if (< count 19)
                    (loop (1+ count))
                    (append-to-scm (string-append DENEMO_LOCAL_ACTIONS_DIR "denemo.scm"))
                    )))))

(if SimulateMidi::active
    (d-InfoDialog (_ "Press Escape in the Denemo Main Window to end MIDI keyboard simulation."))
    (let ((pedal #f)(octave 0))  
        (set! SimulateMidi::active #t)
        (d-InputFilterNames (_ "Simulated MIDI Filter: Esc to end."))
        (d-SetBackground #xFFF0D0)
        (d-SetPrefs "<startmidiin>1</startmidiin>")
        (let loop ()
            (define value #f)
            (define key 
                (if SimulateMidi::active (d-GetKeypress) "Escape"))
            (set! value (assoc-ref SimulateMidi::alist key))
            (cond
                ((number? value)
                    (d-PutMidi (+ (* (+ value octave) 256) #xFF3C90)) (loop))
                ((equal? key "Page_Up")
                    (set! octave (+ octave 12))
                    (d-InputFilterNames (string-append (_ "Octave:") (number->string (/ octave 12))))
                    (if (zero? octave)
                        (begin
                            (d-SetBackground #xFFF0D0)
                            (d-InputFilterNames (_ "Simulated MIDI Filter: Esc to end.")))
                        (if (positive? octave)
                            (d-SetBackground #xFFF8E0)
                            (d-SetBackground #xEFE0C0)))
                    (loop))
                ((equal? key "Page_Down")
                    (set! octave (- octave 12))
                    (d-InputFilterNames (string-append (_ "Octave:") (number->string (/ octave 12))))
                    (if (zero? octave)
                        (begin
                            (d-SetBackground #xFFF0D0)
                            (d-InputFilterNames (_ "Simulated MIDI Filter: Esc to end.")))
                            (if (positive? octave)
                                (d-SetBackground #xFFF8E0)
                                (d-SetBackground #xEFE0C0)))
                    (loop))
                                
                ((equal? key "Tab") 
                    (set! pedal (not pedal))
                    (if pedal 
                        (begin
                            (d-PutMidi #x7F40B0)   
                            (d-SetBackground #xD0F0FF)      
                            (loop))
                        (begin
                            (d-PutMidi #x0040B0) 
                            (d-SetBackground #xFFF0D0)      
                            (loop))))
                ((equal? key "Ctrl+Escape")
                  (setup-keys))  
                ((not (equal? key "Escape")) 
                        (d-GetKeypress #f) ;;puts the last keypress back for normal processing
                                (loop)))
            (set! SimulateMidi::active #f)
            (d-SetBackground #xFFFFFF)
            (d-PutMidi #x0040B0) ;;pedal up
            (d-InputFilterNames "No Input Filter")
            (d-SetPrefs (string-append "<startmidiin>" (if startmidiin "1" "0") "</startmidiin>"))
            (TimedNotice (_ "MIDI simulator end"))))))
