#!/bin/sh
# \
exec wish "$0" "$@"


set procfil  {}
set PLAYMODE 0
set OLDF     -1
set FNAME    {}

proc startplayer {} {
  global FNAME procfil framescount
  if {[catch {open "|nuvplay -Z $FNAME" r+} procfil]} {
    tk_messageBox -icon error  \
                  -message "Could not fork nuvplay -Z: $procfil" -type ok
    exit
  }
  puts $procfil "0 0"
  flush $procfil

  fconfigure $procfil -buffering line -blocking 0

  fconfigure $procfil  -buffering line -blocking 1
  scan [gets $procfil] "%d %d %f %d %f" width height fps framescount effdsp
  puts stderr "width= $width height=$height fps=$fps framescount=$framescount effdsp=$effdsp"
  fconfigure $procfil  -buffering line -blocking 0

  .w.f4.scaler configure -from 0 -to [expr $framescount-1]
  fileevent $procfil readable newdata
}

proc main {fname} {
  global procfil width height fps framescount effdsp FNAME
  set len [string length $fname]
  if {1!=[string match {\.n[u0-9][v0-9]} [string range $fname [expr $len-4] end]]} {
    tk_messageBox -icon error  \
                  -message "The file '$fname' is not a NuppelVideo-file" -type ok
    exit
  }

  set FNAME $fname

  toplevel .w
  wm withdraw .w
  wm title    .w "NuppelVideo Editor nuvedit (use with extreme caution ;)"
  
  frame     .w.f1
  button    .w.f1.exit      -command button-exit      -text "Exit"
  button    .w.f1.save      -command "button-save $fname" \
                                                      -text "Save"
  button    .w.f1.play      -command button-play      -text "Play"
  button    .w.f1.stop      -command button-stop      -text "Stop"
  button    .w.f1.backward  -command button-backward  -text " << "
  button    .w.f1.stepback  -command button-last      -text "Prev"
  button    .w.f1.stepfwd   -command button-next      -text "Next"
  button    .w.f1.forward   -command button-forward   -text " >> "
  button    .w.f1.markstart -command button-markstart -text "Mark"
  button    .w.f1.markend   -command button-markend   -text "Kram"
  button    .w.f1.cut       -command button-cut       -text "Cut"

  frame     .w.f3
  label     .w.f3.l1 -text "Frame:"
  entry     .w.f3.e1 -textvariable FRAMENUMBER
  label     .w.f3.l2 -text "Begin:"
  entry     .w.f3.e2 -textvariable MARKSTART
  label     .w.f3.l3 -text "End:"
  entry     .w.f3.e3 -textvariable MARKEND

  frame     .w.f4
  scale     .w.f4.scaler -orient horizontal -variable FRAMENUMBER -command seekTo
  global    OLDJOB
  set       OLDJOB {}

  frame     .w.f2
  text      .w.f2.text -font "Helvetica -20 bold" -fg blue -width 40 -height 5
  scrollbar .w.f2.sy
  
  .w.f2.sy   configure -command ".w.f2.text yview"
  .w.f2.text configure -yscrollcommand ".w.f2.sy set"

  pack      .w.f3 -side top -expand 0 -fill both
  pack      .w.f1 -side top -expand 0 -fill both
  pack      .w.f4 -side top -expand 0 -fill both
  pack      .w.f2 -side top -expand 1 -fill both

  pack      .w.f1.exit      -side left -expand 0 -fill x 
  pack      .w.f1.save      -side left -expand 0 -fill x 
  pack      .w.f1.play      -side left -expand 0 -fill x 
  pack      .w.f1.stop      -side left -expand 0 -fill x 
  pack      .w.f1.backward  -side left -expand 0 -fill x 
  pack      .w.f1.stepback  -side left -expand 0 -fill x 
  pack      .w.f1.stepfwd   -side left -expand 0 -fill x 
  pack      .w.f1.forward   -side left -expand 0 -fill x 
  pack      .w.f1.markstart -side left -expand 0 -fill x 
  pack      .w.f1.markend   -side left -expand 0 -fill x 
  pack      .w.f1.cut       -side left -expand 0 -fill x 

  pack      .w.f3.l1      -side left -anchor n -expand 0 -fill x 
  pack      .w.f3.e1      -side left -anchor n -expand 0 -fill x 
  pack      .w.f3.l2      -side left -anchor n -expand 0 -fill x 
  pack      .w.f3.e2      -side left -anchor n -expand 0 -fill x 
  pack      .w.f3.l3      -side left -anchor n -expand 0 -fill x 
  pack      .w.f3.e3      -side left -anchor n -expand 0 -fill x 

  pack      .w.f4.scaler  -side bottom -expand 0 -fill x 

  pack      .w.f2.sy   -side right -expand 0 -fill y
  pack      .w.f2.text -side left  -expand 1 -fill both
  wm deiconify .w

  startplayer 

  update

  if {[file exists "${fname}.edit"]} {
    set editlist [open "${fname}.edit" r]
    set txt [read $editlist]
    .w.f2.text insert end $txt
  }
}

