#!/bin/sh

Me="$(basename "$0")"
XTerm="xterm -name DemoScreen -T DemoScreen -e"
ScrName="pub"
ScrF="-S $ScrName"
ScrSF="-h 1000 -RD"
Enc=""
Prefix="^"
SendCmd=""
Verbose=0
RC="$HOME/.$Me"

test -r "$RC" && . "$RC" || :

# TODO tmpfiles remover via trap
TmpPref="${TMPDIR:-/tmp}/demoscreen"
TmpSrc="$TmpPref.source"
TmpFile="$TmpPref.tmp"
TmpLog="$TmpPref.printscreen"

ToSend="$TmpLog"

Msg() { # message
  Error "$*" q
}

Error() { # errormsg [errorlevel]
  case "${2:-1}" in
    [1-9]*) ER="ERROR: "; ret="${2:-1}" ;;
    [0Ii]*) ER="INFO: "; ret=0 ;;
    [-Ww]*) ER="WARNING: "; ret=-1 ;;
    [Qq]*) ER=""; ret=-1;;
    *) ER="ERROR: "; ret=1 ;;
  esac
  if [ "$Verbose" -ge 1 ]	# verbose
  then
    echo "$ERR$1" >&2
  elif [ "$Verbose" -lt 1 ]	# normal
  then
    test "$ret" -eq 0 || echo "$ERR$1" >&2
  elif [ "$Verbose" -lt 0 ]	# quiet
  then
    test "$ret" -le 0 || echo "$ERR$1" >&2
  fi
  test $ret -le 0 || exit $ret
}

StartDemo() {
  #$XTerm "echo '[?1000h'; screen $ScrSF $ScrF" &
  $XTerm "screen $ScrSF $ScrF" &
  until CheckDemo; do sleep 1; done
  icesh -class DemoScreen setWorkspace "Work"
  screen $ScrF -X hardstatus lastline
  screen $ScrF -X slowpaste 100
  # TODO synchronize
  sleep 1
}

CheckDemo() {
  test -n "`screen -ls $ScrName 2> /dev/null | fgrep '(Attached)'`"
}

Printable() { # string
  # TODO all the non-printable via hexdump with names
  # TODO termcap colors
  echo "$*" | sed '
s// ESC /g
s/	/ Tab /g
s/
/ Enter /g
'
}

UUDecode() { # string
  { echo "begin-base64 644 -"
    echo "$*"
    echo "===="
  } | uudecode
}

UUEncode() { # string
  echo "$*" | uuencode -m - | sed '1d;$d' | tr -d '\n'
}

RunDemo() {
  local Enter Arg
  icesh -window root setWorkspace "Work"
  icesh -class DemoScreen setLayer OnTop 
  icesh -class DemoScreen setLayer Normal
  test "$1" = "-n" && shift || Enter="
"
  Arg="$( echo "$*" | sed "s#$Prefix##;s/;;/
/g" )"
  case "$Enc" in
    U*) Arg=$(UUDecode "$Arg") ;;
  esac
  screen $ScrF -X hstatus "$(Printable "$Arg")"
  # TODO synchronize
  sleep 1
  screen $ScrF -X stuff "$Arg$Enter"
}

DumpScreen() { # [screen number]
  echo "
select ${1:-0}
copy
stuff y1G>
writebuf $TmpFile
other
" > $TmpSrc
  screen $ScrF -X source $TmpSrc
  echo -n "########## " >> $TmpLog
  date >> $TmpLog
  cat -s $TmpFile >> $TmpLog
}

SendFile() { # [file_to_send [command]]
  local F=${1:-$ToSend}
  local Cmd="${2:-$SendCmd}"
  test -n "$Cmd" || {
    echo -n "Enter command to send file, use %s as filename: "
    read Cmd
    test -w "$RC" && sed -i~ "/SendCmd=/d" "$RC" || :
    echo "SendCmd='$Cmd'" >> "$RC"
  }
  Cmd=`printf "$Cmd" "$F"`
  $Cmd
}

mkhelp() { # description getopt_flags [param description [...]]
  echo
  echo "$Me: $1"
  echo	"		Options:"
  for c in $(echo "$2" | sed 's/\(.:*\)/\1 /g')
  do
    echo -n "-$c	" | sed 's/:/ ARG/'
    case "$c" in
      h) echo "get this help screen" ;;
      v) echo "increase Verbosity" ;;
      n:) echo "enter ARG string without Newline" ;;
      E:) echo "uu-Encode ARG and exit" ;;
      U) echo "command is UU-encoded" ;;
      H) echo "command has HTTP prefix (e. g. run://)" ;;
      q) echo "Quiet mode (decrease verbosity)" ;;
      k) echo "Kill current demoscreen" ;;
      c:) echo "execute ARG screen command" ;;
      P) echo "Save printscreen file" ;;
      S) echo "Send printscreen file" ;;
      f:) echo "Specify file to send instead of printscreen" ;;
      s:) echo "Command to send file, use %s as filename" ;;
      *) echo "NO HELP PROVIDED" ;;
    esac
  done
  shift; shift; echo
  while [ "$#" -gt 1 ]
  do
    echo "$1:	$2"
    shift; shift;
  done
}

Cmd_F="PUSHE:vqkn:c:f:s:h"
Usage="Usage: $Me [$Cmd_F] cmd [cmd ...]"
Help="$(mkhelp "Run specific commands in dedicated screen" "$Cmd_F" "cmd" "run shell command or enter string")"

while [ "$#" -ge 1 ]
do
  while getopts "$Cmd_F" f
  do
    case "$f" in
      k) screen $ScrF -X "quit"; exit $? ;;
      c) screen $ScrF -X $OPTARG ;;
      n) RunDemo -n "$OPTARG" ;;
      v) Verbose=$(($Verbose+1)) ;;
      q) Verbose=$(($Verbose-1)) ;;
      h) Msg "$Usage"; Msg "$Help"; exit 0;;
      E) UUEncode "$OPTARG"; exit 0;;
      U) Enc=Uuencode ;;
      H) Prefix="[a-z]*://" ;;
      P) DumpScreen ;;
      S) SendFile ;;
      f) ToSend="$OPTARG" ;;
      s) SendCmd="$OPTARG" ;;
      *) Msg "$Usage"; Error "Invalid option $f" ;;
    esac
  done
  shift $(($OPTIND-1))
  test -z "$1" || { CheckDemo || StartDemo; RunDemo "$1"; }
  shift
done

CheckDemo || StartDemo