#include <Arduino.h>
#include <LedControl.h>
#include <Encoder.h>

/*
 pin 0 is connected to the DataIn
 pin 2 is connected to the CLK
 pin 1 is connected to LOAD
 We have only a single MAX72XX.
 */
#if BUILD_ENV_NAME == uno
	LedControl lc = LedControl(11, 13, 10, 1);
#else
	LedControl lc = LedControl(0, 2, 1, 1)
#endif

Encoder myEnc(3, 4);
int encVal = 0;
int shift = 0;

int seconds = 0;

void print_time(int seconds);

void value_select(void);

void start_count(int seconds);

void setup() {
	lc.shutdown(0,false);
	/* Set the brightness to a medium values */
	lc.setIntensity(0,8);
	/* and clear the display */
	lc.clearDisplay(0);
	lc.setDigit(0, 0, 0, false);
	lc.setDigit(0, 1, 0, false);

	myEnc.write(0);

	#if BUILD_ENV_NAME == uno
		Serial.begin(115200);
		while(!Serial.available());
		Serial.print("BUILD_ENV_NAME : ");
		Serial.println(BUILD_ENV_NAME);
	#endif
}

void loop() {
	print_time(seconds);
	while (analogRead(0) > 950) {
		value_select();
	}
	start_count(seconds);
}

void value_select(void) {
	int newEncVal = myEnc.read();
	if (newEncVal != encVal) {
		int increment = 0;
		shift += newEncVal - encVal;
		encVal = newEncVal;

		if (-4 >= shift || shift >= 4) {
			int sign = shift >> 2;

			if (seconds < 60) {
				increment = 1 * sign;

				if (seconds + increment < 0) {
					seconds = 5940;
					increment = 0;
				} else if (seconds + increment >= 60) {
					seconds = 60;
					increment = 0;
				}
			} else if (seconds < 600) {
				increment = sign * 10;

				if (seconds + increment < 60) {
					seconds = 59;
					increment = 0;
				} else if (seconds + increment > 590) {
					seconds = 600;
					increment = 0;
				}
			} else {
				increment = sign * 60;

				if (seconds + increment < 600) {
					seconds = 590;
					increment = 0;
				} else if (seconds + increment > 5940) {
					seconds = 0;
					increment = 0;
				}
			}

			seconds += increment;

			print_time(seconds);

			shift = 0;

			#if BUILD_ENV_NAME == uno
				Serial.print("Seconds : ");
				Serial.println(seconds, DEC);
			#endif
		}
	}
}

void start_count(int secondsToWait) {
	unsigned long millisToWait = secondsToWait * 1000L;
	unsigned long millisElapsed = 0L;
	unsigned long millisAtStart = millis();

	do {
		millisElapsed = millis() - millisAtStart;
		print_time(secondsToWait - millisElapsed / 1000);
		delay(500);
		#if BUILD_ENV_NAME == uno
			Serial.print("millisElapsed : ");
			Serial.print(millisElapsed, DEC);
			Serial.print(" / ");
			Serial.print(millisToWait, DEC);
			Serial.print(" (");
			Serial.print(secondsToWait * 1000, DEC);
			Serial.println(") ");
			Serial.print("Remaining time : ");
			Serial.print(secondsToWait - millisElapsed / 1000, DEC);
			Serial.println(" s");
		#endif
	} while (millisElapsed < millisToWait);

	while (analogRead(0) > 950) {
		lc.setChar(0, 0, '-', false);
		lc.setChar(0, 1, '-', false);
		delay(300);
		lc.setChar(0, 0, ' ', false);
		lc.setChar(0, 1, ' ', false);
		delay(300);
	}

	while (analogRead(0) < 950) {
	}
}

void print_time(int seconds) {
	if (seconds < 60) {
		lc.setDigit(0, 0, seconds % 10, false);
		lc.setDigit(0, 1, seconds / 10, false);
	} else if (seconds < 600) {
		lc.setDigit(0, 0, (seconds / 10) % 6, false);
		lc.setDigit(0, 1, seconds / 60, true);
	} else {
		int minutes = seconds / 60;
		lc.setDigit(0, 0, minutes % 10, true);
		lc.setDigit(0, 1, minutes / 10, false);
	}
}
