#include "common.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <avr/sleep.h>


#include "../common/simple_timer.h"

#include "door.h"
#include "power_monitor.h"
#include "status_output.h"

#include "shell/shell.h"

#include "random.h"

#include "cardreader_interface.h"
#include "keystore.h"
#include "log.h"

#define POWER_SWITCH_TIME 200 //2s
#define POWER_SWITCH_DONE 0xFF
#define POWER_SWITCH_BOOTUP 0xFE
volatile uint8_t power_switch_time = POWER_SWITCH_BOOTUP;


volatile uint8_t timer_tick = 0;
void timer_handler(void){
	timer_tick = 1;
}

void tick(void){
	door_tick();
	power_tick();
	status_tick();
	cardreader_tick();
	shell_tick();
	
	if (power_switch_time != 0 && power_switch_time != POWER_SWITCH_DONE && power_switch_time != POWER_SWITCH_BOOTUP){
		power_switch_time--;
	}
}

ISR(PCINT0_vect){
	card_power_request_pin_changed((CARDREADER_POWER_REQUEST_PIN & (1 << CARDREADER_POWER_REQUEST_LINE)) == 0);
}

void sleep(void){
	wdt_disable();
// 	set_sleep_mode(SLEEP_MODE_IDLE);
// 	sleep_mode();
	wdt_enable(WDTO_8S);
}

int main(void){
	uint8_t last_door_status = 0xFF;
	uint8_t door_status = 0;
	uint8_t power_status = 0;
	uint8_t last_power_status = 0xFF;

	wdt_enable(WDTO_8S);
	
	door_init();
	
	//Pin Change interrupt for cardreader power request line
	PCICR = (1 << PCIE0);
	PCMSK0 |= (1 << CARDREADER_POWER_REQUEST_PCINT);
	
	power_init();
	status_init();
	
	cardreader_init();
	
	timer_init(10);
	shell_init();

	sei();
	
	printf_P(PSTR("\n== Yo! Warpzone Portal control online. ==\n"));
	
	
	keystore_init();
	printf_P(PSTR("Keystore initialized\n"));
	
	log_append(LOG_EVENT_STARTUP, 0);
	
	shell_show_welcome_prompt();
	
	while(1){
		wdt_reset();
		
		sleep();
		
		if (timer_tick){
			tick();
			timer_tick = 0;
		}
		
		door_status = door_get_status();
		
		if (last_door_status != door_status){
/*			uint8_t new_flags = (last_door_status ^ door_status) & door_status;
			if (new_flags & DOOR_STATUS_ALARM) alarm_start();*/
			
			last_door_status = door_status;
			status_update(1, 0); //door status update
		}
		
		power_process();
		power_status = power_get_status();
		if (power_status != last_power_status){
			last_power_status = power_status;
			//Power status changed, need to switch cardreader and keymatic power on or off accordingly
			if (power_switch_time == POWER_SWITCH_BOOTUP){
				//After Bootup we switch immediatly
				power_switch_time = 0;
			} else {
				//otherwise we wait a bit, to avoid needless on/off switching of devices
				power_switch_time = POWER_SWITCH_TIME;
			}
			status_update(0, 1); //update status led to show the power status
		}
		
		//Once the wait time after a power status change is over, we switch the power for external devices
		if (power_switch_time == 0){
			if (power_status & POWER_STATUS_AC_ON){
				//While on AC we keep the card reader and Keymatic battery charger online
				if (!cardreader_is_powered()) cardreader_powerup();
				door_set_keymatic_charge_power(1);
			} else {
				//On battery we turn them off to preserve the main battery power
				//The card reader will be powered up once a card is inserted.
				if (cardreader_is_powered()) cardreader_shutdown();
				door_set_keymatic_charge_power(0);
			}
			
			power_switch_time =  POWER_SWITCH_DONE;
		}
		
		status_process();
		
		cardreader_process();
		shell_process();
		

	}
}