#include "pal.h"
#include "mini/file/file.h"
#include "mini/draw/draw.h"

#include <stdlib.h>

#define clamp(x,a,b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)))

namespace mini
{
    namespace pal
    {
        uint32_t palette[256] = { 0xFF1a1c2c, 0xFF5d275d, 0xFFb13e53, 0xFFef7d57, 0xFFffcd75, 0xFFa7f070, 0xFF38b764, 0xFF257179,
                                0xFF29366f, 0xFF3b5dc9, 0xFF41a6f6, 0xFF73eff7, 0xFFf4f4f4, 0xFF94b0c2, 0xFF566c86, 0xFF333c57 };

        void init() {
            pal::subpal::reset();
            draw::state.trans=0;
        }

        uint32_t* LoadPalette(uint8_t *buffer, uint16_t *size = NULL )
        {
            buffer += 10;
            const uint8_t fields = *buffer;

            uint32_t *global_color_table = (uint32_t *)calloc(1, 1024);;

            if (size) *size = 0;
            if (fields & 0x80) {
                int global_color_table_size = 1 << (((fields & 0x07) + 1));
                if (size) *size = global_color_table_size;

                for (int i=0; i<global_color_table_size;++i) {
                    buffer+=3;
                    global_color_table[i] = (buffer[0]<<16) + (buffer[1]<<8) + buffer[2];
                }
            }
            return global_color_table;
        }

        uint32_t *load(const char* filename, uint16_t *palsize) {
            int size;
            uint8_t *buffer = (uint8_t*)file::getfilebuffer(filename, size);
            uint32_t *pal = LoadPalette(buffer, palsize);
            free(buffer);
            return pal;
        }

        void set(uint32_t *pal) {
            for (int i=0; i<256; ++i) palette[i] = pal[i] | 0xff000000;
        }

        namespace color {
            void set(uint8_t index, uint32_t color) {
                palette[index] = color | 0xff000000;
            }

            uint32_t get(uint8_t index) {
                return palette[index];
            }
        }

        namespace trans {
            void set(uint8_t index) {
                draw::state.trans = index;
            }

            uint8_t get() {
                return draw::state.trans;
            }
        }

        namespace subpal {
            uint8_t set(uint8_t index, uint8_t color) {
                const uint8_t old = draw::state.draw_palette[clamp(index,0,255)];
                draw::state.draw_palette[clamp(index,0,255)] = clamp(color,0,255);
                return old;
            }

            void reset() {
                for (int i=0;i<256;++i) draw::state.draw_palette[i]=i;
            }
        }
    }
}