#include <gamepad.h>
#include <string.h>
#include <interrupts.h>

static gamepad_context ctx = {0};

void gamepad_init();

void gamepad_int_update(){
    if(ctx.button_sel) {
        if((ctx.prev.a == 1 && ctx.controller.a == 0) || (ctx.prev.b == 1 && ctx.controller.b == 0) || (ctx.prev.select == 1 && ctx.controller.select == 0) || (ctx.prev.start == 1 && ctx.controller.start == 0)) {
            cpu_request_interrupt(IT_JOYPAD);
            return;
        }
    }
    if(ctx.dir_sel) {
        if((ctx.prev.up == 1 && ctx.controller.up == 0) || (ctx.prev.down == 1 && ctx.controller.down == 0) || (ctx.prev.left == 1 && ctx.controller.left == 0) || (ctx.prev.right == 1 && ctx.controller.right == 0)) {
            cpu_request_interrupt(IT_JOYPAD);
        }
    }

}

bool gamepad_button_sel(){
    return ctx.button_sel;
}

bool gamepad_dir_sel(){
    return ctx.dir_sel;
}

void gamepad_set_sel(u8 value){
    ctx.button_sel = value & 0x20;
    ctx.dir_sel = value & 0x10;
}

gamepad_state *gamepad_get_state(){
    return &ctx.controller;
}

u8 gamepad_get_output() {
    u8 output = 0xCF;

    if(!gamepad_button_sel()) {
        if (gamepad_get_state()->start) {
            output &= ~(1 << 3);
        }
        if (gamepad_get_state()->select) {
            output &= ~(1 << 2);
        }
        if (gamepad_get_state()->a) {
            output &= ~(1 << 0);
        }
        if (gamepad_get_state()->b) {
            output &= ~(1 << 1);
        }
    }

    if(!gamepad_dir_sel()) {
        if (gamepad_get_state()->left) {
            output &= ~(1 << 1);
        }
        if (gamepad_get_state()->right) {
            output &= ~(1 << 0);
        }
        if (gamepad_get_state()->up) {
            output &= ~(1 << 2);
        }
        if (gamepad_get_state()->down) {
            output &= ~(1 << 3);
        }
    }

    return output;
}

void gamepad_save_state(ctlr_state* state){
    state->ctx = ctx;
}

void gamepad_load_state(const ctlr_state* state){
    ctx = state->ctx;
}