############################################################################
# Autor: 					Jan-Ole Esleben
# e-Mail-Adresse: esleben@cl.uni-heidelberg.de
# Projekt:				Terminparser (beendet WS02)
# 
# Tk-basiertes GUI-Frontend
#
# Dokumentation kann mit rdoc extrahiert werden; Kommentare und
# Dokumentation sind aus Gründen der Kürze und Prägnanz in englischer
# Sprache.
############################################################################
# License: cf. file LICENSE.txt distributed with the code
############################################################################

require 'tk'
require 'grammar'# module processing grammar
require 'text' # module processing text, with grammar data

# The Tagger script - temporary until we know what to do with it
TAGGER = 'ruby tagme.rb'

# Options:
# load grammar     / show regexps button
# load tagged text / evaluate button

# The main GUI class
class TkAP
	# Construct an instance of TkAP - root is the parent element
	def initialize root
		# import instance methods into local scope for Tk blocks
		load_t_p = proc { load_t }
		load_g_p = proc { load_g }
		evaluate_p = proc { evaluate }
		show_regexps_p = proc { show_regexps }
		show_text_p = proc { show_text }
		show_raw_text_p = proc { show_raw_text }
		show_gram_p = proc { show_gram }
		show_findings_p = proc { show_findings }
		root.minsize(400, 350)
		menu_frame = TkFrame.new(root) {
			relief "raised"
			bd 2
			pack("fill"=>"x")
		}
		TkMenubutton.new(menu_frame) { | fb |
			text "Datei"
			TkMenu.new(fb) { | f |
				tearoff false
				fb.configure("menu"=>f)
				add("command", "label"=>"Text laden", "command"=>load_t_p)
				add("command", "label"=>"Grammatik laden", "command"=>load_g_p)
				add("separator")
				add("command", "label"=>"Beenden", "command"=>proc { root.destroy })
			}
			pack("side"=>"left")
		}	
		TkMenubutton.new(menu_frame) { | fb |
			text "Demos"
			TkMenu.new(fb) { | f |
				tearoff false
				fb.configure("menu"=>f)
				add("command", "label"=>"Text auswerten", "command"=>evaluate_p)
				add("command", "label"=>"Regexps anzeigen", "command"=>show_regexps_p)
			}
			pack("side"=>"left")
		}		
		TkMenubutton.new(menu_frame) { | fb |
			text "Anzeigen"
			TkMenu.new(fb) { | f |
				tearoff false
				fb.configure("menu"=>f)
				add("command", "label"=>"Text anzeigen", "command"=>show_raw_text_p)
				add("command", "label"=>"Getaggten Text anzeigen", "command"=>show_text_p)
				add("command", "label"=>"Grammatik anzeigen", "command"=>show_gram_p)
				add("separator")
				add("command", "label"=>"Funde anzeigen", "command"=>show_findings_p)
			}
			pack("side"=>"left")
		}		
		frm = TkFrame.new(root) { pack('fill'=>'both', 'expand'=>'true') }
		text_frm = TkFrame.new(frm)
		@text = TkText.new(text_frm) { | t | # why?
			font "courier 14" 
			background "white"
			height 1
			width 1
			state "disabled"
			bind "Button-1", proc { t.focus }
			TkScrollbar.new(text_frm) { | s | # why?
				pack('side'=>'right', 'fill'=>'y')
				command proc { | *args | t.yview *args }
				t.yscrollcommand proc { | first, last | s.set first, last }
			}
			pack('fill'=>'both', 'expand'=>'true')
		}
		loader_frm = TkFrame.new(frm) { pack('fill'=>"x") }
		TkMessage.new(loader_frm) do
			text "Terminparser (Vorführmodell) v1.0"
			font "helvetica 10 bold italic"
			justify "center"
			width "12c"
			pack('side'=>"left")
		end
		sf = proc { setfont }
		@fonts = TkEntry.new(loader_frm) { 
			font "helvetica 10"
			width "2"
		}
		@fonts.bind("Return") { setfont } 
		@fonts.value = 14
		font_btn = TkButton.new(
			loader_frm,
			'text'=>"Ändern", 
			'font'=>"helvetica 10",
			'command'=>sf
		)
		font_btn.pack('side'=>'right', 'ipadx'=>"1m", 'padx'=>"2m", 'pady'=>"2m")
		@fonts.pack('side'=>'right') 
		TkMessage.new(loader_frm) do
			text "\tSchriftgröße: "
			font "helvetica 10"
			justify "right"
			width "12c"
			pack('side'=>"right")
		end
		text_frm.pack('fill'=>'both', 'expand'=>'true')
	end

	#######
	private
	#######
	
	def evaluate
		# TODO: 
		# break input text up into 2d array
		# go throught each line
		
		raise "No text loaded!" if @text_cont.nil?
		raise "No grammar loaded!" if @grammar.nil?
		@evaluated = Calendar::Text.new(
			@text_cont,
			@grammar_rules
		)
		@evaluated.process
		# TODO: save text (tagged) state
		show_findings
	end

	def show_regexps
		raise "No grammar loaded!" if @grammar.nil?
		tary = []
		@grammar_rules.each do | r |
			tary.push "Type: #{r['type']} :: Score: #{r['score']}\n"
			tary.push "\tRule: #{r['regex']}\n\n"
		end
		@text.configure("state"=>"normal")
		@text.value = tary.join
		@text.configure("state"=>"disabled")
	end

	def load_t
		rawtfile = Tk.getOpenFile()
		return if rawtfile.empty? # exception!
		tfile = '_temporary.xml'
		`#{TAGGER} "#{rawtfile}" #{tfile}`
		@raw_text_cont = IO.readlines(rawtfile).join
		@text_cont = IO.readlines(tfile).join
		@text.configure("state"=>"normal")
		@text.value = @text_cont
		@text.configure("state"=>"disabled")
	end

	def load_g
		@grammar = Tk.getOpenFile
		return if @grammar.empty?
		@grammar_cont = IO.readlines(@grammar).join
		@grammar_rules = Calendar::Grammar.new.precompile(@grammar)
		@text.configure("state"=>"normal")
		@text.value = @grammar_cont
		@text.configure("state"=>"disabled")
	end

	def show_text
		raise "No text loaded!" if @text_cont.nil?
		@text.configure("state"=>"normal")
		@text.value = @text_cont
		@text.configure("state"=>"disabled")
	end
	
	def show_raw_text
		raise "No text loaded!" if @raw_text_cont.nil?
		@text.configure("state"=>"normal")
		@text.value = @raw_text_cont
		@text.configure("state"=>"disabled")
	end

	def show_gram
		raise "No grammar loaded!" if @grammar_cont.nil?
		@text.configure("state"=>"normal")
		@text.value = @grammar_cont
		@text.configure("state"=>"disabled")
	end
	
	def pretty s
		s.gsub! /<[\/]?token.*?>/i, ''
		s.gsub! /<LINEBREAK\/>/, ''
		s.gsub! /[ ]+/, ' '
		s.gsub! /&auml;/, 'ä'
		s.gsub! /&Auml;/, 'Ä'
		s.gsub! /&uuml;/, 'ü'
		s.gsub! /&Uuml;/, 'Ü'
		s.gsub! /&ouml;/, 'ö'
		s.gsub! /&Ouml;/, 'Ö'
		s.gsub! /&eacute;/, 'é'
		s.gsub! /&Eacute;/, 'É'
		s.gsub! /&szlig;/, 'ß'
		s
	end
	
	def show_findings
		raise "Text not evaluated!" if @evaluated.nil?
		@text.configure("state"=>"normal")
		pl = @evaluated.extract("vort")
		ti = @evaluated.extract("vzeit")
		da = @evaluated.extract("vdat")
		ve = @evaluated.extract("vveranst")
		@text.value = "Wer? #{ve ? pretty(ve[1]) : nil}\n\nWo? #{pl ? pretty(pl[1]) : nil}\n\nWann? #{da ? pretty(da[1]) : nil} um #{ti ? pretty(ti[1]) : nil}"
		@text.configure("state"=>"disabled")
	end
	
	def setfont
		@text.configure('font'=>"courier #{@fonts.value}")
		@text.tag_configure("match", 'font'=>"courier #{@fonts.value} bold italic")
	end
end

root = TkRoot.new { title "Terminparser" }
TkAP.new root
Tk.mainloop

# vim:syntax=ruby:
