/*
 * productionMode.cpp
 *
 *  Created on: Apr 05, 2019
 *      Author: wn
 */



#include "defines.h"


#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <mqttHandling.h>


#ifdef WS2811
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER
#include <FastLED.h>
#endif

#ifdef PL9823
#include <Adafruit_NeoPixel.h>
#endif


#include "configuration.h"


#ifdef WS2811
CRGB leds[NUM_OF_LEDs];
#endif

#ifdef PL9823
typedef struct {
	uint8_t r;
	uint8_t g;
	uint8_t b;
} CRGB;


Adafruit_NeoPixel pixels(NUM_OF_LEDs, PIXEL_PIN, NEO_RGB + NEO_KHZ400);
#endif

bool show = false;



static CRGB evaluationColorWord(char* cmd) {
	uint8_t red = 0, green = 0, blue = 0;
	if ((! strcmp(cmd, "on")) || (! strcmp(cmd, "white"))) {
		red = 255;
		green = 255;
		blue = 255;
	} else if (! strcmp(cmd, "off")) {
		red = 0;
		green = 0;
		blue = 0;
	} else if (! strcmp(cmd, "warmwhite")) {
		red = 0;
		green = 0;
		blue = 0;
	} else if (! strcmp(cmd, "red")) {
		red = 255;
		green = 0;
		blue = 0;
	} else if (! strcmp(cmd, "green")) {
		red = 0;
		green = 255;
		blue = 0;
	} else if (! strcmp(cmd, "blue")) {
		red = 0;
		green = 0;
		blue = 255;
	} else if (! strcmp(cmd, "purple")) {
		red = 255;
		green = 0;
		blue = 255;
	} else if (! strcmp(cmd, "yellow")) {
		red = 255;
		green = 255;
		blue = 0;
	}

	CRGB res;
	res.r = red;
	res.g = green;
	res.b = blue;
	return res;
}



void subscribeApplication() {
	mqttClient.subscribe(configBlock.mqttTopicColorCommand);
	mqttClient.subscribe(configBlock.mqttTopicCommand);
}



static void setColor(int8_t ledNumber, uint8_t red, uint8_t green, uint8_t blue) {
	if (ledNumber == -1) {
		for (uint8_t i = 0; i < NUM_OF_LEDs; i++) {
#ifdef WS2811
			leds[i].r = red;
			leds[i].g = green;
			leds[i].b = blue;
#endif
#ifdef PL9823
			pixels.setPixelColor(i, pixels.Color(red, green, blue));
#endif
		}
		show = true;
	} else {
		if (ledNumber >= 0 && ledNumber < NUM_OF_LEDs) {

#ifdef WS2811
			leds[ledNumber].r = red;
			leds[ledNumber].g = green;
			leds[ledNumber].b = blue;
#endif
#ifdef PL9823
			pixels.setPixelColor(ledNumber, pixels.Color(red, green, blue));
#endif
			show = true;
		}
	}
}



void callbackApplication(char *topic, uint8_t tokenCnt, char **tokens) {
	if (! strcmp(topic, configBlock.mqttTopicCommand)) {
		int32_t n, b;
		CRGB pseudoColors;
		switch (tokenCnt) {
		case 1:
			// set brightness
			b = strtol(tokens[0], NULL, 10);
			setColor(-1, b, b, b);
			break;
		case 2:
			// set brightness for one LED
			n = strtol(tokens[0], NULL, 10);
			b = strtol(tokens[1], NULL, 10);
			setColor(n, b, b, b);
			break;
		}
	} else if (! strcmp(topic, configBlock.mqttTopicColorCommand)) {
		int32_t n, red, green, blue;
		CRGB colors;
		switch (tokenCnt) {
		case 1:
			// on, off, color word for all LEDs
			colors = evaluationColorWord(tokens[0]);
			setColor(-1, colors.r, colors.g, colors.b);
			break;
		case 2:
			// token0 = LED number, token1 = color
			n = strtol(tokens[0], NULL, 10);
			colors = evaluationColorWord(tokens[1]);
			setColor(n, colors.r, colors.g, colors.b);
			break;
		case 3:
			// token0 = red, token1 = green, token2 = blue
			red = strtol(tokens[0], NULL, 10);
			green = strtol(tokens[1], NULL, 10);
			blue = strtol(tokens[2], NULL, 10);
			setColor(-1, red, green, blue);
			break;
		case 4:
			// token0 = LED number, token1 = red, token2 = green, token3 = blue
			n = strtol(tokens[0], NULL, 10);
			red = strtol(tokens[1], NULL, 10);
			green = strtol(tokens[2], NULL, 10);
			blue = strtol(tokens[3], NULL, 10);
			setColor(n, red, green, blue);
			break;
		}
	}
}


void setupApplication() {
	mqttSetup();

#ifdef WS2811
	FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, NUM_OF_LEDs);
#endif
#ifdef PL9823
	pixels.begin();

	for (uint8_t i = 0; i < NUM_OF_LEDs; i++) {
		pixels.setPixelColor(i, pixels.Color(0,0,0));
	}
	pixels.show();
#endif
}


void loopApplication() {
	mqttLoop();



	if (show) {
		show = false;
#ifdef WS2811
		FastLED.show();
#endif
#ifdef PL9823
		pixels.show();
#endif
	}
}