-- Glu supports a number of native dialogs.
-- You can also create your own custom dialogs (see YesNoDialog below).

local glu = glu()
local cv = canvas()
local gp = require "gplus"
local cp = require "cplus"

local buttongap = 10
local cvwd = 400
local cvht = 8*cp.buttonht + 9*buttongap + 20
local note_button, warn_button, string_button, file_button, folder_button
local save_button, savechanges_button, custom_button, exit_button

--------------------------------------------------------------------------------

function ShowNote()
    glu.note("Hitting the Cancel button will exit this script.", true)
end

--------------------------------------------------------------------------------

function ShowWarning()
    glu.warn("Warnings are similar to notes, but come with a system beep.", true)
end

--------------------------------------------------------------------------------

function GetString()
    local name = glu.getstring("Enter your name:")
    if name then
        glu.show(name)
    else
        glu.show("You hit the Cancel button.")
    end
end

--------------------------------------------------------------------------------

function GetFile()
    local filepath = glu.open() -- this will choose all file types
    -- do this to choose a particular type of file:
    -- local filepath = glu.open("Choose a Lua file", "Lua files (*.lua)|*.lua")
    if #filepath > 0 then
        glu.show(filepath)
    else
        glu.show("You hit the Cancel button.")
    end
end

--------------------------------------------------------------------------------

function GetFolder()
    local dirpath = glu.open("Choose a folder", "dir")
    if #dirpath > 0 then
        glu.show(dirpath)
    else
        glu.show("You hit the Cancel button.")
    end
end

--------------------------------------------------------------------------------

local savedir = glu.getdir("data")

function SaveFile()
    -- save current canvas in a .png file
    local pngpath = glu.save("Save canvas as PNG file", "PNG (*.png)|*.png", savedir, "canvas.png")
    if #pngpath > 0 then
        cv.save(0, 0, cvwd, cvht, pngpath)
        glu.show("Canvas was saved in "..pngpath)
        -- update savedir for next call by stripping off the file name
        local pathsep = savedir:sub(-1)
        savedir = pngpath:gsub("[^"..pathsep.."]+$","")
    else
        glu.show("You hit the Cancel button.")
    end
end

--------------------------------------------------------------------------------

function SaveChanges()
    local answer = glu.savechanges("Save your changes?", 
                                   "If you don't save, the changes will be lost.") 
    glu.show("answer = "..answer)
end

--------------------------------------------------------------------------------

function YesNoDialog(question)
    -- create a simple custom modal dialog that displays the given question
    -- and returns "Yes" or "No", depending on which button was clicked;
    -- first we need to prevent the existing buttons from being clicked:
    cp.disable_all()
    local result = ""
    local yes_button = cp.button("Yes", function() result = "Yes" end)
    local no_button = cp.button("No", function() result = "No" end)
    yes_button.setbackcolor{0,128,0,255}
    no_button.setbackcolor{128,128,128,255}
    local buttht = yes_button.ht
    local totalbuttwd = no_button.wd+10+yes_button.wd
    
    -- save canvas in a clip and then darken everything
    cv.copy(0,0,0,0,"canvas")
    cv.replace("*#-128 *#-128 *#-128 *#")
    
    -- draw the dialog "window" in middle of canvas
    local oldblend = cv.blend(0)
    local oldrgba = cv.rgba(cp.black)
    local oldfont, oldsize = cv.font("default-bold",12)
    local textwd, textht = cv.text("q", question)
    local dialogwd, dialoght = math.max(textwd+40,totalbuttwd+20), textht+40+buttht+10
    local canvaswd, canvasht = cv.getsize("")
    local x = (canvaswd - dialogwd)//2
    local y = (canvasht - dialoght)//2
    cv.rgba(cp.gray)
    cp.round_rect(x+5, y+5, dialogwd, dialoght, 10, 0, {0,0,0,128}) -- shadow
    cp.round_rect(x, y, dialogwd, dialoght, 10, 1, {230,230,230,255})
    yes_button.show(x+dialogwd-yes_button.wd-10, y+dialoght-buttht-10)
    no_button.show(x+dialogwd-totalbuttwd-10, y+dialoght-buttht-10)
    cv.blend(1)
    cv.paste("q", x+20, y+25)
    cv.delete("q")
    glu.update()

    -- enter a modal event loop
    while true do
        local event = cp.process( glu.getevent() )
        if event == "key return none" then
            result = "Yes" -- the default button
        end
        if #result > 0 then break end
    end
    
    -- remove local buttons
    no_button.hide()
    yes_button.hide()
    
    -- restore canvas
    cv.blend(0)
    cv.paste("canvas",0,0)
    glu.update()
    cv.delete("canvas")
    
    -- restore settings and return which button was clicked
    cv.blend(oldblend)
    cv.rgba(oldrgba)
    cv.font(oldfont, oldsize)
    cp.enable_all() -- restore the buttons that were disabled by cp.disable_all
    return result   -- "Yes" or "No"
end

--------------------------------------------------------------------------------

function CustomDialog()
    glu.show( YesNoDialog("Do you like Lua?") )
end

--------------------------------------------------------------------------------

function CreateCanvas()
    cv.create(cvwd, cvht)
    cv.position("middle")
    -- all these buttons use the cplus default settings
    note_button = cp.button("Note...", ShowNote)
    warn_button = cp.button("Warn...", ShowWarning)
    string_button = cp.button("Your Name...", GetString)
    file_button = cp.button("Choose File...", GetFile)
    folder_button = cp.button("Choose Folder...", GetFolder)
    save_button = cp.button("Save Canvas...", SaveFile)
    savechanges_button = cp.button("Save Changes...", SaveChanges)
    custom_button = cp.button("Custom Dialog...", CustomDialog)
    exit_button = cp.button("Exit", glu.exit)
end

--------------------------------------------------------------------------------

function DrawButton(button, y)
    -- draw button at given y position and centered horizontally in canvas
    button.show((cvwd - button.wd) // 2, y)
    -- return y position of next button
    return y + button.ht + buttongap
end

--------------------------------------------------------------------------------

function DrawCanvas()
    cv.rgba(cp.white)
    cv.fill()
    cv.rgba(cp.black)   -- for text
    cv.blend(2)         -- canvas background is opaque

    -- show Exit button in bottom right corner of canvas
    exit_button.show(cvwd - exit_button.wd - 20,
                     cvht - exit_button.ht - 20)

    local y = 20
    y = DrawButton(note_button, y)
    y = DrawButton(warn_button, y)
    y = DrawButton(string_button, y)
    y = DrawButton(file_button, y)
    y = DrawButton(folder_button, y)
    y = DrawButton(save_button, y)
    y = DrawButton(savechanges_button, y)
    y = DrawButton(custom_button, y)

    glu.update()
end

--------------------------------------------------------------------------------

function EventLoop()
    while true do
        local event = cp.process( glu.getevent() )
        -- event is an empty string if glu.getevent() was empty
        -- or if cp.process handled a click in a button
        if #event == 0 then
            glu.sleep(5) -- don't hog CPU if idle
        else
            -- allow key events like "key h none" to show help window
            glu.doevent(event)
        end
    end
end

--------------------------------------------------------------------------------

function Main()
    glu.settitle("Dialogs")
    glu.show("Button results will be shown here.")
    CreateCanvas()
    DrawCanvas()
    EventLoop()
end

--------------------------------------------------------------------------------

status, err = xpcall(Main, gp.trace)
if err then glu.continue(err) end
-- the following code is always executed
cv.delete()
