#!/usr/bin/wish
##### This is Andreas' original program,
##### with only a few lines changed to enable it to run.

# Installationsverzeichnis
set installdir /usr/local/lib/hangman/extras/1.0
set picturedir $installdir/pictures.1.0
set wordsfilename $installdir/words.1.0
set RandFileName /dev/kmem
set randseed 1000

# Source Datei fuer den Zufallszahlengenerator
source random.tcl

##### no changes below here.

# Globale Variablen
set Version 1.0
set wm_title "Hangman"
set startpicture start.gif
set startpicture2 little1.gif
set framewidth 150
set frameback brown
set labeltext "Press a key"
set labeltext2 "Enter a letter"
set labelback green
set buttontext1 "Restart"
set buttontext2 "Exit"
set exitbuttonwidth 7
set restartbuttonwidth [set exitbuttonwidth]
set randseed 1000
set imageborder 0
set entrylabelwidth 5
set wordlabelwidth 15
set wordlabelcolor blue
set inputcount -1
set piccount 0
set winmessage "Thank you :-)"

############
#Prozeduren#
############

# Bild austauschen
proc ChangePicture picture {
	# Globale Variablen
	global imageborder picturedir

	# Label loeschen falls es existiert
	catch {destroy .label}

	# Bild in Label anzeigen
	image create photo Image  \
		-file $picturedir/$picture
	label .label -image Image -bd $imageborder
	pack .label -side left
}

# Punkte in Label setzen
proc MakePoints {} {
	# Word als Globale Variable
	global Word Points	

	# Wort laden
	set Word [LoadWord]
	
	# Liste mit Punken
	set Points {}
	
	# Lange des Wortes errechnen und Punkte setzen
	for {set i 1} {$i <= [string length $Word]} {incr i} {
		lappend Points "."
	}

	# Punktestring als Rueckgabewert
	return $Points
}

# Spielstart nach einem Tastendruck
proc StartGame {} {
	# Globale Variablen
	global labeltext2

	# Binding fuer Tastendruck aufheben
	bind all <KeyPress> {
	}
	
	# Messagelabeltext veraendern
	.frame.label configure -text $labeltext2	

	# Punkte in Label zeichnen
	MakeLabel [MakePoints]

	# Eingabefokus setzen
	focus .frame.frameentry.entry

	# Eingabe vergleichen bei Tastendruck
	bind .frame.frameentry.entry <KeyRelease> {StartControl}
}

# Bei Tastendruck Eingabe vergleichen
proc StartControl {} {
	# Globale Variablen
	global inputcount picturedir piccount Entry lword Points \
	winmessage
	# Vergleichen, ob die Eingabe in dem Wort enthalten ist
	TestInput step[expr $piccount].gif
	
	# Testen ob Versuche ueberschritten oder Raetsel geloest
	if {$piccount == 12} {
		ChangeLittlePic little3.gif
		ChangeMessageLabel $lword
		bind .frame.frameentry.entry <KeyRelease> {}
	} elseif {$lword == $Points} {
		ChangeLittlePic little2.gif
		ChangeMessageLabel $winmessage
		bind .frame.frameentry.entry <KeyRelease> {}		
	}
}

# Message-Label aendern
proc ChangeMessageLabel Text {
	.frame.label configure -text $Text
}

# Kleines Bild aendern
proc ChangeLittlePic Picture {
	# Globale Variablen
	global picturedir	

	# Bild anzeigen
	image create photo Imagex -file \
		$picturedir/$Picture
	.frame.label2 configure	-image Imagex
}

# Testen ob eingabe erfolgreich. Sonst neues Bild zeichnen
proc TestInput Picture {
	# Globale Variablen
	global inputcount piccount

	if {[CompareInput $inputcount] != "TRUE"} {
		ChangePicture $Picture
		incr piccount
	}	

	incr inputcount
}

