#include <inttypes.h>
#include <stdlib.h> // for NULL

#include "lights.h"

static pattern_t on_pattern [] = {
	{ 1, 0x10 },
	PATTERN_END
};

static pattern_t blink_pattern[] = {
	{ 1, 0x1 },
	{ 0, 0x2 },
	{ 1, 0x1 },
	{ 0, 0x8 },
	{ 1, 0x1 },
	{ 0, 0x8 },
	PATTERN_END
};

static pattern_t slow_pattern[] = {
	{ 1, 0x1 },
	{ 0, 0x1F },
	PATTERN_END
};

static unsigned char light_mode;
static union {
	unsigned char errors;
	struct {
		unsigned char shutdown_in_progress : 1;
		unsigned char pwmled_error : 1;
		unsigned char battery_low : 1;
	};
} e;

void set_error(unsigned char err)
{
	switch(err) {
	case ERR_BATTERY:
		e.battery_low = 1;
		pwmled_set_target(0);
		pattern_reload();
		break;
	case ERR_PWMLED:
		e.pwmled_error = 1;
		break;
	}
}

void init_control()
{
	light_mode = 1;
	e.errors = 0;
	short_press();
}

void long_press_start()
{
	e.shutdown_in_progress = 1;
	pattern_reload();
}

void short_press()
{
	if (e.battery_low)
		return;

	if (++light_mode >= 2*N_PWMLED_MODES)
		light_mode = 0;

	pwmled_set_target(light_mode < N_PWMLED_MODES
		? light_mode
		: light_mode - N_PWMLED_MODES);
	pattern_reload();
}

void long_press()
{
	power_down();
}

pattern_t *pwmled_pattern_select()
{
	if (e.shutdown_in_progress)
		return NULL;

	if (e.battery_low)
		return slow_pattern;

	if (light_mode == 0) {
		return slow_pattern;
	} else if (light_mode < N_PWMLED_MODES) {
		return blink_pattern;
	} else {
		return on_pattern;
	}
}

pattern_t *status_led_pattern_select()
{
	if (e.shutdown_in_progress)
		return on_pattern;

	if (e.pwmled_error)
		return number_pattern(3, 1);

	if (e.battery_low)
		return number_pattern(1, 1);

	return number_pattern(battery_gauge(), 0);
}

#if 0
void brake_on()
{
	braking = 1;
	gpio_set(0, 1);
	led_set_pattern(N_PWMLEDS, status_led_pattern_select());
	led_set_pattern(0, pwmled0_pattern_select());
}

void brake_off()
{
	braking = 0;
	gpio_set(0, 0);
	led_set_pattern(N_PWMLEDS, status_led_pattern_select());
	led_set_pattern(0, pwmled0_pattern_select());
}

#endif
