import rgb
import time
import buttons
import defines
import wifi
import ntp
import default_icons
import system

data_initialized = False
settings_mode = False
settings_data = 0 # None, Time
settings_size = 2 # 3x4, 3x5, 4x6
settings_pos = 0 # center, topleft, topright
settings_background = 1 # on, dimmed, off
settings_foreground = 2 # white, black, inverted

def initialize_data():
	global data_initialized
	if data_initialized:
		return
	
	rgb.enablecomp()
	data, size, frames = default_icons.animation_connecting_wifi
	rgb.clear()
	rgb.framerate(3)
	rgb.gif(data, (12, 0), size, frames)
	
	if not wifi.status():
		wifi.connect()
	if wifi.wait():
		if ntp.set_NTP_time():
			data_initialized = True
	else:
		data, frames = default_icons.icon_no_wifi
		rgb.image(data, (12, 0), (8,8))
		time.sleep(3)
	
	rgb.clear()
	rgb.framerate(30)
	rgb.disablecomp()

def input_a(pressed):
	global settings_mode
	global settings_data
	if pressed:
		if not settings_mode:
			initialize_data()
			if data_initialized:
				settings_mode = True
				if settings_data == 0:
					settings_data = 1
		else:
			settings_data = (settings_data + 1) % 2

def input_b(pressed):
	global exit
	global settings_mode
	if pressed:
		if settings_mode:
			settings_mode = False
		else:
			exit = True

def input_left(pressed):
	global settings_mode
	global settings_size
	brightness = rgb.getbrightness() - 2
	if pressed:
		if settings_mode:
			settings_size = (settings_size + 1) % 3
		else:
			if brightness > 2:
				rgb.setbrightness(brightness)

def input_right(pressed):
	global settings_mode
	global settings_pos
	brightness = rgb.getbrightness() + 2
	if pressed:
		if settings_mode:
			settings_pos = (settings_pos + 1) % 3
		else:
			if brightness < 30:
				rgb.setbrightness(brightness)

def input_up(pressed):
	global settings_mode
	global settings_background
	global rainbow_brightness
	if pressed:
		if settings_mode:
			settings_background = (settings_background + 1) % 3
		else:
			set_rainbow(rainbow_brightness + 1)

def input_down(pressed):
	global settings_mode
	global settings_foreground
	global rainbow_brightness
	if pressed:
		if settings_mode:
			settings_foreground = (settings_foreground + 1) % 3
		else:
			set_rainbow(rainbow_brightness - 1)

