#define LEDCONTROL_C

#include "LEDControl.h"
#include <avr/io.h>

#define SPI_ENABLE  0x50
#define SPI_DISABLE 0x10

// SPI stuff
#define HI_MASK 0xE0
#define LO_MASK 0x00

// GREEN, RED, BLUE
#define NUMBER_OF_LEDS 256
uint8_t led_intensities[NUMBER_OF_LEDS]; // 1 byte per led, 256 LEDS
uint8_t led_modes[NUMBER_OF_LEDS]; // 1 byte per led, 256 LEDS


void LEDUpdateOutputs(void)
{
	static unsigned char next_spi_char = 0;
	static unsigned char current_led_char = 0;
	static unsigned char current_spi_array_posn = 0;
	static unsigned char current_spi_bit_posn = 0;
	unsigned int counter = 0;

	// Set to the starting state
	current_spi_array_posn = 0;
	current_spi_bit_posn = 0;
	current_led_char = led_intensities[current_spi_array_posn];
	
	// Data clocked out MSB first...
	if(0x80 == (current_led_char & 0x80))
	{
		next_spi_char = HI_MASK;
	} else
	{
		next_spi_char = LO_MASK;
	}
	current_spi_bit_posn = 0;

	counter=0;
	while (counter++ < (NUMBER_OF_LEDS*8))
	{
		SPCR = SPI_ENABLE;
		SPDR = next_spi_char;
		current_spi_bit_posn++;
		current_spi_bit_posn &= 0x07;
		SPCR = SPI_DISABLE;
		if(0 == current_spi_bit_posn)
		{
			current_led_char = led_intensities[++current_spi_array_posn];
		}
		if(0x80 == ((current_led_char<<current_spi_bit_posn) & 0x80))
		{
			next_spi_char = HI_MASK;
		} else
		{
			next_spi_char = LO_MASK;
		}
	}
}


void LEDSetup(void)
{
	DDRD = (1<<7); // pinMode(6, OUTPUT);
	DDRB = (1<<2); // pinMode(MOSI, OUTPUT);
	SPCR = SPI_ENABLE;
	SPDR = 0;
	SPCR = SPI_DISABLE;
	PORTD = (1<<7);

	for (uint16_t counter = 0; counter<NUMBER_OF_LEDS; counter++)
	{
		led_intensities[counter] = 0;
		led_modes[counter] = 0x00;
	}
	led_intensities[0] = 255;
}

void processLEDCommands(uint8_t *dataBuffer, uint16_t dataLength, uint8_t *debug)
{
	uint8_t *storage_array;
	uint8_t start_position;
	// Check this is a full message to process

	if(36==dataLength)
	{
		if(0==dataBuffer[0])
		{
			if(32==dataBuffer[3])
			{
				// Modes
				if(2==dataBuffer[1])
				{
					start_position = dataBuffer[2];
					if (start_position < 225)
					{
						for (uint16_t counter = 0; counter<32; counter++)
						{
							led_modes[start_position+counter] = dataBuffer[counter+4];
						}
					}
				}

				// Intensities
				if(3==dataBuffer[1])
				{
					start_position = dataBuffer[2];
					if (start_position < 225)
					{
						for (uint16_t counter = 0; counter<32; counter++)
						{
							led_intensities[start_position+counter] = dataBuffer[counter+4];
						}
					}
				}
			}
		}
	}
}
