#include <display.h>
#include <cpu.h>

#define HIGH_BIT(b) ((b & 0x80) >> 7)
#define LO_BIT(b) ((b >> 0) & 1)

void display_set_register_selector(display_t* display, uint8_t value){
    //printf("set register selector to %d\n", value);
    display->register_selector = value;
}

void display_set_data_register(display_t* display, uint8_t value, cpu_status_t* status){
    //printf("\e[35mset data register to %d register selector is %d\e[39m\n", value, display->register_selector);
    if(display->register_selector == 8){
        if(value==4){display->x=0;SDL_RenderPresent(display->renderer);return;}
        display->line = value-128;
        if(status->log)
        printf("\e[35mline to %d\e[39m\n", value-128+1);
    }
    if(display->register_selector == 10){
        for(int b=0;b<8;b++){
            if(HIGH_BIT(value << b) == 1){
                display_pixel_on(display, display->x*8+b , display->line);
            }
            else {
                display_pixel_off(display, display->x*8+b , display->line);
            }
            //printf("pix %d %d\n", display->x*8+b, display->line);
        }
        display->x++;
    }
}

void display_pixel_on(display_t* display, int x, int y){
    SDL_SetRenderDrawColor(display->renderer, 70,65,69,255);
    SDL_Rect rect;
    rect.h = 3;
    rect.w = 3;
    rect.x = x * 3;
    rect.y = y * 3;
    SDL_RenderFillRect(display->renderer,&rect);
}

void display_pixel_off(display_t* display, int x, int y){
    SDL_SetRenderDrawColor(display->renderer, 179,204,174,255);
    SDL_Rect rect;
    rect.h = 3;
    rect.w = 3;
    rect.x = x * 3;
    rect.y = y * 3;
    SDL_RenderFillRect(display->renderer,&rect);
}

void display_clear(display_t* display){
    SDL_SetRenderDrawColor(display->renderer, 179,204,174,255);
    SDL_RenderClear(display->renderer);
}

void display_update(display_t* display, cpu_status_t* status){
    for(int i=0; i<1024; i++){
        uint8_t byte = status->vram[i];
        for(int b=0; b<8;b++){
            if(HIGH_BIT(byte << b) == 1){
                int nb = b+1;
                int y = i/16;
                int x = (i%16)*8+b;
                display_pixel_on(display, x , y);
            }
            else{
                int nb = b+1;
                int y = i/16;
                int x = (i%16)*8+b;
                display_pixel_off(display, x , y);
            }
        }
        
    }
    SDL_RenderPresent(display->renderer);
}

void display_init(display_t* display){
    SDL_Init( SDL_INIT_VIDEO );
    display->window = SDL_CreateWindow("nemu", 100, 100, 3*128, 3*64, SDL_WINDOW_SHOWN);
    display->renderer = SDL_CreateRenderer(display->window, -1, NULL);
    display_clear(display);
}
