#-*- coding:utf-8 -*-

"""
This file is part of OpenSesame.

OpenSesame 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.

OpenSesame 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 OpenSesame.  If not, see <http://www.gnu.org/licenses/>.
"""

from libopensesame.py3compat import *
from variable_inspector_cell import variable_inspector_cell
from libqtopensesame.widgets.base_widget import base_widget
from libqtopensesame.misc import drag_and_drop
from libqtopensesame.misc.translate import translation_context
_ = translation_context(u'variable_inspector', category=u'extension')

class variable_inspector_widget(base_widget):

	"""
	desc:
		The variable inspector widget, which includes the table, filter button,
		etc.
	"""

	def __init__(self, main_window, ext):

		"""
		desc:
			Constructor.

		arguments:
			main_window:	The main-window object.
			ext:			The variable_inspector-extension object.
		"""

		super(variable_inspector_widget, self).__init__(main_window,
			ui=u'extensions.variable_inspector.variable_inspector')
		self.ext = ext
		self.ui.edit_variable_filter.textChanged.connect(self.refresh)
		self.ui.button_help_variables.clicked.connect(self.ext.open_help)
		self.ui.button_reset.clicked.connect(self.ext.reset)
		self.ui.table_variables.mousePressEvent = self.start_drag
		self.refresh()

	def focus(self):

		"""
		desc:
			Sets the focus to the filter box.
		"""

		self.ui.edit_variable_filter.setFocus()

	def var(self):

		"""
		returns:
			desc:	A (var_store, alive) tuple, where alive indicates whether
					the var_store is from an active or finished experiment, or
					from an inactive GUI experiment.
			type:	tuple
		"""

		d = self.main_window.console.get_workspace_globals()
		if u'var' in d and hasattr(d[u'var'], u'inspect'):
			return d[u'var'], True
		return self.experiment.var, False

	def start_drag(self, e):

		"""
		desc:
			Starts a variable drag operation.

		arguments:
			e:
				type:	QMousePressEvent
		"""

		item = self.ui.table_variables.itemAt(e.pos())
		if item is None:
			return
		row = self.ui.table_variables.row(item)
		var = self.ui.table_variables.item(row, 0).text()
		drag_and_drop.send(self.ui.table_variables,
			{
			u'type' : u'variable',
			u'variable' : var}
			)

	def refresh(self):

		"""
		desc:
			Refreshes the table.
		"""

		# Remember the view position
		scrollpos = self.ui.table_variables.verticalScrollBar().sliderPosition()
		col = self.ui.table_variables.currentColumn()
		row = self.ui.table_variables.currentRow()
		filt = str(self.ui.edit_variable_filter.text())
		var_store, alive = self.var()
		self.ui.label_no_heartbeat.setVisible(
			not self.main_window.runner_cls.has_heartbeat())
		self.ui.label_status.setText(
			_(u'Experiment status: <b>%s</b>') % self.main_window.run_status())
		if alive and self.main_window.run_status() == u'finished':
			self.ui.widget_reset_message.show()
		else:
			self.ui.widget_reset_message.hide()
		# Filter the variables if necessary
		if len(filt) > 1:
			d = {}
			for var, info in var_store.inspect().items():
				if filt in var or (info[u'value'] is not None and \
					filt in safe_decode(info[u'value'], errors=u'ignore')) or \
					filt in u' '.join(info[u'source']):
					d[var] = info
		else:
			d = var_store.inspect()
		# Populate the table
		self.ui.table_variables.setRowCount(len(d))
		for i, var in enumerate(sorted(d.keys())):
			info = d[var]
			self.ui.table_variables.setItem(i, 0,
				variable_inspector_cell(var, info))
			self.ui.table_variables.setItem(i, 1,
				variable_inspector_cell(info['value'], info))
			self.ui.table_variables.setItem(i, 2,
				variable_inspector_cell(info['source'], info))
		# Restore the view position
		self.ui.table_variables.setCurrentCell(row, col)
		self.ui.table_variables.verticalScrollBar().setSliderPosition(scrollpos)
