//Arduboy Assistant
//	Version 1.1, Aug 29, 2016
//	By Jonathan Holmes (crait)
//
//	Website: http://www.crait.net/
//	Twitter: @crait
//
//Arduboy Assistant is a program that allows you to manage an Arduboy's EEPROM as well as test several
//hardware and software components. You can view raw EEPROM data, back it up through the Arduino IDE's
//serial monitor, restore EEPROM data the same way, and even clear the entirety of the EEPROM data.
//Additionally, you can do a button test, LED test, sound test, serial test, and screen test.
//Sorry about the menu code being a little all over the place!

#include "Arduboy.h"
#include <EEPROM.h>
Arduboy arduboy;
#define BLACK 0
#define WHITE 1
#define OFF HIGH
#define ON LOW
boolean buttonfree = true;
int state = 0;
int choice = 0;
int maxchoices = 0;
boolean led[6] = { OFF, OFF, OFF, OFF, OFF, OFF };
char text[24];
int mv = 0;
int oldmv = 0;
int frames = 1200;
int x = 25;
int y = 25;
int pitch = 200;
int eepromlocation = EEPROM_STORAGE_SPACE_START;
int i = 0;
char lastchar = ' ';
char checkchar = 'a';
char arrow[2];
void setup() {
	arduboy.begin();
	arduboy.setFrameRate(100);
	arduboy.display();
}
void loop() {
	sprintf(arrow, "%c%c", '-', 16);
	arduboy.clear();
	arduboy.setCursor(0, 0);
	switch (state) {
		case 0:
			maxchoices = 0;
			frames -= 1;
			if(frames == 0) {
				state = 2;
			}
			arduboy.setCursor(3, 0);
			arduboy.print(F("Arduboy Assistant 1.1"));
			arduboy.setCursor(19, 12);
			arduboy.print(F("Jonathan Holmes"));
			arduboy.setCursor(46, 24);
			arduboy.print(F("@crait"));
			arduboy.setCursor(3, 36);
			arduboy.print(F("http://www.crait.net/"));
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			if(frames < 300) {
				arduboy.print("Wait for button test...");
			}
			else {
				arduboy.print("(A) Continue");
			}
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				buttonfree = false;
				choice = 0;
				state = 1;
				frames = 0;
			}
			break;
		case 1: //Main Menu
			maxchoices = 8;
			if(choice < 6) {
				arduboy.setCursor(18, 0);
			}
			else {
				arduboy.setCursor(18, -8 * (choice - 5));
			}
			arduboy.print(F("Button Test\n   Character Test\n   EEPROM Manager\n   LED Test\n   Screen Test\n   Sound Test\n   USB Transfer Test\n   About"));
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				state = choice + 2;
				if(choice == 6) {
					state = 13;
				}
				if(choice == 7) {
					state = 14;
				}
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.drawLine(0, 53, 128, 53, BLACK);
			arduboy.setCursor(0, 56);
			arduboy.print("(A) Select");
			break;
		case 2: //Button Test
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print("Button Test\n");
			if (arduboy.pressed(A_BUTTON)) {
				arduboy.print("A Pressed\n");
			}
			if (arduboy.pressed(B_BUTTON)) {
				arduboy.print("B Pressed\n");
			}
			if (arduboy.pressed(UP_BUTTON)) {
				arduboy.print("UP Pressed\n");
			}
			if (arduboy.pressed(LEFT_BUTTON)) {
				arduboy.print("LEFT Pressed\n");
			}
			if (arduboy.pressed(RIGHT_BUTTON)) {
				arduboy.print("RIGHT Pressed\n");
			}
			if (arduboy.pressed(DOWN_BUTTON)) {
				arduboy.print("DOWN Pressed\n");
			}
			break;
		case 3: //Character Test
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			sprintf(text, "Integer:   %d\n", checkchar);
			arduboy.print(text);
			sprintf(text, "Character: %c\n", checkchar);
			arduboy.print(text);
			if (arduboy.pressed(UP_BUTTON) && buttonfree) {
				checkchar += 1;
				buttonfree = false;
			}
			if (arduboy.pressed(DOWN_BUTTON) && buttonfree) {
				checkchar -= 1;
				buttonfree = false;
			}
			if (pitch < 0) {
				pitch = 0;
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 1;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 46, 128, 46, WHITE);
			arduboy.setCursor(0, 48);
			arduboy.print(F("(Up/Down) Scroll\n(B) Back"));
			break;
		case 4: //EEPROM Manager
			maxchoices = 4;
			arduboy.setCursor(0, 0);
			arduboy.print(F("   View EEPROM\n   Back-Up EEPROM\n   Restore EEPROM\n   Clear EEPROM"));
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				buttonfree = false;
				switch (choice) {
					case 0:
						state = 8;
						break;
					case 1:
						state = 9;
						break;
					case 2:
						state = 12;
						break;
					case 3:
						state = 10;
						break;
				}
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 1;
				buttonfree = false;
				choice = 0;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print("(B) Back");
			break;
		case 5: //LED Test
			maxchoices = 5;
			arduboy.setCursor(0, 0);
			sprintf(text, "   Red LED:      %s\n", boolcheck(led[0]));
			arduboy.print(text);
			sprintf(text, "   Green LED:    %s\n", boolcheck(led[1]));
			arduboy.print(text);
			sprintf(text, "   Blue LED:     %s\n", boolcheck(led[2]));
			arduboy.print(text);
			sprintf(text, "   Receive LED:  %s\n", boolcheck(led[3]));
			arduboy.print(text);
			sprintf(text, "   Transmit LED: %s\n", boolcheck(led[4]));
			arduboy.print(text);
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				buttonfree = false;
				led[choice] = !led[choice];
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				buttonfree = false;
				state = 1;
				choice = 0;
			}
			digitalWrite(RED_LED, led[0]);
			digitalWrite(GREEN_LED, led[1]);
			digitalWrite(BLUE_LED, led[2]);
			digitalWrite(RX_LED, led[3]);
			digitalWrite(TX_LED, led[4]);
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print(F("(A) Toggle - (B) Back"));
			break;
		case 6: //Screen Test
			maxchoices = 0;
			if (x < 100) {
				if (y < 6) {
					arduboy.setCursor(x + 5, 0);
				}
				else {
					arduboy.setCursor(x + 5, y - 5);
				}
			}
			else {
				if (y < 6) {
					arduboy.setCursor(x - 58, 0);
				}
				else {
					arduboy.setCursor(x - 58, y - 5);
				}
			}
			sprintf(text, "(%d, %d)", x, y);
			arduboy.print(text);
			arduboy.drawPixel(x, y - 1, WHITE);
			arduboy.drawPixel(x - 1, y, WHITE);
			arduboy.drawPixel(x + 0, y, WHITE);
			arduboy.drawPixel(x + 1, y, WHITE);
			arduboy.drawPixel(x, y + 1, WHITE);
			if (arduboy.pressed(LEFT_BUTTON) && buttonfree) {
				buttonfree = false;
				x -= 1;
			}
			if (arduboy.pressed(RIGHT_BUTTON) && buttonfree) {
				buttonfree = false;
				x += 1;
			}
			if (arduboy.pressed(UP_BUTTON) && buttonfree) {
				buttonfree = false;
				y -= 1;
			}
			if (arduboy.pressed(DOWN_BUTTON) && buttonfree) {
				buttonfree = false;
				y += 1;
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				buttonfree = false;
				state = 1;
				choice = 0;
			}
			break;
		case 7: //Sound Test
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			sprintf(text, "Frequency: %d\n", pitch);
			arduboy.print(text);
			if (arduboy.pressed(UP_BUTTON)) {
				pitch += 1;
				buttonfree = false;
			}
			if (arduboy.pressed(DOWN_BUTTON)) {
				pitch -= 1;
				buttonfree = false;
			}
			if (pitch < 0) {
				pitch = 0;
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 1;
				choice = 0;
				buttonfree = false;
			}
			if (arduboy.pressed(A_BUTTON)) {
				arduboy.tunes.tone(pitch, 40);
			}
			arduboy.drawLine(0, 46, 128, 46, WHITE);
			arduboy.setCursor(0, 48);
			arduboy.print(F("(Up/Down) Frequency\n(A) Play - (B) Back"));
			break;
		case 8: //View EEPROM
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			sprintf(text, "Location: %d\n", eepromlocation);
			arduboy.print(text);
			sprintf(text, "Data: %c%c%c%c%c%c%c%c",
				(EEPROM.read(eepromlocation) & 0x80) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x40) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x20) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x10) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x08) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x04) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x02) ? '1' : '0',
				(EEPROM.read(eepromlocation) & 0x01) ? '1' : '0'
			);
			arduboy.print(text);
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 4;
				choice = 0;
				buttonfree = false;
			}
			if (arduboy.pressed(UP_BUTTON) && buttonfree) {
				eepromlocation += 1;
				buttonfree = false;
			}
			if (arduboy.pressed(DOWN_BUTTON) && buttonfree) {
				buttonfree = false;
				eepromlocation -= 1;
			}
			if (eepromlocation < 0) {
				eepromlocation = 1023;
			}
			if (eepromlocation >= 1024) {
				eepromlocation = 0;
			}
			arduboy.drawLine(0, 46, 128, 46, WHITE);
			arduboy.setCursor(0, 48);
			arduboy.print("(Up/Down) Scroll\n(B) Back");
			break;
		case 9: //Back-up EEPROM
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print(F("Connect your Arduboy\nto your PC and run\nthe Arduino IDE.\n"));
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 4;
				choice = 0;
				buttonfree = false;
			}
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				arduboy.clear();
				arduboy.setCursor(0, 24);
				arduboy.print("Sending...");
				arduboy.display();
				delay(500);
				for (i = EEPROM_STORAGE_SPACE_START; i < 1024; i++) {
					Serial.println((char)EEPROM.read(i));
				}
				state = 11;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print(F("(A) Yes - (B) NO"));
			break;
		case 10: //Clear EEPROM
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print(F("Your EEPROM will be\nerased for good. Are\nyou sure you want to\ndo this?"));
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				arduboy.clear();
				arduboy.setCursor(0, 24);
				arduboy.print("Clearing...");
				arduboy.display();
				delay(500);
				for (i = EEPROM_STORAGE_SPACE_START; i < 1024; i++) {
					EEPROM.update(i, 0x00);
				}
				state = 11;
				choice = 0;
				buttonfree = false;
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 4;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print(F("(A) Yes - (B) NO"));
			break;
		case 11: //Done
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print("Done!");
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				state = 1;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print("(A) Continue");
			break;
		case 12: //Receive EEPROM
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print(F("Your EEPROM will be\nerased for good when\nrestoring EEPROM from\nthe Arduino IDE. Are\nyou sure?\n"));
			if (arduboy.pressed(A_BUTTON) && buttonfree) {
				arduboy.clear();
				arduboy.setCursor(0, 24);
				arduboy.print(F("Receiving..."));
				arduboy.display();
				delay(500);
				i = EEPROM_STORAGE_SPACE_START;
				while (Serial.available()) {
					char inChar = (char)Serial.read();
					if (inChar == 'n') {
					}
					else {
						if(i < 1024) {
							EEPROM.update(i, inChar);
							i += 1;
						}
					}
				}
				state = 11;
				choice = 0;
				buttonfree = false;
			}
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 4;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print(F("(A) Yes - (B) NO"));
			break;
		case 13: //Transfer Test
			maxchoices = 0;
			arduboy.setCursor(0, 0);
			arduboy.print(F("Connect your Arduboy\nto your computer and\nrun the Arduino IDE's\nserial monitor.\n\nChar Received: "));
			if(Serial.available()) {
				char inChar = (char)Serial.read();
				Serial.println(inChar);
				if(inChar != lastchar) {
					lastchar = inChar;
				}
			}
			arduboy.print(lastchar);
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 1;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print("(B) Back");
			break;
		case 14: //About
			maxchoices = 0;
			arduboy.setCursor(3, 0);
			arduboy.print(F("Arduboy Assistant 1.1"));
			arduboy.setCursor(19, 12);
			arduboy.print(F("Jonathan Holmes"));
			arduboy.setCursor(46, 24);
			arduboy.print(F("@crait"));
			arduboy.setCursor(3, 36);
			arduboy.print(F("http://www.crait.net/"));
			
			if (arduboy.pressed(B_BUTTON) && buttonfree) {
				state = 1;
				choice = 0;
				buttonfree = false;
			}
			arduboy.drawLine(0, 54, 128, 54, WHITE);
			arduboy.setCursor(0, 56);
			arduboy.print("(B) Back");
			break;
	}
	if (maxchoices != 0) {
		if(choice < 6) {
			arduboy.setCursor(0, choice * 8);
		} else {
			arduboy.setCursor(0, 40);
		}
		arduboy.print(arrow);
		if (arduboy.pressed(UP_BUTTON) && buttonfree) {
			choice -= 1;
			buttonfree = false;
		}
		if (arduboy.pressed(DOWN_BUTTON) && buttonfree) {
			choice += 1;
			buttonfree = false;
		}
		if (choice >= maxchoices) {
			choice = 0;
		}
		if (choice < 0) {
			choice = maxchoices - 1;
		}
	}
	if (buttonfree == false) {
		if (!arduboy.pressed(UP_BUTTON) && !arduboy.pressed(DOWN_BUTTON) && !arduboy.pressed(LEFT_BUTTON) && !arduboy.pressed(RIGHT_BUTTON) && !arduboy.pressed(A_BUTTON) && !arduboy.pressed(B_BUTTON)) {
			buttonfree = true;
		}
	}
	arduboy.display();
}
const char * boolcheck(boolean booltocheck) {
	return booltocheck ? "Off" : "On";
}
