/*
  A really simple analog clock
 Tested and worked with:
 Teensy3,Teensy3.1,Arduino UNO,Arduino YUN,Arduino Leonardo,Stellaris
 Works with Arduino 1.0.6 IDE, Arduino 1.5.8 IDE, Energia 0013 IDE
  ---------------> http://www.buydisplay.com
*/

#include <Arduino.h>
#include <SPI.h>
#include <FishinoRA8875SPI.h>

// Chip select pin -- adapt to your connection
#define RA8875_CS 2

#define tft FishinoRA8875SPI

uint16_t ccenterx,ccentery;//center x,y of the clock
const uint16_t cradius = 110;//radius of the clock
const float scosConst = 0.0174532925;
float sx = 0, sy = 1, mx = 1, my = 0, hx = -1, hy = 0;
float sdeg=0, mdeg=0, hdeg=0;
uint16_t osx,osy,omx,omy,ohx,ohy;
uint16_t x0 = 0, x1 = 0, yy0 = 0, yy1 = 0;
uint32_t targetTime = 0;// for next 1 second timeout
uint8_t hh,mm,ss;  //containers for current time


void drawClockFace()
{
	tft.fillCircle(ccenterx, ccentery, cradius, GFX_BLUE);
	tft.fillCircle(ccenterx, ccentery, cradius-4, GFX_BLACK);
	// Draw 12 lines
	for (int i = 0; i<360; i+= 30)
	{
		sx = cos((i-90)*scosConst);
		sy = sin((i-90)*scosConst);
		x0 = sx*(cradius-4)+ccenterx;
		yy0 = sy*(cradius-4)+ccentery;
		x1 = sx*(cradius-11)+ccenterx;
		yy1 = sy*(cradius-11)+ccentery;
		tft.drawLine(x0, yy0, x1, yy1, GFX_BLUE);
	}
}

static uint8_t conv2d(const char* p)
{
	uint8_t v = 0;
	if ('0' <= *p && *p <= '9')
		v = *p - '0';
	return 10 * v + *++p - '0';
}

void setup(void)
{
	tft.begin(RA8875_CS);

	tft.setTextColor(GFX_WHITE, GFX_BLACK);
	ccenterx = tft.width()/2;
	ccentery = tft.height()/2;
	osx = ccenterx;
	osy = ccentery;
	omx = ccenterx;
	omy = ccentery;
	ohx = ccenterx;
	ohy = ccentery;
	drawClockFace();// Draw clock face
	//get current time from compiler
	hh = conv2d(__TIME__);
	mm = conv2d(__TIME__+3);
	ss = conv2d(__TIME__+6);
	targetTime = millis() + 1000;
}

void drawClockHands(uint8_t h,uint8_t m,uint8_t s)
{
	// Pre-compute hand degrees, x & y coords for a fast screen update
	sdeg = s * 6;                  // 0-59 -> 0-354
	mdeg = m * 6 + sdeg * 0.01666667;  // 0-59 -> 0-360 - includes seconds
	hdeg = h * 30 + mdeg * 0.0833333;  // 0-11 -> 0-360 - includes minutes and seconds
	hx = cos((hdeg-90)*scosConst);
	hy = sin((hdeg-90)*scosConst);
	mx = cos((mdeg-90)*scosConst);
	my = sin((mdeg-90)*scosConst);
	sx = cos((sdeg-90)*scosConst);
	sy = sin((sdeg-90)*scosConst);

	// Erase just old hand positions
	tft.drawLine(ohx, ohy, ccenterx+1, ccentery+1, GFX_BLACK);
	tft.drawLine(omx, omy, ccenterx+1, ccentery+1, GFX_BLACK);
	tft.drawLine(osx, osy, ccenterx+1, ccentery+1, GFX_BLACK);
	// Draw new hand positions
	tft.drawLine(hx*(cradius-28)+ccenterx+1, hy*(cradius-28)+ccentery+1, ccenterx+1, ccentery+1, GFX_WHITE);
	tft.drawLine(mx*(cradius-17)+ccenterx+1, my*(cradius-17)+ccentery+1, ccenterx+1, ccentery+1, GFX_WHITE);
	tft.drawLine(sx*(cradius-14)+ccenterx+1, sy*(cradius-14)+ccentery+1, ccenterx+1, ccentery+1, GFX_RED);
	tft.fillCircle(ccenterx+1, ccentery+1, 3, GFX_RED);

	// Update old x&y coords
	osx = sx*(cradius-14)+ccenterx+1;
	osy = sy*(cradius-14)+ccentery+1;
	omx = mx*(cradius-17)+ccenterx+1;
	omy = my*(cradius-17)+ccentery+1;
	ohx = hx*(cradius-28)+ccenterx+1;
	ohy = hy*(cradius-28)+ccentery+1;
}

void drawPrintTime(uint16_t x,uint16_t y, uint8_t h,uint8_t m,uint8_t s)
{
	tft.changeMode(TEXT);
	tft.setCursor(0, 0);
	tft.print("www.buydisplay.com");
	tft.setCursor(x, y);
	tft.print(__DATE__);
	tft.setCursor(x, y-13);
	if (hh > 12)
	{
		if (hh < 22)
			tft.print('0');
		tft.print(hh-12);
	}
	else
	{
		if (hh < 10)
			tft.print('0');
		tft.print(hh);
	}
	tft.print(':');
	if (mm < 10)
		tft.print('0');
	tft.print(mm);
	tft.print(':');
	if (ss < 10)
		tft.print('0');
	tft.print(ss);
	if (hh > 12)
	{
		tft.print(" pm");
	}
	else
	{
		tft.print(" am");
	}
	tft.changeMode(GRAPHIC);
}

void loop()
{
	if (targetTime < millis())
	{
		targetTime = millis()+1000;
		ss++;
		if (ss == 60)
		{
			ss = 0;
			mm++;
			if (mm > 59)
			{
				mm = 0;
				hh++;
				if (hh > 23)
					hh = 0;
			}
		}
		drawClockHands(hh,mm,ss);
		drawPrintTime(34,151,hh,mm,ss);
	}
}



