 q# HAL for Raspberry Pi with https://github.com/rpi-ws281x/rpi-ws281x-python
# See https://github.com/jgarff/rpi_ws281x for more details on this library.
#
# The below code assumes the LED strip is connected to GPIO 18 (PCM CLK)
# (see https://pinout.xyz) and that you've installed the rpi_ws281x library.
#
# For Python 2.x:
#
#   sudo apt install -y python-pip; sudo pip install rpi_ws281x
#
# For Python 3.x:
#
#   sudo apt install -y python3-pip; sudo pip3 install rpi_ws281x
#
#
from rpi_ws281x import PixelStrip, Color
from gpiozero import Button
import utime

# LED strip configuration:
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255  # Set to 0 for darkest and 255 for brightest
LED_INVERT = False    # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53
BUTTON_LEFT = 17
BUTTON_RIGHT = 27

class RaspberryPiHAL:
	def __init__(self, config):
		self.left_button = Button(BUTTON_LEFT)
		self.right_button = Button(BUTTON_RIGHT)
		#set button callback
		self.left_button.when_pressed = self.button_irq_press
		self.right_button.when_pressed = self.button_irq_press
		self.left_button.when_released = self.button_irq
		self.right_button.when_released = self.button_irq
		self.suspend_host_pin.when_held = self.button_irw_held
		self.left_down_t = 0
		self.right_down_t = 0
		self.button_state = 0
		self.num_pixels = config['LedMatrix']['columns'] * config['LedMatrix']['stride']
		self.strip = PixelStrip(self.num_pixels, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
		self.strip.begin()
	def init_display(self, num_pixels=64):
		self.clear_display()
	def clear_display(self):
		c = Color(0, 0, 0)
		for i in range(self.num_pixels):
			self.strip.setPixelColor(i, c)
		self.strip.show()
	def update_display(self, num_modified_pixels):
		if not num_modified_pixels:
			return
		self.strip.show()
	def put_pixel(self, addr, r, g, b):
		self.strip.setPixelColor(addr % self.num_pixels, Color(r, g, b))
	def reset(self):
		self.clear_display()

	def set_rtc(self, t):
		#Not relevant
		pass
	def set_auto_time(self, enable=True):
		#Not relevant
		pass
	def suspend_host(self, restart_timeout_seconds):
		#Not relevant
		pass
	def button_irq_press(self):
		if(button_left.is_pressed):
			self.left_down_t = utime.ticks_ms()
		if(button_right.is_pressed):
			self.right_down_t = utime.ticks_ms()

	def button_irq(self):
		t = utime.ticks_ms() - self.button_down_t
		shift = 0 if self.left_button.value else 4
		if t > 1500:
			self.button_state |= 1<<(shift+2)
		elif t > 500:
			self.button_state |= 1<<(shift+1)
		elif t > 80:
			self.button_state |= 1<<(shift+0)
		self.button_down_t = 0

	def process_input(self):
		#TODO: implement
		# Process button input
		button_state = self.button_state
		if button_state:
			try:
				if button_state & 1:
					# Notify the host about the button press in a similar manner
					# to what ArduinoSer2FastLED does
					print('LEFTB_SHRT_PRESS\n')
				elif button_state & 2:
					print('LEFTB_LONG_PRESS\n')
				elif button_state & 4:
					print('LEFTB_HOLD_PRESS\n')
				elif button_state & 16:
					print('RGHTB_SHRT_PRESS\n')
				elif button_state & 32:
					print('RGHTB_LONG_PRESS\n')
				elif button_state & 64:
					print('RGHTB_HOLD_PRESS\n')
			except OSError as e:
				print('HAL: UART write failed: {}'.format(e.args[0]))
		self.button_state = 0

		return button_state


