--[[
	This file is part of NeuralView.

    NeuralView is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    NeuralView is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with NeuralView.  If not, see <http://www.gnu.org/licenses/>.
--]]

---
-- Interface creation utilities.
local Utils, UtilsMT = nv_module("view.Utils")

---
-- Creates a new frame with a label.
--
-- @param label Frame label
-- @return New frame
function Utils.new_frame(label)
	local label = gtk.Label.new("<b>" .. label .. "</b>")
	label:set("use-markup", true)
	local frame = gtk.Frame.new()
	frame:set("label-widget", label, "shadow", gtk.SHADOW_NONE)
	
	return frame
end

---
-- Creates a stock button with a custom label.
--
-- @param stock Stock id
-- @param label Label to override the stock one
-- @return New Button
function Utils.new_button(stock, label)
	local image = gtk.Image.new()
	image:set("stock", stock)
	local button = gtk.Button.new_with_mnemonic(label)
	button:set("image", image)
	
	return button
end

---
-- Creates a stock tool button. Makes GTK+ respect the use-underline
-- property!
--
-- @param stock Stock id
-- @param label Label to override the stock one
-- @return New ToolButton
function Utils.new_tool_button(stock, label)
	local button = gtk.ToolButton.new(gtk.Image.new_from_stock(stock), '')
	local label = gtk.Label.new_with_mnemonic(label)
	button:set("label-widget", label)
	
	return button
end

---
-- Creates a label | main widget ToolItem.
--
-- @param label Label widget
-- @param entry Widget to serve as content
-- @return New composed tool item
function Utils.new_tool_item(label, entry)
	local item = gtk.ToolItem.new()
	local hbox = gtk.HBox.new(false, 0)
	hbox:pack_start(label, false, true, 0)
	hbox:pack_start(entry, true, true, 5)
	item:add(hbox)
	label:set("mnemonic-widget", entry)
	
	return item
end

local iter = gtk.TreeIter.new()

---
-- Populates a model using values from a table.
-- Does not accept nils.
--
-- @param model Model to be populated
-- @param values Values in the form { {cell11, cell12}, {cell21, cell22}, ... }
-- @param clear true to also clear the model before the population
-- @param view View of the model to freeze signals (optional)
function Utils.populate_model(model, values, clear, view)
	if view then view:set("model", nil) end
	if clear then model:clear() end
	
	for i, row in ipairs(values) do
		model:append(iter)
		model:seto(iter, unpack(row))
	end
	
	if view then view:set("model", model) end
end

-- confirmation dialog table
local confirm = {}

local function build_confirm_dlg()
	confirm.dlg = gtk.Dialog.new()
	confirm.dlg:set("window-position", gtk.WIN_POS_CENTER, "resizable", false,
		"title", _"Confirmation", "role", "confirm", "modal", true,
		"icon", NVIcon)
	confirm.no, confirm.yes = confirm.dlg:add_buttons("gtk-cancel", gtk.RESPONSE_CANCEL,
		"gtk-ok", gtk.RESPONSE_OK)
	local vbox = confirm.dlg:get_content_area()
	local image = gtk.Image.new()
	image:set("icon-size", 6, "stock", "gtk-dialog-warning")
	confirm.label = gtk.Label.new("")
	confirm.label:set("selectable", true, "use-markup", true)
	local hbox = gtk.HBox.new(false, 10)
	hbox:add(image, confirm.label)
	vbox:add(hbox)
	vbox:show_all()
end

---
-- Shows a confirmation dialog (Cancel, OK buttons).
--
-- @param message Message to show on the dialog
-- @return true if the user clicked OK, false otherwise
function Utils.show_confirmation(message)
	if not confirm.dlg then
		build_confirm_dlg()
	end
	
	confirm.label:set("label", message)
	confirm.no:grab_focus()
	local res = confirm.dlg:run()
	confirm.dlg:hide()
	
	return res == gtk.RESPONSE_OK
end

-- info dialog table
local info = {}

local function build_info_dlg()
	info.dlg = gtk.Dialog.new()
	info.dlg:set("window-position", gtk.WIN_POS_CENTER, "resizable", false,
		"title", _"Information", "role", "info", "modal", true, "icon", NVIcon)
	info.dlg:add_buttons("gtk-ok", gtk.RESPONSE_OK)
	local vbox = info.dlg:get_content_area()
	local image = gtk.Image.new()
	image:set("icon-size", 6, "stock", "gtk-dialog-info")
	info.label = gtk.Label.new("")
	info.label:set("selectable", true, "use-markup", true)
	local hbox = gtk.HBox.new(false, 10)
	hbox:add(image, info.label)
	vbox:add(hbox)
	vbox:show_all()
end

---
-- Shows a info dialog (OK button).
--
-- @param message Message to show on the dialog
function Utils.show_info(message)
	if not info.dlg then
		build_info_dlg()
	end
	
	info.label:set("label", message)
	local res = info.dlg:run()
	info.dlg:hide()
end

return Utils
