#include "hdgl.h"
#include <string.h>
#include <stdint.h>

void hdgl_init(HDGL_Lattice *lattice) {
    lattice->num_channels = MAX_CHANNELS;
    for(int i=0;i<MAX_CHANNELS;i++){
        memset(lattice->channels[i].buffer, 0, PAGE_SIZE);
        lattice->channels[i].active = 1;
        snprintf(lattice->channels[i].name, 32, "channel_%d", i);
    }
}

void hdgl_map_bytes(HDGL_Lattice *lattice, uint8_t *data, int len, const char *device_name){
    int pages = len / PAGE_SIZE + ((len % PAGE_SIZE) ? 1 : 0);
    for(int i=0;i<pages;i++){
        int ch_idx = i % MAX_CHANNELS;
        int offset = i*PAGE_SIZE;
        int copy_len = (len-offset > PAGE_SIZE) ? PAGE_SIZE : (len-offset);
        memcpy(lattice->channels[ch_idx].buffer, data+offset, copy_len);
    }
}

void hdgl_execute_all(HDGL_Lattice *lattice){
    for(int i=0;i<MAX_CHANNELS;i++){
        if(!lattice->channels[i].active) continue;
        for(int j=0;j<PAGE_SIZE;j++){
            lattice->channels[i].buffer[j] = (lattice->channels[i].buffer[j] + 1) % 256;
        }
    }
}

void hdgl_fuse_channels(HDGL_Lattice *lattice){
    for(int i=0;i<MAX_CHANNELS-1;i++){
        if(!lattice->channels[i].active) continue;
        for(int j=0;j<PAGE_SIZE;j++){
            uint16_t sum = lattice->channels[i].buffer[j] + lattice->channels[i+1].buffer[j];
            lattice->channels[i].buffer[j] = (sum/2) & 0xFF;
        }
    }
}
