#!/usr/local/bin/tclmidi
proc Usage {} {
	puts stderr {Usage: mrec [-thru] [-merge] \
	    [[-repeat] -play play_filename] [-tempo tempo] [rec_filename]}
}

set repeat ""
set tempo 120
set merge 0
set pfname stdin
set pf ""
set rfname stdout
set rf stdout

for {set i 0} {$i < $argc} {incr i} {
	switch -- [lindex $argv $i] {
	"-?" -
	"-h" -
	"-help" {
		Usage
		exit 1
	}
	"-thru" {
		mididevice {midithru on}
	}
	"-repeat" {
		set repeat repeat
	}
	"-play" {
		incr i
		if {$i >= $argc || $pfname != "stdin"} {
			Usage
			exit 1
		}
		set pfname [lindex $argv $i]
		if {$pfname == "-"} {
			set pf stdin
		} else {
			set pf [open $pfname r]
		}
	}
	"-tempo" {
		incr i
		if {$i >= $argc} {
			Usage
			exit 1
		}
		set tempo [lindex $argv $i]
	}
	"-merge" {
		set merge 1
	}
	default {
		if {$rfname != "stdout"} {
			Usage
			exit 1
		}
		set rfname [lindex $argv $i]
		if {$rfname == "-"} {
			set rf stdout
		} else {
			set rf [open $rfname w]
		}
	}
	}
}

if {$pf != ""} {
	puts "please wait, loading play file"
	set pmf [midiread $pf]
} else {
	set pmf [midimake]
	midiconfig $pmf {tracks 1}
	midiput $pmf 0 "0 metatempo $tempo"
}

set rmf [midimake]
set pconfig [midiconfig $pmf division]
midiconfig $rmf [lindex $pconfig 0] {tracks 1}

puts "press return to begin recording"
gets stdin

if {![midirecord $rmf $pmf $repeat]} {
	puts stderr "midirecord command not available"
	exit 1
}
# if we're repeating or not playing something, prompt to quit
if {$pf == "" || $repeat != ""} {
	puts "press return to stop recording"
	gets stdin
} else {
	midiwait
}
midistop

midirewind $rmf
if {!$merge} {
	# remove the EOT event from track 0 of the play file
	# so it won't be copied into the record track
	midirewind $pmf
	set lastevent [midiget $pmf 0 prev]
	if {[lindex $lastevent 1] == "MetaEndOfTrack"} {
		mididelete $pmf 0 $lastevent
	}
	# copy meta events from play file into record track
	if {[lindex [lindex [midiconfig $pmf format] 0] 1] == 0} {
		set playmeta [midimake]
		midiconfig $playmeta {format 0} {tracks 1}
		# meta events go to the record file, others are thrown away
		midisplit "$pmf 0" "$rmf 0" "$playmeta 0"
		midifree $playmeta
	} else {
		# copy all of track 0 of the pmf
		midicopy "$rmf 0" 0 "$pmf 0" 0 \
		    [expr "[miditrack $pmf 0 end] + 1"]
	}

	# add EOT
	midiput $rmf 0 "[miditrack $rmf 0 end] MetaEndOfTrack"
	midiwrite $rf $rmf
	midifree $pmf
	midifree $rmf
} else {
	# create a format one file consiting of the play file
	# plus the recorded track
	set playconfig [midiconfig $pmf]
	set playtracks [lindex [lindex $playconfig 2] 1]
	set playdiv [lindex [lindex $playconfig 1] 1]
	set playformat [lindex [lindex $playconfig 0] 1]
	set newfile [midimake]
	midiconfig $newfile "format 1" "division $playdiv" \
	    "tracks [expr $playtracks+1]"
	if {$playformat != 0} {
		# copy each track to newfile
		midiconfig $newfile "tracks [expr $playtracks+1]"
		for {set i 0} {$i < $playtracks} {incr i} {
			midicopy "$newfile $i" 0 "$pmf $i" \
			    0 [expr "[miditrack $pmf $i end] + 1"]
		}
		set newtrack $i
		midicopy "$newfile $i" 0 "$rmf 0" 0 \
		    [expr "[miditrack $rmf 0 end] + 1"]
	} else {
		# split track 0 into newfile
		midiconfig $newfile "tracks [expr $playtracks+2]"
		midisplit "$pmf 0" "$newfile 0" "$newfile 1"
		midicopy "$newfile 2" 0 "$rmf 0" 0 \
		    [expr "[miditrack $rmf 0 end] + 1"]
		set newtrack 2
	}
	# add EOT to recorded track
	midiput $newfile $newtrack \
	    "[miditrack $newfile $newtrack end] MetaEndOfTrack"

	midiwrite $rf $newfile
	midifree $pmf
	midifree $rmf
	midifree $newfile
}
