if 0 {
  /*
    * This file is part of din.
    *
    * din is copyright (c) 2006 - 2023 Jagannathan Sampath <jag@dinisnoise.org>
    * For more information, please visit http://dinisnoise.org
    *
    *
  */
}

;# remove a value from a list
proc lremove {listVariable value} {
  upvar 1 $listVariable var
  set idx [lsearch -exact $var $value]
  set var [lreplace $var $idx $idx]
}

;# bring the math ops & functions to use them LISP style eg., + 2 3
namespace path {::tcl::mathop ::tcl::mathfunc}

;# console colors
set color(header) {set-text-color 1 0.75 0.5}
set color(text) {set-text-color 0.8 1 0.8}
set color(error) {set-text-color 1 0.6 0.6}
set color(fine) {set-text-color 0.6 1 0.6}

;# tap bpm
set resetbeat 0
proc tap-bpm-changed {name element op} {
  ;# tap bpm changed
  global taptarget tapbpm resetbeat
  set wr {}
  if $resetbeat {
    foreach i $taptarget {
      set-beat $i [get-beat $i first]
    }
    set wr {[+ reset]}
  }
  foreach tt $taptarget {
    set-bpm $tt $tapbpm
  }
}

trace add variable tapbpm write tap-bpm-changed

proc add-tap-target what {
  global taptarget
  lappend taptarget $what
}

proc remove-tap-target what {
  global taptarget
  lremove taptarget $what
}

;# list files in user directory matching extension
proc lsuserdir {{ext *}} {
  global user
  set mapping [list .$ext {}]
  string map $mapping [lsort [glob -nocomplain -tails -directory $user *.$ext]]
}

proc bad-sub-command {c} {
  upvar $c cmds
  set err "bad sub-command. should be: "
  foreach i [lrange $cmds 0 end-1] {
    append err "$i, "
  }
  append err "or [lindex $cmds end]"
}

proc exec-sub-command {ucmds uactions ucmd uargs} {
  upvar $ucmds cmds $uactions actions $ucmd cmd $uargs args
  set j 0
  foreach i $cmds {
    if {$cmd eq $i} {
      return [{*}[lindex $actions $j] {*}$args]
    }
    incr j
  }
  bad-sub-command cmds
}

;# tuning command -> list, set and get available tunings
proc tuning {cmd args} { ;# tuning command
  set cmds {list set get}
  set actions {"lsuserdir tuning" "set-var tuning" "get-var tuning"}
  exec-sub-command cmds actions cmd args
}

;# called when drones are deleted
proc drones-deleted {args} {}

;# called once every din loop
proc loop {} {} ;# required

;# list-patches command
set lsp_body {{} {
  lsuserdir patch.tcl
}}

eval "proc list-patches $lsp_body"
eval "proc lp $lsp_body"

;# load-patch command
set lop_body {{patch {quiet 0}} {
  src $patch.patch
  if [catch {src $patch.patch}] {
    set-text-color 1 0.5 0.5
    echo "bad patch: $patch"
  } else {
    set-text-color 0.5 1 0.5
    if {$quiet eq 0} {
  		echo "loaded $patch"
      echo "help $patch for more information"
  	}
  }
}}

eval "proc load-patch $lop_body"
eval "proc lop $lop_body"

;# make interval note variables based on current tuning
src make-interval-note-vars

;# load help displayer
src help

if 0 {
  make empty midi procs
  if user wants diagnostics, they can load midimap patch
}

proc make-midi name {
  uplevel #0 "proc $name args {}"
}

foreach i {midi-start midi-clock midi-note-on midi-note-off midi-pitch-bend midi-program-change midi-cc} {
  make-midi $i
}

proc setup-editors {} {
  set instrument [get-var instrument]
  set eds [set instrument]_editors
  global $eds
  set ids [array get $eds]
  foreach {i j} $ids {set-curve-editor $j $i}
}

proc update-editor {name screen} {
  set instrument [get-var instrument]
  set eds [set instrument]_editors
  global $eds
  array set $eds [list $screen $name]
}

proc show-eval-notice {} {

  set-text-color 1 1 0.5
  echo "Thank you for evaluating DIN Is Noise!"
  echo {}
  set-text-color 1 0.5 0.5
  echo "This Evaluation Version has some limits."
  echo {}
  set-text-color 1 1 0.5
  echo "To remove these limits, please buy a License."
  echo "This is a Lifetime License that includes free upgrades for life."
  echo "And you will not see this message."
  echo ""
  echo "Your license helps support my independent research and work "
  echo "on DIN Is Noise.  Hope you enjoy using the program!"
  echo ""
  echo "Jagannathan Sampath <jag@dinisnoise.org>"

}

proc buy-license os {
  set oss {Windows Darwin Linux} ;# platforms
  set launchers {{cmd /c start} open xdg-open} ;# to open the installed web browser
  if {$os in $oss} {
    set i [lsearch -exact $oss $os]
    exec {*}[lindex $launchers $i] https://dinisnoise.org/buy/
  }
}

proc factory-reset {} {
  global user
  file mkdir $user/reset2factory
  echo {Please restart DIN Is Noise to use factory settings}
}

proc exit {} {}

proc get-val {min max amount} { ;# get interpolated value from min to max
  set amount [/ $amount 127.0]
  return [expr { (1 - $amount) * $min + $amount * $max }]
}

proc get-nums {start end {step 1}} {
  ;# get numbers from start to end with step
  set nums {}
  set i $start
  set j $end
  while {$i <= $end} {
  	lappend nums $i
  	incr i $step
  }
  return $nums
}

proc rnd {a b} {
  ;# return random number in range (a,b)
  set r01 [rand]
  set ba [- $b $a]
  set v [+ $a [* $r01 $ba]]
  return $v
}

proc eval-expr {e {t ""}} { ;# evaluates a tcl expression (used by field ui control)
  uplevel #0 [list expr $t ($e)]
}

proc stopped-recording {} {}

proc key* {args} {
  ;# set key for all instruments
  foreach i {microtonal_keyboard keyboard_keyboard mondrian sounding_board} {
  	key $i {*}$args
  }
}

;# make set-bpm helpers
set set_bpm_op_val { {what op value} { set-bpm $what [$op [get-bpm $what] $value] } }
proc set-bpm' {*}$set_bpm_op_val
proc sb' {*}$set_bpm_op_val
unset set_bpm_op_val

;# make set-var helpers
set set_var_op_val {{what op value} {set-var $what [$op [get-var $what] $value]}}
proc set-var' {*}$set_var_op_val
proc sv' {*}$set_var_op_val
unset set_var_op_val

proc uptime {{cons 1}} {
  ;# print the uptime of DIN
  global timenow genesis
  set elapsed [- $timenow $genesis]
  set hours [/ $elapsed 3600.0]
  set ihours [expr int($hours)]
  set mins [expr ($hours - $ihours) * 60.0]
  set imins [expr int($mins)]
  set seconds [expr ($mins - $imins) * 60.0]
  set output "${ihours} hours ${imins} minutes [expr int($seconds)] seconds"
  if $cons {echo $output} else {return $output}
}

src binaural-drones; ;# for binaural drones
set genesis $timenow ;# for uptime
