
#include "despair.h"

#include "vga.h"
#include "jclib.h"
#include "sincos.h"
#include "llscreen.h"
#include "llkey.h"
#include "pix.h"

static sint32 (*dtable)[256];//32
static sint32 (*stable)[256];//32

static byte (*ctable)[256];//256

static byte (*image)[512];//256

static byte (*clr)[256];//32

static byte (*pix)[320];//200

static byte *iguanapic;

static bool Dontclear = FALSE;

#define pal DestPal

static void MatchColors(void) {
    int i, j, k, found_num;
    unsigned long found_dist, this_dist;

    if (JCLIB_Load("GFX\\weave.mix", ctable, 65536) == 65536)
        return;
    for (i = 0; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            int r, g, b;
            found_dist = 0x7FFFFFFFL;
            found_num = 0;
            r = (8*pal[3*i+0] + 4*pal[3*j+0])/12;
            g = (8*pal[3*i+1] + 4*pal[3*j+1])/12;
            b = (8*pal[3*i+2] + 4*pal[3*j+2])/12;
            for (k = 0; k < 768; k+=3) {
                this_dist = Pow2(r - (sint32)pal[k])
                          + Pow2(g - (sint32)pal[k+1])
                          + Pow2(b - (sint32)pal[k+2]);
                if (this_dist < found_dist) {
                    found_dist = this_dist;
                    found_num = k;
                    if (this_dist == 0)
                        break;
                }
            }
            ctable[i][j] = found_num/3;
        }
//        putchar('ú'); fflush(stdout);
    }
    {
        FILE *f = fopen("GFX\\weave.mix", "wb");
        fwrite(ctable[0],   256, 64, f);
        fwrite(ctable[64],  256, 64, f);
        fwrite(ctable[128], 256, 64, f);
        fwrite(ctable[192], 256, 64, f);
        fclose(f);
    }
}

#undef pal


static int a, b;
static int idt;
static float f_idt = 0;
static dword lasttime = 0;

static bool DoWeave(dword time) {
    int i, j;
    int ia, jb;
    byte *p;
    sint32 *dt;

    dt = dtable[idt];
    p = LLS_Screen[0];
    for (i = 0, ia = a; i < 200; i+=1, ia = (ia+1)&255) {
        for (j = 0, jb = b; j < 320; j+=1, jb = (jb+1)&255) {
            sint32 ki = dt[jb];
            sint32 kj = dt[ia];
            *p = ctable[*p][image[(i+ki)&255]
                                 [(j+kj)&511]
                           ];

            p+=1;
        }
    }


    for (i = 0; i < 200; i++)
        memcpy(image[i], LLS_Screen[i], 320);

    while (lasttime < time) {
        a = (a+2)&255;
        b = (b+3)&255;
        f_idt += 0.017f;
        lasttime += 1;
    }
    idt = (int)f_idt;
    if (idt > 31)
        idt = 31;

    LLS_Update();

    return TRUE;
}

extern bool InitWeave(dword time) {
    int i, j;

    lasttime = time;

    REQUIRE( (dtable = NEW(32*sizeof(*dtable))) != NULL);
    REQUIRE( (stable = NEW(32*sizeof(*stable))) != NULL);
    REQUIRE( (ctable = NEW(256*sizeof(*ctable))) != NULL);
    REQUIRE( (image  = NEW(256*sizeof(*image))) != NULL);
    REQUIRE( (clr = NEW(32*sizeof(*clr))) != NULL);
    REQUIRE( (pix = NEW(200*sizeof(*pix))) != NULL);
    REQUIRE( (iguanapic = NEW(2*(200*320+768))) != NULL);

    for (i = 0; i < 32; i++)
        for (j = 0; j < 256; j++)
            dtable[i][j] = FPMult(i, Cos(j*256));

    for (i = 0; i < 32; i++)
        for (j = 0; j < 256; j++)
            stable[i][j] = FPMult(3*i, FPMult(Cos(j*256),Cos(j*256)));

    PIX_Load("GFX\\WEAVE.GIF", pix[0], DestPal, NULL, NULL, FALSE);
    EnhancePal();
    PIX_Load("GFX\\IGUANA1.GIF", iguanapic, iguanapic+320*200, NULL, NULL, FALSE);
    PIX_Load("GFX\\DESPAIR3.GIF", iguanapic + 64768, iguanapic+128768, NULL, NULL, FALSE);
    JCLIB_Load("GFX\\weave.clr", clr[0], 8192);
    for (i = 0; i < 256; i++)
        for (j = 0; j < 512; j++)
            image[i][j] = pix[i%200][j%320];

    for (i = 0; i < 200; i++)
        for (j = 0; j < 320; j++)
            image[i][j] = 0;

    MatchColors();

//    LLS_Init(LLSM_DIRECT, LLSVM_MODE13);
    VGA_DumpPalette(DestPal, 0, 256);

    a = 17; b = 93;
    idt = 0;

    CurFunction = DoWeave;

    return TRUE;
}

extern bool StopWeave(dword time) {

    memcpy(LLS_Screen[0], iguanapic, 320*200);
    memcpy(DestPal, iguanapic+320*200, 768);
    EnhancePal();

    DISPOSE(dtable);
    DISPOSE(stable);
    DISPOSE(ctable);
    DISPOSE(image);
    DISPOSE(clr);
    DISPOSE(pix);

    LLS_Update();

    CurFunction = NULL;

    return TRUE;
}

extern bool EndWeave(dword time) {

    memcpy(LLS_Screen[0], iguanapic+64768, 320*200);
    memcpy(DestPal, iguanapic+128768, 768);
    EnhancePal();

    DISPOSE(iguanapic);

    LLS_Update();

    return TRUE;
}

extern bool WeaveNoClear(dword time) {
    a = (a + 80) & 255;
    b = (b + 50) & 255;
    Dontclear = TRUE;
    return TRUE;
}
