# Copyright 2000, 2004 by Paul Mattes.
#  Permission to use, copy, modify, and distribute this software and its
#  documentation for any purpose and without fee is hereby granted,
#  provided that the above copyright notice appear in all copies and that
#  both that copyright notice and this permission notice appear in
#  supporting documentation.
#
# x3270, c3270, s3270 and tcl3270 are distributed in the hope that they will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file LICENSE
# for more details.

# Glue functions between 'expect' and x3270
# Usage: source x3270_glue.expect

namespace eval x3270 {
	variable verbose 0
	variable pid 0

	# Start function: Start ?-nohup? ?program? ?options?
	#
	# Sets up the 'expect' environment correctly and spawns a 3270
	# interface process.
	#
	# The 'program' and 'options' can be:
	#  "x3270 -script" to drive an x3270 session
	#  "s3270" to drive a displayless 3270 session
	#  "x3270if -i" to run as a child script of x3270 (via the Script()
	#   action)
	#
	# If "args" is empty, or starts with an option besides '-nohup',
	#  guesses which process to start.
	# It will only guess "x3270if -i" or "s3270"; if you want to start
	#  x3270, you need to specify it explicitly.
	#
	# Returns the process ID of the spawned process.

	proc Start {args} {
		global stty_init timeout spawn_id env
		variable verbose
		variable pid

		if {$pid != 0} {return -code error "Already started."}

		# If the first argument is "-nohup", remember that as an
		# argument to 'spawn'.
		if {[lindex $args 0] == "-nohup"} {
			set nohup {-ignore HUP}
			set args [lrange $args 1 end]
		} {
			set nohup {}
		}

		# If there are no arguments, or the first argument is an
		#  option, guess what to start.
		# If X3270INPUT is defined in the environment, this must be a
		#  child script; start x3270if.  Otherwise, this must be a peer
		#  script; start s3270.
		if {$args == {} || [string index [lindex $args 0] 0] == "-"} {
			if {[info exists env(X3270INPUT)]} {
				set args [concat x3270if -i $args]
			} {
				set args [concat s3270 $args]
			}
		}

		# Set up the pty initialization default.
		set stty_init -echo

		# Spawn the process.
		if {$verbose} {
			set pid [eval [concat spawn $nohup $args]]
		} {
			set pid [eval [concat spawn -noecho $nohup $args]]
			log_user 0
		}

		# Set the 'expect' timeout.
		set timeout -1

		return $pid
	}

	# Basic interface command.  Used internally by the action functions
	# below.
	proc cmd {cmd} {
		variable verbose
		variable pid

		if {$pid==0} { return -code error "Not started yet." }

		if {$verbose} {puts "+$cmd"}

		send "$cmd\r"
		expect {
			-re "data: (.*)\r\n.*\r\nok\r\n$" {
				set r $expect_out(buffer)
			}
			"*ok\r\n" { return {} }
			-re "(.*)\r\n.*?\r\nerror\r\n" {
				return -code error "$expect_out(1,string)"
			}
			"*error\r\n" {
				return -code error \
					"$cmd failed: $expect_out(buffer)"
			}
			eof { set pid 0; error "process died" }
		}

		# Convert result to a list.
		set ret {}
		set iter 0
		while {1} {
			if {! [regexp "data: (.*?)\r\n" $r dummy elt]} {break}
			if {$iter==1} {set ret [list $ret]}
			set r [string range $r [expr [string length $elt]+7] \
				end]
			if {$iter > 0} {
				set ret [linsert $ret end $elt]
			} {
				set ret $elt
			}
			set iter [expr $iter + 1]
		}
		if {$verbose} {puts "ret $iter"}
		return $ret
	}

	# Convert an argument list to a comma-separated list that x3270 will
	# accept.
	proc commafy {alist} {
		set i 0
		set a ""
		while {$i < [llength $alist]} {
			if {$i > 0} {
				set a "$a,[lindex $alist $i]"
			} {
				set a [lindex $alist $i]
			}
			incr i
		}
		return $a
	}

	# Quote a text string into x3270-acceptable format.
	proc stringify {text} {
		set a "\""
		set i 0
		while {$i < [string len $text]} {
			set c [string range $text $i $i]
			switch -- $c {
				"\n" { set a "$a\\n" }
				"\r" { set a "$a\\r" }
				" " { set a "$a\\ " }
				"\"" { set a "$a\\\"" }
				default { set a "$a$c" }
			}
			incr i
		}
		set a "$a\""
		return $a
	}

