/*
 * AtTiny_alarm_clock.c
 *
 * Created: 16.07.2018 13:55:13
 * Author : dozed
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "lcd4.h"

#define butt1 0
#define butt2 1
#define butt3 2

typedef enum {CLOCK_INIT = 0, CLOCK_IDLE, CLOCK_ALARM, CLOCK_STOPWATCH_RUNNING, CLOCK_STOPWATCH_STOPPED, CLOCK_STOPWATCH_NOT_SET, CLOCK_USER_INPUT, CLOCK_SET_TIME} clock_state_e;

clock_state_e clock_old_state;
clock_state_e clock_state = CLOCK_INIT;
clock_state_e clock_new_state = CLOCK_INIT;

uint8_t t1[] = {' ','H','a','l','l','o','_','_','_','_','_','_','_','_','_','_','_'};
int counter = 0;

uint8_t flags;

int clock_state_changed = 0;
int update_display = 1;

ISR (TIMER1_OVF_vect)    // Timer1 ISR
{
	//counter++;
	TCNT1 = 63974;
}

int main(void)
{
	DDRD = 0x00;
	
	TCNT1 = 63974;   // for 1 sec at 16 MHz

	TCCR1A = 0x00;
	TCCR1B = (1<<CS10) | (1<<CS12);;  // Timer mode with 1024 prescaler
	TIMSK = (1 << TOIE1) ;   // Enable timer1 overflow interrupt(TOIE1)
	sei(); // Enable global interrupts by setting global interrupt enable bit in SREG

    /* Replace with your application code */
    while (1) 
    {
		if(clock_state != clock_new_state){
			clock_state = clock_new_state;
			clock_state_changed = 1;
			update_display = 1;
		}
		else {
			clock_state_changed = 0;
		}
		
		
		switch(clock_state){
			case CLOCK_INIT:
				//do some init stuff...
				lcd_init();
				lcd_5ms();
				lcd_instruct(lcd_DISPLAY_CLEAR);
				//INIT done -> change to IDLE
				clock_new_state = CLOCK_IDLE;
				
				break;

			case CLOCK_IDLE:
				//IDLE MODE

				//print the IDLE Screen

				if(update_display){
					lcd_5ms();
					lcd_write_text(0,0,(uint8_t []){'_','_','_','_','_','_','t','i','m','e','_','_','_','_','_','_'});
					lcd_5ms();
					lcd_write_text(1,0,(uint8_t []){' ',' ',' ',' ',' ',' ','t','i','m','e',' ',' ',' ',' ',' ',' '});
						update_display = 0;
				}

				if(button_clicked(butt1)){
					clock_new_state = CLOCK_ALARM;
				}
				else if(button_clicked(butt2)){
					counter += 2;
				}
				else if(button_clicked(butt3)){
					counter += 3;
				}

				
				t1[0] = counter + 48;
				
			break;
			
			case CLOCK_ALARM:
				//ALARM setup Mode
				//print the ALARM screen
				if(update_display){
					lcd_write_text(0,0,(uint8_t []){' ',' ','[','a','l','a','r','m',' ','t','i','m','e',']',' ',' '});
					lcd_write_text(1,0,(uint8_t []){' ',' ',' ',' ',' ','a','l','a','r','m',' ','>',' ',' ',' ',' '});
						update_display = 0;
				}
			break;
		}
    }
}

void lcd_write_text(int row, int col, uint8_t text[])
{
	switch(row){
		case 0:
			row = line1;
			break;
		case 1:
			row = line2;
			break;
	}
	for(int i=0;i<=15;i++){
		if(text[i] != 0x5F){
			lcd_write(row, text[i], 0+i);
		}
		lcd_5ms();
	}
}

int button_clicked(int button)
{
	if(((PIND & 0x03) == button+1) != ((flags & (1<<button))>0)){
		//if the pin is not equal to the stored state -> was pressed or released
		//check is the button has been pressed or released
		if((PIND & 0x03) == button+1){
			//button is high -> pressed
			flags |= (1<<button); //set bit
			return(1);
		}
		else{
			//button is low -> released
			flags &= ~(1<<button); //delete bit
			return(0);
		}
	}
	return(0);
}

