#!/usr/bin/zsh-beta

# zec: Z-Shell Empire Client
#   Copyright (C) 2001, 2002, 2003  Clint Adams

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

ZEC_VERSION="0.3.1"

cat <<EOF;
  zec version ${ZEC_VERSION}, Copyright (C) 2001, 2002, 2003  Clint Adams
  zec comes with ABSOLUTELY NO WARRANTY.
  This is free software, and you are welcome to redistribute it
  under certain conditions.

EOF

zmodload -i zsh/parameter || exit 244
zmodload -i zsh/net/tcp || exit 245
zmodload -i zsh/zselect || exit 246

setopt extendedglob

# connect to empire server
# usage: zelogin country password hostname_or_ip tcpportnum

zelogin() {
local greeting answer

ztcp -d 9 $3 $4
builtin read "$readopts" greeting
[[ "$greeting" == "2 Empire server ready" ]] || return 1
print -u9 "user $LOGNAME"
builtin read "$readopts" answer
[[ "$answer" == "0 hello $LOGNAME" ]] || return 2
print -u9 "client zec $ZEC_VERSION"
builtin read "$readopts" answer
[[ "$answer" == "0 talking to zec $ZEC_VERSION" ]] || return 3
print -u9 "country $1"
builtin read "$readopts" answer
[[ "$answer" == "0 country name $1" ]] || return 4
print -u9 "pass $2"
builtin read "$readopts" answer
[[ "$answer" == "0 password ok" ]] || return 5
print -u9 "play"
builtin read "$readopts" answer
[[ "$answer" == "2 2" ]] || return 6
}

zelogout() {
local answer

print -u9 "quit"
builtin read "$readopts" answer
[[ "$answer" == "3 so long" ]] || return 8
}

zec_alias_parse() {
local cmd="$1"

[[ -n "${zec_aliases[$cmd]}" ]] || return 9

cookedline="${line/$cmd/$zec_aliases[$cmd]}"
}

zec_tool_history() {
local i

for i in "${(onk)history[@]}"
do
print "$i: ${history[$i]}"
done
}

zec_tool_jack() {

  local tmpfilenam="${TMPDIR:-/tmp}/zecjack$$"

  print -u9 "prod * >$tmpfilenam"
  zec_parseresponse
  for i in ${(M)${(f)"$(<$tmpfilenam)"}:#[[:space:]]#-#[0-9]##,-#[0-9]##[[:space:]]##[jk]*};
  print th i ${${(z)i}[1]} ${${(z)i}[10]/i(#e)/}

  rm ${tmpfilenam}

}

zec_tool_alias() {
local i

for i in "${(onk)zec_aliases[@]}"
do
print "$i: ${zec_aliases[$i]}"
done
}

zec_tools_parse() {
local cmd="$1"

[[ -n "${zec_tools[(r)$cmd]}" ]] || return 10

zec_tool_$cmd
}

zec_subcommand() {
local vpmpt line

vpmpt="-p $subpmpt $1> "

vared -h "$vpmpt" line
[[ -z "$line" ]] || print -s "$line"
print -u9 "$line"
}

unset outgo

redir_output() {
 outgo=${1}
 [[ "$outgo" != \>* ]] && exit 211
 eval exec 8$outgo
 outgo="-u8"
}

pipe_output() {
 [[ "$@" != \|* ]] && exit 212
 outgo=("${(z)@/| #/}")
 eval exec 8\>\>\(${outgo}\)
 outgo="-u8"
}

restore_output() {
 [[ "$outgo" == "-u8" ]] && exec 8>&-
 unset outgo
}

print_output() {
 print $outgo -- "$1"
}

zec_parseresponse() {

local i=0

while builtin zselect -t 100 -r 9
do

[[ "$i" -gt 0 ]] && print "TIMED OUT"

  while builtin read "$readopts" answer
  do

  case "$answer" in
  	'1'(#b)(*)) print_output "${match[1]/ /}"
  	;;
  	3*) return 1
  	;;
  	'4'(#b)(*)) zec_subcommand "$match[1]"
  	;;
  	6*) restore_output ; break 2
  	;;
	'8 '(#b)(*)) redir_output "$match[1]"
	;;
	'9 '(#b)(*)) pipe_output "$match[1]"
	;;
  	'd'(#b)(*)) print_output "${match[1]/ /}"  # flash
	;;
  	'e'(#b)(*)) print_output "INFORM (slight confusion): ${match[1]/ /}"  # inform
	;;
  	*) print "OH, NO!  I AM CONFUSED BY THIS LINE!"
  	   print "$answer"
  	   zelogout
  	;;
  esac

  done

(( i += 1 ))

done
}

zec_command() {
local line

[[ "$answer" == '6 '(#b)([0-9]##)' '([0-9]##) ]] || return 9
vpmpt="-p $pmpt $match[1]:$match[2]%# "

vared -he "$vpmpt" line || zelogout
[[ -z "$line" ]] || print -s "$line"
if zec_alias_parse "${(z)line}"
then
print -u9 "$cookedline"
elif zec_tools_parse "${(z)line}"
then
print -u9 ""
else
print -u9 "$line"
fi
}

parse_config() {
local CONFIGLINE
local i=1

while read CONFIGLINE
do
 case $CONFIGLINE in
   addgame*)
     games[i]="${CONFIGLINE#addgame }"
     (( i++ ))
   ;;
   'alias '(#b)([^ ]##)' '(*))
     zec_aliases[${match[1]}]="$match[2]"
   ;;
   *)
    print "Unknown config line: $CONFIGLINE"
   ;;
 esac

done <$1
}

twitter() {
local g

[[ -r ~/.zecrc ]] && parse_config ~/.zecrc

case $#games in
	0)
	;;
	1) set -- ${(z)games[1]}
	   shift
	;;
	*) for i in $games; do g=(${(z)i}); printf "%-20s %20s:%s\n" ${g[1]} ${g[4]} ${g[5]}; done
	   print "FIXME: should give a menu here"
	   set -- ${(z)games[1]}
	   shift
	;;
esac

if [[ -z "$1" ]] || [[ -z "$2" ]] || [[ -z "$3" ]] || [[ -z "$4" ]];
then
print "usage: $SCRIPTNAME country password host port"
print "or"
return 2
fi

if zelogin $1 $2 $3 $4
then
zec_parseresponse
while zec_command ; do zec_parseresponse ; done
#zelogout && return 0
#print "But we failed to log out."
#return 1
else
print "Boo, you suck.  $?"
return 2
fi
}

[[ -n "$ZEC_DEBUG" ]] && readopts="-Eu9" || readopts="-u9"
typeset -A zec_aliases
zec_aliases=(exit quit)
typeset -a zec_tools
zec_tools=(history jack alias)

SCRIPTNAME="$0"

twitter "$@"