# Eingabe vergleichen
proc CompareInput InputNum {
	# Globale Variablen
	global Word Entry Points lword

	# Wort als Liste
	set lword {}

	# String in Liste verwandeln
	for {set i 0} {$i < [string length $Word]} {incr i} {
		lappend lword [string index $Word $i]
	}

	# Eingetragenen Buchstaben mit Wort vergleichen
	for {set i 0} {$i < [llength $lword]} {incr i} {
		if {[lindex $lword $i] == \
			[string index $Entry $InputNum]} {
			set Points [lreplace $Points $i $i\
				    [string index $Entry $InputNum]]
			set ret "TRUE"
		}
	}

	# Label aendern
	MakeLabel $Points

	# Testen ob ret existiert
	if {[info exists ret] == 1} {
		return $ret
	} else {
		return "FALSE"
	}
}

# Labeltext veraendern
proc MakeLabel Text {
	.frame.frameentry.wordlabel configure -text $Text	
}

# Wort aus einer Datei lesen
proc LoadWord {} {
	# Globale Variablen
	global wordsfilename randseed

	# Liste der Woerter
	set wordslist {}

	# Datei oeffnen
	set wordfile [open $wordsfilename r]

	# Solange lesen bis Dateiende erreicht ist.
	for {set i 0} {[gets $wordfile getword]} {incr i} {
		# Testen ob Dateiende erreicht ist
		if {[eof $wordfile] == 1} {
			break
		}

		# Word an Liste anhaengen
		lappend wordslist $getword
	}
	
	# Ein Wort aus der Liste zufaellig aussuchen und in
	# Kleinbuchstaben umwandeln
	set randnumber [random [llength $wordslist] \
			[random $randseed]]
	set WORD [string tolower [lindex $wordslist $randnumber]]

	# Datei schliessen
	close $wordfile

	# Das Zufallswort als Rueckgabewert
	return $WORD
}

# Spiel neu starten
proc Restart {} {
	# Globale Variablen
	global inputcount piccount	

	# Eingabe loeschen
	.frame.frameentry.entry delete 0 [expr $inputcount +1]
	
	# Zuruecksetzen
	set inputcount 0
	set piccount 1

	# Bilder aendern
	ChangeLittlePic little1.gif
	ChangePicture step0.gif
	StartGame
}

########################
#Starten des Programmes#
########################

# Zeichnet die Oberflaeche und Startet die anderen Prozeduren
# Globale Variablen
global Version wm_title startpicture picturedir \
	framewidth frameback labeltext labelback \
	startpicture2 buttontext1 buttontext2 \
	exitbuttonwidth restartbuttonwidth \

# Windowmanager
wm title . "$wm_title $Version"
wm maxsize . 315 149
wm minsize . 315 149

# Startbild anzeigen
ChangePicture $startpicture

# Frame fuer die rechte Seite
frame .frame -width $framewidth -background $frameback
pack .frame -side right -fill y

# Label fuer Meldungen an den Spieler
label .frame.label -text $labeltext -background $labelback
pack .frame.label -fill x -padx 1m -pady 1m

# Frame fuer das Entrywidget und das Labelwidget
frame .frame.frameentry -background $frameback
pack .frame.frameentry -side top -fill x

# Entry Widget
entry .frame.frameentry.entry -textvariable Entry \
	-width $entrylabelwidth
pack .frame.frameentry.entry -side left -padx 1m -pady 1m

# Label zeichnen
label .frame.frameentry.wordlabel \
-background $wordlabelcolor -width $wordlabelwidth
pack .frame.frameentry.wordlabel -side right -padx 1m -pady 1m

# Label fuer Bilder unter der Eingabe
label .frame.label2 -background $frameback
pack .frame.label2 -padx 1m -pady 1m -fill x

# Startblid unter der Eingabe
ChangeLittlePic $startpicture2

# Frame fuer Buttons
frame .frame.frame -width $framewidth -background $frameback
pack .frame.frame -side top -fill x

# Buttons fuer Spiel Verlassen und Neustart
button .frame.frame.button1 -text $buttontext1 \
	-width $restartbuttonwidth -command Restart
button .frame.frame.button2 -text $buttontext2 \
	-width $exitbuttonwidth -command exit
pack .frame.frame.button1 -side left -padx 1m -pady 1m
pack .frame.frame.button2 -side right -padx 1m -pady 1m

# Binding fuer den Tastendruck der das Spiel startet
bind all <KeyPress> {
	StartGame
}
