--[[
	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/>.
--]]

---
-- Dialog that allows the user to test the network with a data file.
local NetworkTester, NetworkTesterMT = nv_module("view.NetworkTester")

local DataSelector = require("view.DataSelector")
local Utils = require("view.Utils")

---
-- Constructor.
--
-- @param parent Parent window
-- @return New instance of NetworkTester 
function NetworkTester.new(parent)
	local self = {}
	setmetatable(self, NetworkTesterMT)
	
	self:build_gui(parent)
	
	return self
end

-- layout params
local xpad, ypad, of = 5, 0, gtk.EXPAND + gtk.FILL

---
-- Builds the interface.
--
-- @param parent Parent window
-- @private
function NetworkTester:build_gui(parent)
	self.dialog = gtk.Dialog.new()
	self.dialog:set("transient-for", parent, "title", _"Test network",
		"icon", NVIcon)
	self.dialog:add_button("gtk-close", gtk.RESPONSE_OK)
	self.vbox = self.dialog:get_content_area()
	
	self.table = gtk.Table.new(3, 3)
	
	self.data_label = gtk.Label.new_with_mnemonic(_"Test _data")
	self.data_label:set("xalign", 1)
	self.data_sel = DataSelector.new()
	self.data_label:set("mnemonic-widget", self.data_sel.widget,
		"tooltip-text", _"Test data to be used")
	
	self.data_test = Utils.new_button("gtk-execute", _"Test")
	self.data_test:connect("clicked", self.test, self)
	self.data_test:set("tooltip-text", _"Test the network")
	
	self.table:attach(self.data_label, 0, 1, 0, 1, gtk.FILL, 0, xpad, ypad)
	self.table:attach(self.data_sel.widget, 1, 2, 0, 1, of, 0, xpad, ypad)
	self.table:attach(self.data_test, 2, 3, 0, 1, gtk.FILL, 0, xpad, ypad)
	
	self.mse_label = gtk.Label.new(_"Mean squared error")
	self.mse_label:set("xalign", 1, "tooltip-text", _"Test result")
	self.mse_res = gtk.Label.new("-")
	self.mse_res:set("xalign", 0)
	
	self.table:attach(self.mse_label, 0, 1, 1, 2, gtk.FILL, 0, xpad, ypad)
	self.table:attach(self.mse_res, 1, 3, 1, 2, of, 0, xpad, ypad)
	
	self.bit_label = gtk.Label.new(_"Bit fail")
	self.bit_label:set("xalign", 1, "tooltip-text", _"Test result")
	self.bit_res = gtk.Label.new("-")
	self.bit_res:set("xalign", 0)
	
	self.table:attach(self.bit_label, 0, 1, 2, 3, gtk.FILL, 0, xpad, ypad)
	self.table:attach(self.bit_res, 1, 3, 2, 3, of, 0, xpad, ypad)
	
	self.vbox:pack_start(self.table)
	self.vbox:show_all()
end

---
-- Prepares the dialog for tests.
function NetworkTester:prepare(project)
	self.project = project
	local data_array = project and project.data
	local has_data = data_array and #data_array > 0 or false
	self.data_sel:prepare(data_array)
	self.data_test:set("sensitive", has_data)
end

---
-- Tests the current network with the selected data.
--
-- @private
function NetworkTester:test()
	local data = self.data_sel:get()
	
	if data then
		local net = self.project.network
		net:reset_MSE()
		net:test_data(data)
		
		local mse = net:get_MSE()
		local bit_fail = net:get_bit_fail()
		
		self.mse_res:set("label", string.format("%.6f", mse))
		self.bit_res:set("label", bit_fail)
	end
end

---
-- Runs the network tester.
--
-- @param project Project to use
function NetworkTester:run(project)
	self:prepare(project)
	
	self.dialog:run()
	self.dialog:hide()

	self:prepare()
end

return NetworkTester
