from ableton.v2.control_surface.control import ButtonControl
from ableton.v2.control_surface import DeviceBankRegistry, Component
from ableton.v2.control_surface.components import  DeviceNavigationComponent as DeviceNavigationComponentBase
from ableton.v2.base import nop
from ableton.v3.control_surface.components import DeviceComponent, DeviceParametersComponent, DeviceBankNavigationComponent as DeviceBankNavigationComponentBase

from ..skin import Colors
from ..color import Color

class DeviceNavigationComponent(DeviceNavigationComponentBase):
	"A DeviceNavigationComponent with some Exquis fixes"
	color_class_name = 'Device.ItemNavigation'

	def _appoint_device(self, device):
		self._device_component._set_device(device)

	def _update_device(self):
		self._update_item_provider(self._device_component.device)

class DeviceBankNavigationComponent(DeviceBankNavigationComponentBase):
	"A DeviceBankNavigationComponent with some Exquis fixes"

	def _should_skip_first_bank(self):
		"Fixes a bug in bank display"
		return False
	
	def _update_bank_select_buttons(self):
		super(DeviceBankNavigationComponent, self)._update_bank_select_buttons()
		# Redraw the entire slider before updating the colors
		for i in range(0, self.bank_select_buttons.control_count):
			control = self.bank_select_buttons[i]
			if control._control_element:
				control._control_element.set_light(Color(0))
		self.bank_select_buttons._update_controls()

class DeviceModeComponent(Component):
	"A component that handles the Device part of the Tracks mode of the Exquis"

	encoder0_push = ButtonControl()
	encoder1_push = ButtonControl()
	encoder2_push = ButtonControl()
	encoder3_push = ButtonControl()

	def __init__(self, *a, **k):
		super(DeviceModeComponent, self).__init__(*a, **k)

		self.device = DeviceComponent(
			name="NotesDevice",
			bank_size=4,
			device_bank_registry=DeviceBankRegistry(),
			toggle_lock=nop,
			bank_navigation_component_type=DeviceBankNavigationComponent,
		)

		bank_select_buttons = self.device._bank_navigation_component.bank_select_buttons
		for i in range(0, bank_select_buttons.control_count):
			control = bank_select_buttons[i]
			control.color = Colors.Device.Bank.NoItem
			control.checked_color = Colors.Device.Bank.Selected
			control.unchecked_color = Colors.Device.Bank.NotSelected
			control._unavailable_color = Colors.Device.Bank.NoItem
		bank_select_buttons._unavailable_color = Colors.Device.Bank.NoItem
		
		self.device_parameters = DeviceParametersComponent(
			name="NotesDeviceParameter",
			parameter_provider=self.device,
		)
		self.device_navigation = DeviceNavigationComponent(
			name="NotesDeviceNavigation",
			device_component=self.device,
		)

	def set_encoders(self, _):
		self.device_parameters.set_parameter_controls(_)
		
	def set_device_buttons(self, _):
		self.device_navigation.select_buttons.set_control_element(_)
		self.device_navigation._update_button_colors()
	
	def set_bank_buttons(self, _):
		self.device._bank_navigation_component.set_bank_select_buttons(_)
	
	def update(self):
		super(DeviceModeComponent, self).update()

	@encoder0_push.released_immediately
	def on_encoder0_push_pressed(self, _):
		self.on_reset_parameter_button(0)
	
	@encoder1_push.released_immediately
	def on_encoder1_push_pressed(self, _):
		self.on_reset_parameter_button(1)

	@encoder2_push.released_immediately
	def on_encoder2_push_pressed(self, _):
		self.on_reset_parameter_button(2)

	@encoder3_push.released_immediately
	def on_encoder3_push_pressed(self, _):
		self.on_reset_parameter_button(3)
	
	def on_reset_parameter_button(self, index):
		try:
			# Reset the parameter to its default value
			control = self.device_parameters.controls.__getitem__(index)
			parameter = control.mapped_parameter
			parameter.value = parameter.default_value
		except Exception as e:
			pass