	# User-accessible actions.
	# Some of these apply only to x3270 and x3270if, and not to s3270.
	proc AltCursor {} { return [cmd "AltCursor"] }
	proc Ascii {args} { return [cmd "Ascii([commafy $args])"] }
	proc AsciiField {} { return [cmd "AsciiField"] }
	proc Attn {} { return [cmd "Attn"] }
	proc BackSpace {} { return [cmd "BackSpace"] }
	proc BackTab {} { return [cmd "BackTab"] }
	proc CircumNot {} { return [cmd "CircumNot"] }
	proc Clear {} { return [cmd "Clear"] }
	proc CloseScript {} { return [cmd "CloseScript"] }
	proc Cols {} { return [lindex [Status] 7] }
	proc Compose {} { return [cmd "Compose"] }
	proc Connect {host} { return [cmd "Connect($host)"] }
	proc CursorSelect {} { return [cmd "CursorSelect"] }
	proc Delete {} { return [cmd "Delete"] }
	proc DeleteField {} { return [cmd "DeleteField"] }
	proc DeleteWord {} { return [cmd "DeleteWord"] }
	proc Disconnect {} { return [cmd "Disconnect"] }
	proc Down {} { return [cmd "Down"] }
	proc Dup {} { return [cmd "Dup"] }
	proc Ebcdic {args} { return [cmd "Ebcdic([commafy $args])"] }
	proc EbcdicField {} { return [cmd "EbcdicField"] }
	proc Enter {} { return [cmd "Enter"] }
	proc Erase {} { return [cmd "Erase"] }
	proc EraseEOF {} { return [cmd "EraseEOF"] }
	proc EraseInput {} { return [cmd "EraseInput"] }
	proc FieldEnd {} { return [cmd "FieldEnd"] }
	proc FieldMark {} { return [cmd "FieldMark"] }
	proc FieldExit {} { return [cmd "FieldExit"] }
	proc Flip {} { return [cmd "Flip"] }
	proc HexString {x} { return [cmd "HexString($x)"] }
	proc Home {} { return [cmd "Home"] }
	proc Info {text} { return [cmd "Info([stringify $text])"] }
	proc Insert {} { return [cmd "Insert"] }
	proc Interrupt {} { return [cmd "Interrupt"] }
	proc Key {k} { return [cmd "Key($k)"] }
	proc Keymap {k} { return [cmd "Keymap($k)"] }
	proc Left {} { return [cmd "Left"] }
	proc Left2 {} { return [cmd "Left2"] }
	proc MonoCase {} { return [cmd "MonoCase"] }
	proc MoveCursor {r c} { return [cmd "MoveCursor($r,$c)"] }
	proc Newline {} { return [cmd "Newline"] }
	proc NextWord {} { return [cmd "NextWord"] }
	proc PA {n} { return [cmd "PA($n)"] }
	proc PF {n} { return [cmd "PF($n)"] }
	proc PreviousWord {} { return [cmd "PreviousWord"] }
	proc Quit {} { exit }
	proc Reset {} { return [cmd "Reset"] }
	proc Right {} { return [cmd "Right"] }
	proc Right2 {} { return [cmd "Right2"] }
	proc Rows {} { return [lindex [Status] 6] }
	proc SetFont {font} { return [cmd "SetFont($font)"] }
	proc Snap {args} { return [cmd "Snap([commafy $args])"] }
	proc Status {} {
		variable verbose
		variable pid
		if {$pid==0} { return -code error "Not started yet." }
		if {$verbose} {puts "+(nothing)"}
		send "\r"
		expect {
			"*ok\r\n" { set r $expect_out(buffer) }
			eof { set pid 0; error "process died" }
		}
		return [string range $r 0 [expr [string length $r]-7]]
	}
	proc String {text} { return [cmd "String([stringify $text])"] }
	proc SysReq {} { return [cmd "SysReq"] }
	proc Tab {} { return [cmd "Tab"] }
	proc ToggleInsert {} { return [cmd "ToggleInsert"] }
	proc ToggleReverse {} { return [cmd "ToggleReverse"] }
	proc TemporaryKeymap {args} { return [cmd "TemporaryKeymap($args)"] }
	proc Transfer {args} { return [cmd "Transfer([commafy $args])"] }
	proc Up {} { return [cmd "Up"] }
	proc Wait {args} { return [cmd "Wait([commafy $args])"] }

	# Extra function to toggle verbosity on the fly.
	proc Setverbose {level} {
		variable verbose
		set verbose $level
		return
	}

	# Export all the user-visible functions.
	namespace export \[A-Z\]*
}

# Import all of the exported functions.
namespace import x3270::*
