#if defined(WIN32)
#include <curses.h>
#else
#include <ncurses.h> //getch printw addch attron attroff
#endif
#include <unistd.h> //sleep unix only
#include <time.h>  //clock

#include "engine.h"
/* timing */

void Wait(Co ck){
    Let lastTick = ck->llection[MMAND][LstTck];
	clock_t rangetck = CLOCKS_PER_SEC / FPS;
	unsigned int usleepmax = 1000000 / FPS;
	unsigned int slp = usleepmax;
	clock_t nowtck = clock();
	clock_t difftck = nowtck - lastTick;
	if (difftck < rangetck){
		clock_t timeleft = rangetck - difftck;
		slp = usleepmax * timeleft / rangetck;
	}
	usleep(slp);
    ck->llection[MMAND][LstTck] = nowtck;
    ck->llection[MMAND][Clck] = (ck->llection[MMAND][Clck] + 1) % MAX;
}

void CursesInit(Co co){
	initscr();
	cbreak();
	noecho();
    curs_set(0);
	keypad(stdscr,1);
	mousemask(ALL_MOUSE_EVENTS, NULL);
	nodelay(stdscr,1);
	if (has_colors() == 0 ){
		printw("no color");
        endwin();
        exit(0);
	}
	else{
		start_color();
		use_default_colors();
        short ofg=0, obg=0;
        pair_content(-1,&obg, &ofg);
        short palette[] = {-1, COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE,
                              COLOR_CYAN, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE }; 
        for(Color c=T; c < Colors; c++){
            short fg = c%9;
            short bg = c/9;
            init_pair(c,palette[bg],palette[fg]);
        }
	}
}

void CursesExit(Co co){
    endwin();
    exit(0);
}


void Control(Co co){
    //decrement any value of all keys until they reach 0
    for (int i=0;i<MAX;i++)
    if (co->llection[KEYS][i])
    co->llection[KEYS][i]--;

	MEVENT mouse;
	int k = getch();
	while (k != ERR){
        //anykey
        co->llection[KEYS]['*'] = 1;
        //convert special key to simple value
        switch(k){
            case KEY_MOUSE:
                if (getmouse(&mouse) == OK){
                    co->llection[MMAND][ClickX] = mouse.x;
                    co->llection[MMAND][ClickY] = mouse.y;
                    k = '!';
                }
                break;
            case 27 : 
                if (getch() == ERR){
                    k = 'q';
                }
                break;
            case KEY_UP:
                k = Up;
                break;
            case KEY_DOWN:
                k = Down;
                break;
            case KEY_LEFT:
                k = Left;
                break;
            case KEY_RIGHT:
                k = Right;
                break;
            case KEY_ENTER:
                break;
            case KEY_BACKSPACE:
                break;
        }
        // if the key repeat, just ignore until it pop out
        // no way to handle multiple held key

        if ('a' <= k && 'z' >= k){
            k = k - 'a' + 'A';
        }

        if (MAX > k)
        if (co->llection[KEYS][k] == 0)
        co->llection[KEYS][k] = Tkey;

        k = getch();
	}
}
/*
corner and lines
ACS_BSSB ACS_SSBB ... ACS_[SB]{4} you get it ?
ACS_SSSS is PLUS +
ACS_BBBB dont exist,  nor ACS_SBBB BSBB BBSB BBBS

*/
void CursesPlot(Let ch, Let col, Let row, Color cl){
    int frames[] = {0,ACS_CKBOARD, ACS_BULLET, ACS_DIAMOND,
                    ACS_LARROW, ACS_RARROW, ACS_UARROW, ACS_DARROW,  
                    ACS_S1, ACS_S3, ACS_S7, ACS_S9,
                    ACS_VLINE,ACS_HLINE,ACS_PLUS,
                    ACS_LLCORNER,ACS_ULCORNER,ACS_URCORNER,ACS_LRCORNER,
                    ACS_TTEE,ACS_RTEE,ACS_BTEE,ACS_LTEE,
                    0};
    int chw = ch;
    if (ch < Symbols) chw = frames[ch];
    move(row,col);
    attrset(COLOR_PAIR(cl));
    attron(A_BOLD);
    addch(chw);
}

void CursesRefresh(Co co){
    {
    int w,h;
    getmaxyx(stdscr,h,w);
    co->llection[MMAND][ScrW] = w;
    co->llection[MMAND][ScrH] = h;
    }
    attrset(0);
    move(H,W);
    refresh();
}

void CursesFlash(Co co,Let rate, Color cl){
    if (flash() == 0){
        short ofg=0, obg=0;
        pair_content(-1,&obg, &ofg);
        //init_pair(-1,obg,ofg);
    }
}

void CursesSay(Co co,Let * msg, Let col, Let row, Color cl){
    move(row,col);
    attrset(COLOR_PAIR(cl));
    addstr(msg);
}



