#include <16F876A.h>
#include <stdlib.h>

#FUSES WDT                      //Watch Dog Timer 
#FUSES XT                        
#FUSES NOPUT                    //No Power Up Timer 
#FUSES NOPROTECT                //Code not protected from reading 
#FUSES NODEBUG                  //No Debug mode for ICD 
#FUSES NOBROWNOUT               //No brownout reset 
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 
#FUSES NOCPD                    //No EE protection 
#FUSES NOWRT                    //Program memory not write protected 

#use delay(clock=4000000)
//#include <ds1307.c>
//#include <unixtime.c> 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, STREAM=COM_A, parity=N, bits=8) 	
//#zero_ram

char p, term[2], command[56] = "", action[10] = "", values[40] = "", picid[8] = "", pass[8] = "", permited[9] = "";
short newcommand = 0;
int k = 0;
int32 seconds[14], times[14], epoch;
//BYTE sec, min, hrs, day, mn, yr, dow;
int1 logged;

#INT_RDA
void usart_modem(void)
{  
	newcommand = 0;
	if (kbhit(COM_A))
	{
		p = fgetc(COM_A);
		if(p == '#') {
			command[k] = '\0';
			newcommand = 1;
			k = 0;
		}else{
			command[k] = p;
			k++;
		}
	}
}

int command_is(char *p1, char *p2)
{
	int *p3;
	p3 = strstr(p1,p2);
	return (p3);
}

void open(void)
{
	int i, j=0;
	char numbers[3] = "", letter;
	unsigned char number;
	for(i = 0; i < strlen(values); i += 3){
		numbers[0] = values[i];
		numbers[1] = values[i+1];
		numbers[2] = '\0';
		letter     = values[i+2];
		number     = atoi(numbers);
		if(letter == 77) number *= 60;
		seconds[j] = number;
		times[j]   = epoch; //secondsSinceYear1(yr, mn, day, hrs, min, sec);
		j++;
	}
	if(seconds[0]  > 0) output_bit(PIN_C0, 1);
	if(seconds[1]  > 0) output_bit(PIN_C1, 1);
	if(seconds[2]  > 0) output_bit(PIN_C2, 1);
	if(seconds[3]  > 0) output_bit(PIN_C3, 1);
	if(seconds[4]  > 0) output_bit(PIN_B7, 1);
	if(seconds[5]  > 0) output_bit(PIN_B6, 1);
	if(seconds[6]  > 0) output_bit(PIN_B5, 1);
	if(seconds[7]  > 0) output_bit(PIN_B4, 1);
	if(seconds[8]  > 0) output_bit(PIN_B3, 1);
	if(seconds[9]  > 0) output_bit(PIN_B2, 1);
	if(seconds[10] > 0) output_bit(PIN_B1, 1);
	if(seconds[11] > 0) output_bit(PIN_B0, 1);
	if(seconds[12] > 0) output_bit(PIN_C5, 1);
	if(seconds[13] > 0) output_bit(PIN_C4, 1);
}

void close(void)
{
	if(values[0]  > 0) output_bit(PIN_C0, 0);
	if(values[1]  > 0) output_bit(PIN_C1, 0);
	if(values[2]  > 0) output_bit(PIN_C2, 0);
	if(values[3]  > 0) output_bit(PIN_C3, 0);
	if(values[4]  > 0) output_bit(PIN_B7, 0);
	if(values[5]  > 0) output_bit(PIN_B6, 0);
	if(values[6]  > 0) output_bit(PIN_B5, 0);
	if(values[7]  > 0) output_bit(PIN_B4, 0);
	if(values[8]  > 0) output_bit(PIN_B3, 0);
	if(values[9]  > 0) output_bit(PIN_B2, 0);
	if(values[10] > 0) output_bit(PIN_B1, 0);
	if(values[11] > 0) output_bit(PIN_B0, 0);
	if(values[12] > 0) output_bit(PIN_C5, 0);
	if(values[13] > 0) output_bit(PIN_C4, 0);
}

/*
void set_time(void)
{
	char val[3];
	val[0] = values[0];
	val[1] = values[1];
	val[2] = '\0';
	day = atoi(val);
	val[0] = values[2];
	val[1] = values[3];
	val[2] = '\0';
	mn = atoi(val);
	val[0] = values[4];
	val[1] = values[5];
	val[2] = '\0';
	yr = atoi(val);
	val[0] = values[6];
	val[1] = values[7];
	val[2] = '\0';
	hrs = atoi(val);
	val[0] = values[8];
	val[1] = values[9];
	val[2] = '\0';
	min = atoi(val);
	val[0] = values[10];
	val[1] = values[11];
	val[2] = '\0';
	sec = atoi(val);
	dow = 1;
	//ds1307_set_date_time(day,mn,yr,dow,hrs,min,sec);
}

void read_time(void)
{
	printf("\r\n\%02d/\%02d/\%02d \%02d:\%02d:\%02d\r\n", day, mn, yr, hrs, min, sec); 
}
*/
void read_pass(void)
{
	int i, address = 12;
	for(i = 0; i < 6; i++){
		pass[i] = read_eeprom(address + i);
	}
	pass[i] = '\0';
}