def get_digit(digit):
	global settings_size
	size = settings_size
	if size == 0:
		tpl = [[[0, 1, 0], [1, 1, 1], [1, 0, 1], [0, 1, 0]],
			   [[1, 1, 0], [0, 1, 0], [0, 1, 0], [1, 1, 1]],
			   [[1, 1, 0], [0, 0, 1], [0, 1, 0], [1, 1, 1]],
			   [[1, 1, 0], [0, 1, 1], [0, 0, 1], [1, 1, 0]],
			   [[1, 0, 1], [1, 1, 1], [0, 0, 1], [0, 0, 1]],
			   [[1, 1, 1], [1, 1, 0], [0, 0, 1], [0, 1, 0]],
			   [[0, 1, 1], [1, 0, 0], [1, 1, 1], [1, 1, 0]],
			   [[1, 1, 1], [0, 0, 1], [0, 1, 0], [1, 0, 0]],
			   [[1, 1, 1], [1, 1, 1], [1, 0, 1], [1, 1, 1]],
			   [[0, 1, 1], [1, 1, 1], [0, 0, 1], [1, 1, 0]]]
	if size == 1:
		tpl = [[[1, 1, 1], [1, 0, 1], [1, 0, 1], [1, 0, 1], [1, 1, 1]],
			   [[0, 1, 0], [1, 1, 0], [0, 1, 0], [0, 1, 0], [1, 1, 1]],
			   [[1, 1, 1], [0, 0, 1], [1, 1, 1], [1, 0, 0], [1, 1, 1]],
			   [[1, 1, 1], [0, 0, 1], [1, 1, 1], [0, 0, 1], [1, 1, 1]],
			   [[1, 0, 1], [1, 0, 1], [1, 1, 1], [0, 0, 1], [0, 0, 1]],
			   [[1, 1, 1], [1, 0, 0], [1, 1, 1], [0, 0, 1], [1, 1, 1]],
			   [[1, 1, 1], [1, 0, 0], [1, 1, 1], [1, 0, 1], [1, 1, 1]],
			   [[1, 1, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1]],
			   [[1, 1, 1], [1, 0, 1], [1, 1, 1], [1, 0, 1], [1, 1, 1]],
			   [[1, 1, 1], [1, 0, 1], [1, 1, 1], [0, 0, 1], [1, 1, 1]]]
	if size == 2:
		tpl = [[[0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
			   [[0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 1, 1, 1]],
			   [[0, 1, 1, 0], [1, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0], [1, 1, 1, 1]],
			   [[1, 1, 1, 0], [0, 0, 0, 1], [0, 1, 1, 0], [0, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
			   [[1, 0, 1, 0], [1, 0, 1, 0], [1, 1, 1, 1], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]],
			   [[1, 1, 1, 1], [1, 0, 0, 0], [1, 1, 1, 0], [0, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
			   [[0, 1, 1, 1], [1, 0, 0, 0], [1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
			   [[1, 1, 1, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [0, 1, 0, 0]],
			   [[0, 1, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]],
			   [[0, 1, 1, 0], [1, 0, 0, 1], [0, 1, 1, 1], [0, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]]
	return tpl[digit]

def digit_size():
	digit = get_digit(0)
	return (len(digit[0]), len(digit))

def render_digit(pixels, digit, tx, ty, color):
	tpl = get_digit(digit)
	for y in range(len(tpl)):
		for x in range(len(tpl[y])):
			if tpl[y][x] == 1:
				if color < 0:
					pixels[x+tx+32*(y+ty)] = 0xffffff00-pixels[x+tx+32*(y+ty)]
				else:
					pixels[x+tx+32*(y+ty)] = color

def normalize(x, y, width, height):
	if x < 0:
		width += x
		x = 0
	if y < 0:
		height += y
		y = 0
	if (x + width) > 32:
		width = 32 - x
	if (y + height) > 8:
		height = 8 - y
	return (x, y, width, height)

def dim_area_by_half(pixels, tx, ty, width, height):
	(tx, ty, width, height) = normalize(tx, ty, width, height)
	for y in range(height):
		for x in range(width):
			pixels[tx+x + 32 * (ty+y)] = (pixels[tx+x + 32 * (ty+y)] & 0xfefefe00) >> 1

def dim_area_by_quarter(pixels, tx, ty, width, height):
	(tx, ty, width, height) = normalize(tx, ty, width, height)
	for y in range(height):
		for x in range(width):
			pixels[tx+x + 32 * (ty+y)] = (pixels[tx+x + 32 * (ty+y)] & 0xfcfcfc00) >> 2

def dim_area(pixels, tx, ty, width, height, factor):
	(tx, ty, width, height) = normalize(tx, ty, width, height)
	for y in range(height):
		for x in range(width):
			pixel = pixels[tx+x + 32 * (ty+y)]
			r = int(((pixel >> 24) & 0xff) * factor)
			g = int(((pixel >> 16) & 0xff) * factor)
			b = int(((pixel >> 8) & 0xff) * factor)
			pixels[tx+x + 32 * (ty+y)] = (r << 24) | (g << 16) | (b << 8)

def set_area(pixels, tx, ty, width, height, color):
	(tx, ty, width, height) = normalize(tx, ty, width, height)
	for y in range(height):
		for x in range(width):
			pixels[tx+x + 32 * (ty+y)] = color

def render_time(pixels):
	global settings_foreground
	global settings_background
	global settings_pos
	
	digit_width, digit_height = digit_size()
	width = 4*digit_width + 5
	height = digit_height
	
	pos = settings_pos
	if pos == 0:
		top = 4 - int(height / 2)
		left = 16 - int(width / 2)
	if pos == 1:
		top = 0
		left = 0
	if pos == 2:
		top = 0
		left = 32 - width
	
	foreground = settings_foreground
	if foreground == 0:
		color = 0xffffff00
	if foreground == 1:
		color = 0
	if foreground == 2:
		color = -1
	
	background = settings_background
	if background == 1:
		dim_area_by_quarter(pixels, left, top, width, height)
		dim_area_by_half(pixels, left-1, top-1, width+2, 1)
		dim_area_by_half(pixels, left-1, top+height, width+2, 1)
		dim_area_by_half(pixels, left-1, top, 1, height)
		dim_area_by_half(pixels, left+width, top, 1, height)
	if background == 2:
		set_area(pixels, left-1, top-1, width+2, height+2, 0)
	
	th = time.strftime("0%H")
	th0 = int(th[len(th)-2])
	th1 = int(th[len(th)-1])
	tm = time.strftime("0%M")
	tm0 = int(tm[len(tm)-2])
	tm1 = int(tm[len(tm)-1])
	render_digit(pixels, th0, left, top, color)
	left = left + digit_width + 1
	render_digit(pixels, th1, left, top, color)
	left = left + digit_width + 1
	pixels[left+(top+1)*32] = color
	pixels[left+(top+3)*32] = color
	left = left + 2
	render_digit(pixels, tm0, left, top, color)
	left = left + digit_width + 1
	render_digit(pixels, tm1, left, top, color)

def set_rainbow(brightness):
	global plainbow
	global rainbow
	global rainbow_brightness
	if brightness >= 2 and brightness <= 16:
		rainbow_brightness = brightness
	rainbow = plainbow[:]
	for i in range(len(rainbow)):
		r = int(((rainbow[i] >> 24) & 0xff) * (rainbow_brightness / 16))
		g = int(((rainbow[i] >> 16) & 0xff) * (rainbow_brightness / 16))
		b = int(((rainbow[i] >> 8) & 0xff) * (rainbow_brightness / 16))
		rainbow[i] = (r << 24) | (g << 16) | (b << 8)

buttons.register(defines.BTN_UP, input_up)
buttons.register(defines.BTN_DOWN, input_down)
buttons.register(defines.BTN_LEFT, input_left)
buttons.register(defines.BTN_RIGHT, input_right)
buttons.register(defines.BTN_A, input_a)
buttons.register(defines.BTN_B, input_b)

rgb.framerate(30)
rgb.disablecomp()

plainbow = [0xff000000+0x00100000*x for x in range(16)]
plainbow.extend([0xffff0000-0x10000000*x for x in range(16)])
plainbow.extend([0x00ff0000+0x00001000*x for x in range(16)])
plainbow.extend([0x00ffff00-0x00100000*x for x in range(16)])
plainbow.extend([0x0000ff00+0x10000000*x for x in range(16)])
plainbow.extend([0xff00ff00-0x00001000*x for x in range(16)])

rainbow_brightness = 16
set_rainbow(rainbow_brightness)

it = 0
exit = False
while not exit:
	pixels = []
	for i in range(8):
		pixels.extend([rainbow[(x+it+2*i) % len(rainbow)] for x in range(32)])
	if settings_data == 1:
		render_time(pixels)
	if settings_mode:
		for y in range(8):
			pixels[32*y] = 0xffffff00 * (it % 2)
	rgb.frame(pixels)
	it = it + 1
	time.sleep(0.01)
system.reboot()