--include GtkEngine.e
include tinewg.exw
include std/search.e
include std/io.e
include std/filesys.e
include std/sequence.e
include std/text.e

-- EuGTK keywords are in blue;

 ------------------------------------------------------------------------
-- variables;
------------------------------------------------------------------------
integer max, ct = 0
object avail, blanks, current_word
-- max limits number of guesses allowed;
-- ct tracks how many guesses so far;
-- avail is the set of un-guessed letters, initially a...z;
-- blanks holds substitute characters to use in place of hidden letters;

atom keypressed = routine_id("KeyPressed")
-- 'forward' link to the 'brains' of the game;

sequence file = canonical_path("worte.txt")
sequence words = read_lines(file)

------------------------------------------------------------------------
-- interface;
------------------------------------------------------------------------
--constant win = create(GtkWindow)
WindowType=StandardWin
Window("HangMan",-1,-1,460,240)
--      set(win,"border width",10)
--      connect(win,"destroy","Quit") -- on program end;
--      connect(win,"key-press-event",keypressed)  
SetHandler(WinHwnd,Key,keypressed)

--constant panel = create(GtkBox,1)
--      add(win,panel)

--constant display = create(GtkLabel) -- for word being guessed;
constant display=Control(Label,"",30,10,400,80)
constant font1=NewFont("Arial",28,1,0,0,)
SetFont(display,font1)
--      set(display,"font","bold 24")
--      add(panel,display)

--constant lbl1 = create(GtkLabel,"Guess the word") -- for status;
constant lbl1=Control(Label,"Guess the word",30,90,400,40)
constant font2=NewFont("Arial",12,0,0,0)
SetFont(lbl1,font2)
--      set(lbl1,"font","8")
--      add(panel,lbl1)

-- There is no Grid in tinEWG
--constant grid = create(GtkGrid) -- to hold button set;
--      add(panel,grid)
--      set(grid,"row spacing",2)
--      set(grid,"column spacing",2)

object letters = repeat(0,'z'-'a'+1) -- build a set of empty buttons;
integer x = 0, y = 130, z = 0

constant font3=NewFont("Arial",14,0,0,0)

for i = 1 to length(letters) do
        z = 'a'+i-1
        letters[i] = Control(ClickLabel,sprintf("%s",z),x*35,y,35,35)  --ClickLabel fits better
        SetHandler(letters[i],Key,keypressed)
        SetHandler(letters[i],Click,keypressed)
        SetFont(letters[i],font3)
        --SetWindowTheme(letters[i],0,0)
--      set(grid,"attach",letters[i],x,y,1,1)
        x += 1 if x > 12 then x = 0 y += 35 end if -- time for a new row;
end for

new_word()      -- get a new word and initialize counters;
--set(display,"markup",FormatWord(current_word))
SetText(display,FormatWord(current_word))
--show_all(win)
--main()
WinMain()
----------------------------------------------------------------------------------------------------------
procedure new_word() -- selects a random word, resets available letters;
----------------------------------------------------------------------------------------------------------
        current_word = words[rand(length(words))] 
        current_word = lower(current_word)              -- my german wordlist has uppercase letters
        avail = series('a',1,32,'+')                    -- set of {'a'...'z'}
        blanks = repeat('_',length(avail))              -- to hide unguessed letters;
        ct = 0                                          -- number of tries so far;
        max = 2 * length(current_word)          -- number of tries allowed;

--      set(display,"markup",FormatWord(current_word)) 
        SetText(display,FormatWord(current_word)) 
        for i = 1 to length(letters) do                 -- reset colors;
--              set(letters[i],"background","gray")
                SetColor(letters[i],CL_BLACK,CL_GRAY)               
        end for
end procedure

---------------------------------------------------------------------------------------------------
--global function KeyPressed(atom ctl, atom event) -- event handler;
global procedure KeyPressed()
--end function
---------------------------------------------------------------------------------------------------
-- this function is linked to both keypresses and button clicks, 
-- so we need to determine which happened;
integer key

--if is_in_range(event,{'a','z'}) then key = event   -- button clicked;
--else key = lower(peek(event+20))                  -- keyboard input;
--end if
key=0 -- make sure key has a Value
if Event=Key then
    if is_in_range(EventItem,{'a','z'}) then key = EventItem end if
else
    if Event=Click then
        for i=1 to length(letters) do
            if EventOwner=letters[i] then
                key=i+96  --for small letters
            end if
        end for
    end if  
end if


if is_in_list(key,avail) then                           -- in set of unused letters?;
        ct += 1                                                 -- new guess counts;
        if find(key,current_word) > 0 then
--              set(letters[key-'a'+1],"background","green")
                SetColor(letters[key-'a'+1],CL_BLACK,CL_GREEN)
        else  
--              set(letters[key-'a'+1],"background","yellow")
                SetColor(letters[key-'a'+1],CL_BLACK,CL_YELLOW)
        end if

        avail = remove_all(key,avail) -- remove letter from available set;

--      set(display,"markup",FormatWord(current_word))
        SetText(display,FormatWord(current_word))
        if ct > max then                        -- too many tries;
--              if Question(win,"Sorry",
--                      sprintf("The word was %s",{current_word}),
--                      "Play again?") = MB_YES then    
                if AskMsg(sprintf("The word was %s",{current_word})&"\n\rPlay again?","Sorry") then
                        new_word()
                else abort(0)
                end if
        end if

end if
--return 1
end procedure

-------------------------------------------------------------------------------------------------------------
function FormatWord(object word) -- handles display and testing a for win;
-------------------------------------------------------------------------------------------------------------
object result = ""

--set(lbl1,"text",sprintf("%d letter word,\n%d guesses left.",
--              {length(current_word),max-ct}))
SetText(lbl1,sprintf("%d letter word,\n%d guesses left.",
                {length(current_word),max-ct}))
word = transmute(word,avail,blanks)     -- change un-guessed letters to underscores,
                                                        -- using the still untried letters remaining;
for i = 1 to length(word) do                    -- add spaces between letters (looks better!);
        result &= word[i]  & ' '
end for

if not find('_',word) then              -- if no hidden letters left, puzzle solved!

--      set(display,"markup",sprintf("%s",{result})) 
        SetText(display,sprintf("%s",{result}))
--      if Question(win,"Congratulations!",current_word,
--              sprintf("You guessed it in %d tries!\nPlay again?",ct)) = MB_YES then
--              new_word()
--              return FormatWord(current_word)
        if AskMsg(sprintf("You guessed it in %d tries!\nPlay again?",ct),"Congratulations!") then
            new_word()
            return FormatWord(current_word)
            --else abort(0)
        else    CloseApp(0)  -- CloseApp is the better choice i think
        end if

end if

return result
end function