################################################################################
#
# This Expect script scans the output of the Linux version of id's
# game Quake for relevant information wrt. CD audio and calls "playcd"
# to trigger the appropriate action. It also realizes "artificial"
# commands (such as "cd" and "lxsh").
#
# (C) Copyright 1996 Michael Schumacher (mike@hightec.saarlink.de)
#
################################################################################

################################################################################
# If you'd like to continue seeing the complete output of x[f86]quake
# (which normally is suppressed by this script), change the second next
# command from "log_user 0" to "log_user 1"; aside from that, there are
# no user serviceable parts around here. Please check the README file and
# the "playcd" script for interesting things which you can easily change.
################################################################################

load $env(LXQCD_BINPATH)/libexpect5.20.so
log_user 0
if { [catch {set playcd [open "| tclsh $env(LXQCD_BINPATH)/playcd" w]} res] } {
  puts "lxQuakeCDmusic: couldn't execute tclsh; reason:\n$res"
  exit 1
}
if { [catch {puts $playcd test; flush $playcd}] } {
  puts "lxQuakeCDmusic: can't talk to music server; playcd broken?"
  exit 1
}
set ignore_next_map 0
set ignore_next_exit 0
set timeout -1
set ws "\[ \t\]*"
set num {0-9\.+\-}
if { [catch {source $env(LXQCD_BINPATH)/setvolume} res] } {
  puts -nonewline "lxQuakeCDmusic: couldn't source $env(LXQCD_BINPATH)/"
  puts "setvolume; reason:\n$res"
}
if { [catch {eval spawn -noecho $env(QUAKE) $argv} res] } {
  puts "lxQuakeCDmusic: couldn't execute $env(QUAKE); reason:\n$res"
  exit 1
}

expect {
  -re "^PackFile: .*\.pak : \.*(e\[1-4\]m\[1-8\])\.bsp\r\n" {
    if { $ignore_next_map } {
      set ignore_next_map 0
    } else {
      puts $playcd "play $expect_out(1,string)"
      flush $playcd
    }
    set ignore_next_exit 0
    exp_continue
  }
  -re "^PackFile: .*\.pak : \.*(dm\[1-6\])\.bsp\r\n" {
    if { $ignore_next_map } {
      set ignore_next_map 0
    } else {
      puts $playcd "play $expect_out(1,string)"
      flush $playcd
    }
    set ignore_next_exit 0
    exp_continue
  }
  -re "^PackFile: .*\.pak : maps/end\.bsp\r\n" {
    if { $ignore_next_map } {
      set ignore_next_map 0
    } else {
      puts $playcd "play end"
      flush $playcd
    }
    exp_continue
  }
  -re "^PackFile: .*\.pak : (demo\[123\])\.dem\r\n" {
    puts $playcd "play $expect_out(1,string)"
    flush $playcd
    set ignore_next_map 1
    exp_continue
  }
  -re "^player paused the game\r\n" {
    puts $playcd pause
    flush $playcd
    exp_continue
  }
  -re "^player unpaused the game\r\n" {
    puts $playcd unpause
    flush $playcd
    exp_continue
  }
  -re "^player exited the level\r\n" {
    if { $ignore_next_exit } {
      set ignore_next_exit 0
    } else {
      puts $playcd "play exit"
      flush $playcd
    }
    exp_continue
  }
  -re "^\x2Introduction\r\n" {
    puts $playcd "play start"
    flush $playcd
    set ignore_next_exit 1
    exp_continue
  }
  -re "^\]${ws}cd${ws}(\[^\r\n\]+)$ws\r\n" {
    switch -- [lindex $expect_out(1,string) 0] {
      on {
	puts $playcd on
	flush $playcd
      }
      off {
	puts $playcd off
	flush $playcd
      }
      reset {
	puts $playcd reset
	flush $playcd
      }
      info {
	puts $playcd info
	flush $playcd
      }
      eject {
	puts $playcd eject
	flush $playcd
      }
      stop {
	puts $playcd pause
	flush $playcd
      }
      resume {
	puts $playcd unpause
	flush $playcd
      }
      play {
        if { [regexp {^[0-9]+$} [lrange $expect_out(1,string) 1 end]] } {
	  puts $playcd "play #[lrange $expect_out(1,string) 1 end]"
	  flush $playcd
	}
      }
      loop {
        if { [regexp {^[0-9]+$} [lrange $expect_out(1,string) 1 end]] } {
	  puts $playcd "play +[lrange $expect_out(1,string) 1 end]"
	  flush $playcd
	}
      }
      current {
	puts $playcd current
	flush $playcd
      }
    }
    exp_continue
  }
  -re "^\]${ws}lx${ws}(\[^\r\n\t $num]+)${ws}(\[$num\]*)$ws\r\n" {
    switch -glob -- [lindex $expect_out(1,string) 0] {
      vo* {
        catch {adjust_volume volume $expect_out(2,string)}
      }
      cd {
	catch {adjust_volume cd $expect_out(2,string)}
      }
      so* {
	catch {adjust_volume sound $expect_out(2,string)}
      }
      lo* {
        if { "$expect_out(2,string)" == "1" } {
	  puts "lxQuakeCDmusic: logging enabled."
	  log_user 1
	} elseif { "$expect_out(2,string)" == "0" } {
	  puts "lxQuakeCDmusic: logging disabled."
	  log_user 0
	}
      }
    }
    exp_continue
  }
  -re "^\]${ws}volume${ws}(\[$num\]*)$ws\r\n" {
    catch {adjust_volume sound $expect_out(1,string)}
    exp_continue
  }
  -re "^\]${ws}bgmvolume${ws}(\[$num\]*)$ws\r\n" {
    catch {adjust_volume cd $expect_out(1,string)}
    exp_continue
  }
  -re "^\]${ws}lxsh${ws}(\[^\r\n]+)\r\n" {
    puts "running sh -c $expect_out(1,string)"
    if { [info exists env(SHELL)] } {
      catch {eval exec $env(SHELL) -c \"$expect_out(1,string)\; echo \$\" &}
    } else {
      catch {eval exec /bin/sh -c \"$expect_out(1,string)\; echo \$\" &}
    }
    exp_continue
  }
  -re .*\r\n {
    exp_continue
  }
  eof {
    puts $playcd stop
    flush $playcd
  }
}

### EOF ########################################################################