proc seekTo {where} {
  global OLDJOB

  if {$OLDJOB=={}} {
    set OLDJOB [after 150 "realSeekTo $where"]
  } else {
    after cancel $OLDJOB
    set OLDJOB [after 150 "realSeekTo $where"]
  }
}

proc realSeekTo {where} {
  global OLDJOB PLAYMODE procfil
  
  set OLDJOB {}
  
  puts $procfil "$PLAYMODE $where"
  flush $procfil
}

proc newdata {} {
  global FRAMENUMBER OLDF STATE procfil PLAYMODE
  set txt [gets $procfil]
  if {[eof $procfil]} {
    close $procfil
    tk_messageBox -icon error -message "The player crashed for unknown reason!" -type ok
    startplayer
    set FRAMENUMBER 0
    set PLAYMODE 0
  }
  if {2==[scan $txt "%d %d" new STATE]} {
    if {("$new" != "$OLDF" && $PLAYMODE==0) || $PLAYMODE == 1 } {
      set FRAMENUMBER $new
      set OLDF $FRAMENUMBER
    }
    update
  } else {
    puts stderr "garbage: $txt"
  }
  #after 1000 newdata
}


proc button-exit {} {
  global procfil
  set ans [tk_messageBox -icon question \
                         -message "Are you sure?" -type yesno]
  if {$ans=="yes"} {
    catch {close $procfil} 
    exit
  }
} 

proc button-save {fname} {
  set editlist [open "${fname}.edit" w]
  puts -nonewline $editlist [.w.f2.text get 0.0 end]
  close $editlist
} 

proc button-play {} {
  global PLAYMODE procfil
  puts $procfil "1 -1"
  flush $procfil
  set PLAYMODE 1
} 

proc button-stop {} {
  global PLAYMODE procfil
  puts $procfil "0 -1"
  flush $procfil
  set PLAYMODE 0
} 

proc button-backward {} {
  global PLAYMODE FRAMENUMBER procfil

  set FRAMENUMBER [expr {$FRAMENUMBER-250}]
  if {$FRAMENUMBER<0} {set FRAMENUMBER 0}
  puts $procfil "$PLAYMODE $FRAMENUMBER"
  flush $procfil
} 

proc button-forward {} {
  global PLAYMODE FRAMENUMBER framescount procfil

  set FRAMENUMBER [expr {$FRAMENUMBER+250}]
  if {$FRAMENUMBER>[expr $framescount-1]} {set FRAMENUMBER [expr $framescount-1]}
  puts $procfil "$PLAYMODE $FRAMENUMBER"
  flush $procfil
} 

proc button-last {} {
  global PLAYMODE FRAMENUMBER procfil

  set FRAMENUMBER [expr {$FRAMENUMBER-1}]
  if {$FRAMENUMBER<0} {set FRAMENUMBER 0}
  puts $procfil "$PLAYMODE $FRAMENUMBER"
  flush $procfil
} 

proc button-next {} {
  global PLAYMODE FRAMENUMBER framescount procfil

  set FRAMENUMBER [expr {$FRAMENUMBER+1}]
  if {$FRAMENUMBER>[expr $framescount-1]} {set FRAMENUMBER [expr $framescount-1]}
  puts $procfil "$PLAYMODE $FRAMENUMBER"
  flush $procfil
} 

proc button-markstart {} {
  global MARKSTART MARKEND FRAMENUMBER
  set MARKSTART $FRAMENUMBER
} 

proc button-markend {} {
  global MARKSTART MARKEND FRAMENUMBER
  set MARKEND   $FRAMENUMBER
} 

proc button-cut {} {
  global MARKSTART MARKEND FRAMENUMBER
  if {2==[scan "$MARKSTART $MARKEND" "%d %d" a b]} {
    .w.f2.text insert end "$a $b\n"
    set MARKSTART {}
    set MARKEND   {}
  }
}


# now it's tcls real main: the tail of the file ;)

wm withdraw .
if {$argc==0} {
  set argv [tk_getOpenFile]
  if {$argv=={}} exit
} 

set fname [lindex $argv 0]

if {![file exists "$fname"]} {
  tk_messageBox -icon error -message "File does '$fname' not exist" -type ok
  exit
}

#fake main


after 100 {main "$fname"}