void set_pass(void)
{
	int i, address = 12;
	for(i = 0; i < 6; i++){
		write_eeprom(address + i, values[i]);
	}
}

void read_pic(void)
{
	int i, address = 2;
	for(i = 0; i < 7; i++){
		picid[i] = read_eeprom(address + i);
	}
	picid[i] = '\0';
}

void set_pic(void)
{
	int i, address = 2;
	for(i = 0; i < 7; i++){
		write_eeprom(address + i, values[i]);
	}
}

void auto_off(void)
{
	//epoch = secondsSinceYear1(yr, mn, day, hrs, min, sec);
	if(seconds[0]  > 0 && (epoch - times[0])  > seconds[0])  output_bit(PIN_C0, 0);
	if(seconds[1]  > 0 && (epoch - times[1])  > seconds[1])  output_bit(PIN_C1, 0);
	if(seconds[2]  > 0 && (epoch - times[2])  > seconds[2])  output_bit(PIN_C2, 0);
	if(seconds[3]  > 0 && (epoch - times[3])  > seconds[3])  output_bit(PIN_C3, 0);
	if(seconds[4]  > 0 && (epoch - times[4])  > seconds[4])  output_bit(PIN_B7, 0);
	if(seconds[5]  > 0 && (epoch - times[5])  > seconds[5])  output_bit(PIN_B6, 0);
	if(seconds[6]  > 0 && (epoch - times[6])  > seconds[6])  output_bit(PIN_B5, 0);
	if(seconds[7]  > 0 && (epoch - times[7])  > seconds[7])  output_bit(PIN_B4, 0);
	if(seconds[8]  > 0 && (epoch - times[8])  > seconds[8])  output_bit(PIN_B3, 0);
	if(seconds[9]  > 0 && (epoch - times[9])  > seconds[9])  output_bit(PIN_B2, 0);
	if(seconds[10] > 0 && (epoch - times[10]) > seconds[10]) output_bit(PIN_B1, 0);
	if(seconds[11] > 0 && (epoch - times[11]) > seconds[11]) output_bit(PIN_B0, 0);
	if(seconds[12] > 0 && (epoch - times[12]) > seconds[12]) output_bit(PIN_C5, 0);
	if(seconds[13] > 0 && (epoch - times[13]) > seconds[13]) output_bit(PIN_C4, 0);
}

/*		Programa principal		*/
void main(void)															
{
	/* Activo todos los pines A como entradas */
	set_tris_a(0xFF);
	/* Activo todos los pines B como salidas */
	set_tris_b(0b00000000);
	/* Activo PIN_C4 y PIN_C7 como entradas */
	set_tris_c(0b10010000);
	
	/* Todos los pines B y C apagados, excepto los que son entradas */
	output_B(0b00000000);
	output_bit(PIN_C0, 0);
	output_bit(PIN_C1, 0);
	output_bit(PIN_C2, 0);
	output_bit(PIN_C5, 0);
	
	/* Activo interrupciones */
	enable_interrupts(GLOBAL);
	enable_interrupts(INT_RDA);
	
	//ds1307_init();
	epoch = 0;
	/* Password por defecto*/
	strcpy(values, "BUS554");
	set_pass();

	while(TRUE)
	{
		delay_ms(1000);
		epoch++;
		
		//ds1307_get_date(day, mn, yr, dow); 
		//ds1307_get_time(hrs, min, sec); 
		//read_time();
		auto_off();
		
		if(newcommand){
			newcommand = 0;
			
			strcpy(term, "|");
			strcpy(picid, strtok(command, term));
			strcpy(action, strtok(0, term));
			strcpy(values, strtok(0, term));
			
			//printf("\r\npicid: %s action: %s values: %s\r\n", picid, action, values);
			
			strcpy(permited, "LOGIN");
			if(command_is(permited, action)){
				read_pass();
				if(command_is(values, pass)){
					logged = 1;
					printf("Logged ...\r\n");
				}
			}
			strcpy(permited, "SETPASS");
			if(command_is(permited, action) && logged){
				set_pass();
				printf("%s\r\n", pass);
			}
			strcpy(permited, "READPASS");
			if(command_is(permited, action) && logged){
				read_pass();
				printf("%s\r\n", pass);
			}
			strcpy(permited, "READPIC");
			if(command_is(permited, action) && logged){
				read_pic();
				printf("%s\r\n", picid);
			}
			strcpy(permited, "SETPIC");
			if(command_is(permited, action) && logged){
				set_pic();
				printf("Setpic ...\r\n");
			}
			/*
			strcpy(permited, "SETTIME");
			if(command_is(permited, action) && logged){
				set_time();
				printf("Settime ...\r\n");
			}
			strcpy(permited, "READTIME");
			if(command_is(permited, action)){
				read_time();
				printf("Readtime ...\r\n");
			}
			*/
			strcpy(permited, "OPEN");
			if(command_is(permited, action)){
				open();
				printf("Opened ...\r\n");
			}
			strcpy(permited, "CLOSE");
			if(command_is(permited, action)){
				close();
				printf("Closed ...\r\n");
			}
			strcpy(permited, "EXIT");
			if(command_is(permited, action)){
				logged = 0;
				printf("Exit ...\r\n");
			}
		}else{
			printf("Waiting %lu...\r\n", epoch);
		}
	}
}