#include "game/momia.hpp"

#include <stdlib.h>

#include "core/jail/jgame.hpp"

Momia::Momia(JD8_Surface gfx, bool dimoni, Uint16 x, Uint16 y, Prota* sam)
    : Sprite(gfx) {
    this->dimoni = dimoni;
    this->sam = sam;

    this->entitat = (Entitat*)malloc(sizeof(Entitat));
    // Frames
    this->entitat->num_frames = 20;
    this->entitat->frames = (Frame*)malloc(this->entitat->num_frames * sizeof(Frame));
    Uint16 frame = 0;
    for (int y = 0; y < 4; y++) {
        for (int x = 0; x < 5; x++) {
            this->entitat->frames[frame].w = 15;
            this->entitat->frames[frame].h = 15;
            if (info::num_piramide == 4) this->entitat->frames[frame].h -= 5;
            this->entitat->frames[frame].x = (x * 15) + 75;
            if (this->dimoni) this->entitat->frames[frame].x += 75;
            this->entitat->frames[frame].y = 20 + (y * 15);
            frame++;
        }
    }
    // Animacions
    this->entitat->num_animacions = 4;
    this->entitat->animacions = (Animacio*)malloc(this->entitat->num_animacions * sizeof(Animacio));
    for (int i = 0; i < 4; i++) {
        this->entitat->animacions[i].num_frames = 8;
        this->entitat->animacions[i].frames = (Uint8*)malloc(8);
        this->entitat->animacions[i].frames[0] = 0 + (i * 5);
        this->entitat->animacions[i].frames[1] = 1 + (i * 5);
        this->entitat->animacions[i].frames[2] = 2 + (i * 5);
        this->entitat->animacions[i].frames[3] = 1 + (i * 5);
        this->entitat->animacions[i].frames[4] = 0 + (i * 5);
        this->entitat->animacions[i].frames[5] = 3 + (i * 5);
        this->entitat->animacions[i].frames[6] = 4 + (i * 5);
        this->entitat->animacions[i].frames[7] = 3 + (i * 5);
    }

    this->cur_frame = 0;
    this->o = rand() % 4;
    this->cycles_per_frame = 4;
    this->next = NULL;

    if (this->dimoni) {
        if (x == 0) {
            this->x = 150;
        } else {
            this->x = x;
        }
        if (y == 0) {
            if (this->sam->y > 100) {
                this->y = 30;
            } else {
                this->y = 170;
            }
        } else {
            this->y = y;
        }
        this->engendro = new Engendro(gfx, this->x, this->y);
    } else {
        this->engendro = NULL;
        this->x = x;
        this->y = y;
    }
}

void Momia::clear() {
    if (this->next != NULL) this->next->clear();
    if (this->engendro != NULL) delete this->engendro;
    delete this->next;
}

void Momia::draw() {
    if (this->engendro != NULL) {
        this->engendro->draw();
    } else {
        Sprite::draw();

        if (info::num_piramide == 4) {
            if ((JG_GetCycleCounter() % 40) < 20) {
                JD8_BlitCK(this->x, this->y, this->gfx, 220, 80, 15, 15, 255);
            } else {
                JD8_BlitCK(this->x, this->y, this->gfx, 235, 80, 15, 15, 255);
            }
        }
    }
    if (this->next != NULL) this->next->draw();
}

bool Momia::update() {
    bool morta = false;

    if (this->engendro != NULL) {
        if (this->engendro->update()) {
            delete this->engendro;
            this->engendro = NULL;
        }
    } else {
        if (this->sam->o < 4 && (this->dimoni || info::num_piramide == 5 || JG_GetCycleCounter() % 2 == 0)) {
            if ((this->x - 20) % 65 == 0 && (this->y - 30) % 35 == 0) {
                if (this->dimoni) {
                    if (rand() % 2 == 0) {
                        if (this->x > this->sam->x) {
                            this->o = 3;
                        } else if (this->x < this->sam->x) {
                            this->o = 2;
                        } else if (this->y < this->sam->y) {
                            this->o = 0;
                        } else if (this->y > this->sam->y) {
                            this->o = 1;
                        }
                    } else {
                        if (this->y < this->sam->y) {
                            this->o = 0;
                        } else if (this->y > this->sam->y) {
                            this->o = 1;
                        } else if (this->x > this->sam->x) {
                            this->o = 3;
                        } else if (this->x < this->sam->x) {
                            this->o = 2;
                        }
                    }
                } else {
                    this->o = rand() % 4;
                }
            }

            switch (this->o) {
                case 0:
                    if (y < 170) this->y++;
                    break;
                case 1:
                    if (y > 30) this->y--;
                    break;
                case 2:
                    if (x < 280) this->x++;
                    break;
                case 3:
                    if (x > 20) this->x--;
                    break;
            }

            if (JG_GetCycleCounter() % this->cycles_per_frame == 0) {
                this->cur_frame++;
                if (this->cur_frame == this->entitat->animacions[this->o].num_frames) this->cur_frame = 0;
            }

            if (this->x > (this->sam->x - 7) && this->x < (this->sam->x + 7) && this->y > (this->sam->y - 7) && this->y < (this->sam->y + 7)) {
                morta = true;
                if (this->sam->pergami) {
                    this->sam->pergami = false;
                } else {
                    info::vida--;
                    if (info::vida == 0) this->sam->o = 5;
                }
            }
        }
    }

    if (this->next != NULL) {
        if (this->next->update()) {
            Momia* seguent = this->next->next;
            delete this->next;
            this->next = seguent;
            info::momies--;
        }
    }

    return morta;
}

void Momia::insertar(Momia* momia) {
    if (this->next != NULL) {
        this->next->insertar(momia);
    } else {
        this->next = momia;
    }
}
