#include <iostream>
#include <string>
#include <unistd.h>

std::string state[] = {"\e[1;32mgreen\e[1;0m","\e[1;33myellow\e[1;0m","\e[1;31mred\e[1;0m"};
uint32_t debug_timing = 500000;
int timing[] = {0,5,25};
std::string location[] = {"north","south","east","west"};
std::string tab = "	";
int pid[] = {0,0};
int light_states[] = {2,2,2,2};
int count = 0;

void clear_screen(){
        std::cout << "\033[H\033[2J\033[3J";
}

void state_addrs(){
        count = 0;
        while(count < 3){
                std::string* p = &state[count];
                std::cout << "state[" << count << "]:" << tab << tab << p << tab << state[count] << '\n';
                count++;
	}
	return;
}

void debug_timing_addrs(){
        count = 0;
        while(count < 1){
                uint32_t* q = &debug_timing;
                std::cout << "debug_timing:" << tab << tab << q << tab << debug_timing << '\n';
                count++;
	}
	return;
}

void timing_addrs(){
	count = 0;
	while(count < 3){
		int* r = &timing[count];
		std::cout << "timing[" << count << "]:" << tab << tab << r << tab << timing[count] << '\n';
		count++;
	}
	return;
}

void location_addrs(){
        count = 0;
        while(count < 4){
                std::string* s = &location[count];
                std::cout << "location[" << count << "]:" << tab << tab << s << tab << location[count] << '\n';
                count++;
        }
        return;
}


void tab_addrs(){
        count = 0;
        while(count < 1){
                std::string* t = &tab;
                std::cout << "tab:" << tab << tab << tab << t << tab << "[tab]" << '\n';
                count++;
        }
        return;
}

void pid_addrs(){
        count = 0;
        while(count < 2){
                int* u = &pid[count];
                std::cout << "pid[" << count << "]:" << tab << tab << tab << u << tab << pid[count] << '\n';
                count++;
        }
        return;
}



void light_states_addrs(){
        count = 0;
        while(count < 4){
                int* v = &light_states[count];
                std::cout << "light_states[" << count << "]:" << tab << v << tab << light_states[count] << '\n';
                count++;
        }
        return;
}


void dump_addrs(){
	state_addrs();
	debug_timing_addrs();
	timing_addrs();
	location_addrs();
	tab_addrs();
	pid_addrs();
	light_states_addrs();
}

void display_light_states(){
	int count = 0;
	while(count < 4){
		std::cout << location[count] << tab << state[light_states[count]] << "\n";
		count++;
	
	}
	return;
} 

void _xor(int &a){
	a = a ^ a;
}

void _inc(int &a){
	a++;
}

void display_pids(){
	std::cout << "PID:" << tab << std::hex << pid[0] << "\n";
	std::cout << "Cycle:" << tab << std::hex << pid[1] << "\n";
}

void green_func(int a, int b){
        _inc(pid[0]);
        _xor(light_states[a]);
        _xor(light_states[b]);
        clear_screen();
        display_light_states();
        display_pids();
dump_addrs();
        //sleep(timing[2]);
usleep(debug_timing);
}

void ry_func(int a, int b){
        _inc(pid[0]);
        _inc(light_states[a]);
        _inc(light_states[b]);
        clear_screen();
        display_light_states();
        display_pids();
dump_addrs();
        //sleep(timing[1]);
usleep(debug_timing);
}

void half_cycle(int a, int b){
	green_func(a,b);
	ry_func(a,b);
	ry_func(a,b);
}

int main(){

	_xor(pid[1]);

	while(true){
		_xor(pid[0]);

		half_cycle(0,1);
		half_cycle(2,3);

		_inc(pid[1]);

	}

return 0;

}
