#include "proc_arounders.h"
#include "jgame.h"
#include "proc_mapa.h"
#include "proc_explosio.h"

namespace arounders
{
    arounder *first {nullptr};
    arounder *seleccionat {nullptr};

    draw::surface *sprites { nullptr };
    draw::surface *marca { nullptr };
    draw::surface *explosio { nullptr };
    uint8_t colorEscalo = 76;
    uint8_t colorCorda = 4;

	void initMort(arounder *a);
	void initArrivat(arounder *a);
	void initCaminar(arounder *a);
	void initCaure(arounder *a);
	void initParar(arounder *a);
	void initCavar(arounder *a);
	void initEscalar(arounder *a);
	void initPerforar(arounder *a);
	void initEscalera(arounder *a);
	void initPasarela(arounder *a);
	void initCorda(arounder *a);
	void initPujarCorda(arounder *a);
	void initBaixarCorda(arounder *a);
	void initSuicidi(arounder *a);

	void procesarCaminar(arounder *a);
	void procesarCaure(arounder *a);
	void procesarParar(arounder *a);
	void procesarCavar(arounder *a);
	void procesarEscalar(arounder *a);
	void procesarPerforar(arounder *a);
	void procesarEscalera(arounder *a);
	void procesarPasarela(arounder *a);
	void procesarCorda(arounder *a);
	void procesarPujarCorda(arounder *a);
	void procesarBaixarCorda(arounder *a);
	void procesarSuicidi(arounder *a);

	bool blockCaure(arounder *a, int desfase = 0);
	bool blockCaminar(arounder *a);
	bool blockArounder(arounder *a);
	bool blockParet(arounder *a, int desfase = 0);
	bool blockTecho(arounder *a, int desfase = 0);
	bool blockPrecipici(arounder *a);
	bool blockPrecipiciPasarela(arounder *a);
	bool blockNovaCorda(arounder *a);
	bool blockCordaBaixar(arounder *a, int desfase = 0);
	bool blockCordaPujar(arounder *a, int desfase = 0);
	bool pujarEscalo(arounder *a);
    bool baixarEscalo(arounder *a);

	bool checkArounderAnt(arounder *a, int x, int y, int o);
	bool checkArounderSig(arounder *a, int x, int y, int o);

	void doCavar(arounder *a);
	void doPerforar(arounder *a);
	void doEscalera(arounder *a, int desfase = 0);
	void doCorda(arounder *a);


    void init()
    {
        if (!sprites) sprites = draw::loadSurface("sprites.gif");
        if (!marca) marca = draw::loadSurface("marca.gif");
        if (!explosio) explosio = draw::loadSurface("explosio.gif");
        arounders::first = arounders::seleccionat = nullptr;
    }

    void afegir()
    {
        arounder *a = new arounder();
        a->x = mapa::ini_x*16+8;
        a->y = mapa::ini_y*16+8;
        a->orientacio = mapa::arounders::orientacio_inicial;

        a->frame = a->frameX = a->frameY = a->altura = 0;

        a->accio = a->prevista = accions::caminar;
        a->siguiente = a->anterior = nullptr;

        if (!arounders::first) {
            arounders::first = a;
        } else {
            arounder *pare = arounders::first;
            while (pare->siguiente) pare = pare->siguiente;
            pare->siguiente = a;
            a->anterior = pare;
        }
    }

    void pintar()
    {
        arounder *a = arounders::first;

        draw::setSource(sprites);
        while (a)
        {
            draw::draw(a->x, a->y, 8, 8, a->frameX*8, a->frameY);
            a = a->siguiente;
        }

        if (arounders::seleccionat) {
            draw::setSource(marca);
            draw::draw(arounders::seleccionat->x-3, arounders::seleccionat->y-3);
        }
        explosio::pintar();
    }

    const bool seleccionar()
    {
        const int mx = input::mouseX();
        const int my = input::mouseY();

        arounder *a = arounders::first;
        while (a)
        {
            if (a->x <= mx && (a->x+8) >= mx && a->y <= my && (a->y+8) >= my)
            {
                arounders::seleccionat = a;
                return true;
            }
            a = a->siguiente;
        }
        return false;
    }

    void abortarAccio()
    {
        arounder *a = arounders::seleccionat;
        if (!a) return;

        if (a->accio == arounders::accions::escalar)
        {
            if (a->orientacio == arounders::orientacions::dreta) a->x-=5; else a->x+=5;
        }

        if (a->accio != arounders::accions::caminar &&
            a->accio != arounders::accions::caure &&
            a->accio != arounders::accions::pujarcorda &&
            a->accio != arounders::accions::baixarcorda )
        {
            a->accio = arounders::accions::caminar;
        }
    }

    void procesar()
    {
        arounder *a = arounders::first;

        while (a)
        {
            switch (a->accio)
            {
                case arounders::accions::caminar: procesarCaminar(a); break;
                case arounders::accions::caure: procesarCaure(a); break;
                case arounders::accions::cavar: procesarCavar(a); break;
                case arounders::accions::escalar: procesarEscalar(a); break;
                case arounders::accions::perforar: procesarPerforar(a); break;
                case arounders::accions::escalera: procesarEscalera(a); break;
                case arounders::accions::pasarela: procesarPasarela(a); break;
                case arounders::accions::corda: procesarCorda(a); break;
                case arounders::accions::pujarcorda: procesarPujarCorda(a); break;
                case arounders::accions::baixarcorda: procesarBaixarCorda(a); break;
                case arounders::accions::suicidi: procesarSuicidi(a); break;
            }

            if (a->x == (mapa::fin_x*16)+8 && a->y == (mapa::fin_y*16)+8) initArrivat(a);

            a = a->siguiente;
        }

        a = arounders::first;
        if (a)
        {
            while (a->siguiente) a = a->siguiente;
                    
            while (a) {
                if (a->accio == arounders::accions::mort) {
                    arounder *borrar = a;
                    if (borrar->siguiente) borrar->siguiente->anterior = borrar->anterior;
                    if (borrar->anterior) borrar->anterior->siguiente = borrar->siguiente;
                    if (borrar == arounders::first) arounders::first = borrar->siguiente;
                    if (borrar == arounders::seleccionat) arounders::seleccionat = nullptr;
                    a = borrar->anterior;
                    delete borrar;
                } else {
                    a = a->anterior;
                }
            }
        }
    }

	uint8_t get_pixel(const int x, const int y)
    {
        return mapa::mapa->pixels[x+y*320];
    }

	void put_pixel(const int x, const int y, const uint8_t pixel )
    {
        mapa::mapa->pixels[x+y*320] = pixel;
    }

	void initMort(arounder *a)
    {
        a->accio = arounders::accions::mort;
        draw::setDestination(mapa::mapa);
        draw::setSource(explosio);
        draw::setTrans(1);
        draw::draw(a->x-9, a->y-12);
        draw::setTrans(0);
        draw::setDestination(nullptr);
        explosio::crear(a->x+4, a->y+3, 20, 200, 20, 0);
        mapa::arounders::morts++;
    }

	void initArrivat(arounder *a)
    {
        a->accio = arounders::accions::mort;
        mapa::arounders::arrivats++;
    }

	void initCaminar(arounder *a)
    {
        a->frame = 0;
        a->accio = arounders::accions::caminar;
        procesarCaminar(a);
    }

	void initCaure(arounder *a)
    {
        a->frame = 0;
        a->accio = arounders::accions::caure;
        a->altura = 0;
        procesarCaure(a);
    }

	void initParar(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;

        if (mapa::accions::parar > 0) {
            a->accio = arounders::accions::parar;
            mapa::accions::parar--;
            procesarParar(a);
        } else {
            initCaminar(a);
        }
    }

	void initCavar(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;

        if (mapa::accions::cavar > 0) {
            a->accio = arounders::accions::cavar;
            mapa::accions::cavar--;
            procesarCavar(a);
        } else {
            initCaminar(a);
        }
    }

	void initEscalar(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;

        if (mapa::accions::escalar > 0) {
            a->accio = arounders::accions::escalar;
            mapa::accions::escalar--;
            a->x = a->orientacio == arounders::orientacions::dreta ? a->x + 5 : a->x - 5;
            procesarEscalar(a);
        } else {
            initCaminar(a);
        }
    }

	void initPerforar(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;

        if (mapa::accions::perforar > 0) {
            a->accio = arounders::accions::perforar;
            mapa::accions::perforar--;
            procesarPerforar(a);
        } else {
            initCaminar(a);
        }
    }

	void initEscalera(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;
        a->accio = arounders::accions::escalera;
        procesarEscalera(a);
    }

	void initPasarela(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;
        a->accio = arounders::accions::pasarela;
        procesarPasarela(a);
    }

	void initCorda(arounder *a)
    {
        a->frame = 0;
        a->prevista = arounders::accions::caminar;

        if (mapa::accions::corda > 0) {
            a->accio = arounders::accions::corda;
            mapa::accions::corda--;
            procesarCorda(a);
        } else {
            initCaminar(a);
        }
    }

	void initPujarCorda(arounder *a)
    {
        a->frame = 0;
        a->accio = arounders::accions::pujarcorda;
        a->x = a->orientacio == arounders::orientacions::dreta ? a->x + 3 : a->x - 3;
        procesarPujarCorda(a);
    }

	void initBaixarCorda(arounder *a)
    {
        a->frame = 0;
        a->accio = arounders::accions::baixarcorda;
        if (a->orientacio == arounders::orientacions::dreta) {
            a->x += 2;
        } else {
            a->x -= 2;
        }
        procesarBaixarCorda(a);
    }

	void initSuicidi(arounder *a)
    {
        a->frame = 0;
        a->accio = a->prevista = arounders::accions::suicidi;
        procesarSuicidi(a);
    }



	void procesarCaminar(arounder *a)
    {
        const int frames[4] = {3,4,3,5};
        a->frame++;
        if (a->frame >= 4) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (blockCaure(a)) {
            initCaure(a);
        } else {
            switch ( a->prevista ) {
                case arounders::accions::parar:
                    initParar(a);
                    break;
                case arounders::accions::perforar:
                    initPerforar(a);
                    break;
                case arounders::accions::escalera:
                    initEscalera(a);
                    break;
                case arounders::accions::suicidi:
                    initSuicidi(a);
                    break;
                default:
                    if (blockCordaPujar(a)) {
                        initPujarCorda(a);
                    } else if (blockCaminar(a)) {
                        if (a->prevista == arounders::accions::cavar) {
                            initCavar(a);
                        } else if (a->prevista == arounders::accions::escalar) {
                            initEscalar(a);
                        } else {
                            a->orientacio = a->orientacio ^ arounders::orientacions::esquerra;
                        }
                    } else {
                        if (blockArounder(a)) {
                            a->orientacio = a->orientacio ^ arounders::orientacions::esquerra;
                        } else {
                            if (blockPrecipici(a) && (a->prevista == arounders::accions::pasarela || a->prevista == arounders::accions::corda)) {
                                if (a->prevista == arounders::accions::pasarela) {
                                    initPasarela(a);
                                } else {
                                    initCorda(a);
                                }
                            } else {
                                if (blockCordaBaixar(a)) {
                                    initBaixarCorda(a);
                                } else if (blockCordaPujar(a)) {
                                    initPujarCorda(a);
                                } else {
                                    if (pujarEscalo(a)) a->y--;
                                    a->x += ((((a->orientacio ^ 8) << 1) >> 3) - 1);
                                    if (baixarEscalo(a)) a->y++;
                                }
                            }
                        }
                    }
            }
        }
    }

	void procesarCaure(arounder *a)
    {
        a->frame = 0;
        a->frameX = 11;
        a->frameY = a->orientacio;

        if (!blockCaure(a)) {
            if (a->altura >= 32) {
                initMort(a);
            } else {
                initCaminar(a);
            }
        } else {
            if (a->y > 151) {
                initMort(a);
            } else {
                a->y++;
                a->altura++;
            }
        }
    }

	void procesarParar(arounder *a)
    {
        a->frame = 0;
        a->frameX = 2;
        a->frameY = 8;
    }

	void procesarCavar(arounder *a)
    {
        const int frames[3] = {6,7,8};
        a->frame++;
        if (a->frame == 3) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (blockCaure(a)) {
            initCaure(a);
        } else {
            if (!blockCaminar(a)) {
                initCaminar(a);
            } else {
                if (a->frame == 2) {
                    doCavar(a);
                    if (a->orientacio == arounders::orientacions::dreta) {
                        a->x++;
                    } else {
                        a->x--;
                    }
                }
            }
        }
    }

	void procesarEscalar(arounder *a)
    {
        const int frames[2] = {9,10};
        a->frame++;
        if (a->frame == 2) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (!blockParet(a, 5)) {
            if (a->orientacio == arounders::orientacions::dreta) {
                a->x = a->x - 1;
            } else {
                a->x = a->x + 1;
            }
            a->y = a->y - 1;
            initCaminar(a);
        } else {
            if (blockTecho(a, 5)) {
                if (a->orientacio == arounders::orientacions::dreta) {
                    a->x = a->x - 5;
                } else {
                    a->x = a->x + 5;
                }
                initCaminar(a);
            } else {
                a->y--;
            }
        }
    }

	void procesarPerforar(arounder *a)
    {
        const int frames[2] = {0,1};
        a->frame++;
        if (a->frame == 2) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = 8;

        if (blockCaure(a)) {
            initCaure(a);
        } else {
            if (a->frame == 1) {
                doPerforar(a);
                a->y++;
            }
        }
    }

	void procesarEscalera(arounder *a)
    {
        const int frames[5] = {12,13,14,15,4};
        a->frame++;
        if (a->frame == 5) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (blockParet(a) || blockTecho(a) || mapa::accions::escalera == 0) {
            initCaminar(a);
        } else {
            if (a->frame == 3) {
                doEscalera(a);
                mapa::accions::escalera--;
            }
            if (a->frame == 4) {
                a->y--;
                if (a->orientacio == arounders::orientacions::dreta) {
                    a->x++;
                } else {
                    a->x--;
                }
            }
        }
    }

	void procesarPasarela(arounder *a)
    {
        const int frames[5] = {12,13,14,15,4};
        a->frame++;
        if (a->frame == 5) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (blockParet(a) || !blockPrecipiciPasarela(a) || mapa::accions::pasarela == 0) {
            initCaminar(a);
        } else {
            if (a->frame == 3) {
                doEscalera(a, 1);
                mapa::accions::pasarela--;
            }
            if (a->frame == 4) {
                if (a->orientacio == arounders::orientacions::dreta) {
                    a->x = a->x + 2;
                } else {
                    a->x = a->x - 2;
                }
            }
        }
    }

	void procesarCorda(arounder *a)
    {
        const int frames[4] = {12,13,14,15};
        if (a->frame < 3) a->frame++;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (a->frame == 3 ) {
            if (!blockNovaCorda(a)) {
                initCaminar(a);
            } else {
                doCorda(a);
                a->altura++;
            }
        }
    }

	void procesarPujarCorda(arounder *a)
    {
        const int frames[2] = {9,10};
        a->frame++;
        if (a->frame == 2) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = a->orientacio;

        if (!blockCordaPujar(a, 3)) {
            a->y = a->y - 2;
            initCaminar(a);
        } else {
            if (blockTecho(a, 3)) {
                if (a->orientacio == arounders::orientacions::dreta) {
                    a->x = a->x - 3;
                } else {
                    a->x = a->x + 3;
                }
                initCaminar(a);
            } else {
                a->y--;
            }
        }
    }

	void procesarBaixarCorda(arounder *a)
    {
        const int frames[2] = {9,10};
        a->frame++;
        if (a->frame == 2) a->frame = 0;
        a->frameX = frames[a->frame];
        a->frameY = arounders::orientacions::esquerra - a->orientacio;

        if (!blockCordaBaixar(a, 2)) {
            initCaminar(a);
        } else {
            if (!blockCaure(a, 3)) {
                if (a->orientacio == arounders::orientacions::dreta) {
                    a->x = a->x - 2;
                } else {
                    a->x = a->x + 2;
                }
                initCaminar(a);
            } else {
                a->y++;
            }
        }
    }

	void procesarSuicidi(arounder *a)
    {
        const int frames[5] = {0,1,2,1,2};
        a->frameX = frames[a->frame];
        a->frameY = 0;

        if (a->frame == 4) initMort(a);
        a->frame++;
    }

	bool blockCaure(arounder *a, int desfase)
    {
        if ( a->orientacio == arounders::orientacions::esquerra) desfase = -desfase;
        return ((get_pixel(a->x+desfase  , a->y+8) == 0 || get_pixel(a->x+desfase  , a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+1, a->y+8) == 0 || get_pixel(a->x+desfase+1, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+2, a->y+8) == 0 || get_pixel(a->x+desfase+2, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+3, a->y+8) == 0 || get_pixel(a->x+desfase+3, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+4, a->y+8) == 0 || get_pixel(a->x+desfase+4, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+5, a->y+8) == 0 || get_pixel(a->x+desfase+5, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+6, a->y+8) == 0 || get_pixel(a->x+desfase+6, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase+7, a->y+8) == 0 || get_pixel(a->x+desfase+7, a->y+8) == colorCorda) &&
                (get_pixel(a->x+desfase  , a->y+9) == 0 || get_pixel(a->x+desfase  , a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+1, a->y+9) == 0 || get_pixel(a->x+desfase+1, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+2, a->y+9) == 0 || get_pixel(a->x+desfase+2, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+3, a->y+9) == 0 || get_pixel(a->x+desfase+3, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+4, a->y+9) == 0 || get_pixel(a->x+desfase+4, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+5, a->y+9) == 0 || get_pixel(a->x+desfase+5, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+6, a->y+9) == 0 || get_pixel(a->x+desfase+6, a->y+9) == colorCorda) &&
                (get_pixel(a->x+desfase+7, a->y+9) == 0 || get_pixel(a->x+desfase+7, a->y+9) == colorCorda)
            );
    }

	bool blockCaminar(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+8, a->y+6) != 0 && get_pixel(a->x+8, a->y+7) != 0 && get_pixel(a->x+8, a->y+6) != colorEscalo);
        } else {
            return (get_pixel(a->x-1, a->y+6) != 0 && get_pixel(a->x-1, a->y+7) != 0 && get_pixel(a->x-1, a->y+6) != colorEscalo);
        }
    }

	bool blockArounder(arounder *a)
    {
        bool resultado = false;
        if (a->anterior) resultado = checkArounderAnt(a->anterior, a->x, a->y, a->orientacio);
        if (a->siguiente) resultado = resultado || checkArounderSig(a->siguiente, a->x, a->y, a->orientacio);

        return resultado;
    }

	bool blockParet(arounder *a, int desfase)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+8-desfase, a->y  ) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+1) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+2) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+3) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+4) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+5) != 0 ||
                    get_pixel(a->x+8-desfase, a->y+6) != 0// ||
                    //get_pixel(X+8-desfase, Y+7) != 0
                );
        } else {
            return (get_pixel(a->x-1+desfase, a->y  ) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+1) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+2) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+3) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+4) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+5) != 0 ||
                    get_pixel(a->x-1+desfase, a->y+6) != 0// ||
                    //get_pixel(X-1+desfase, Y+7) != 0
                );
        }
    }

	bool blockTecho(arounder *a, int desfase)
    {
        if (a->orientacio == arounders::orientacions::dreta) desfase = -desfase;

        return ((get_pixel(a->x+desfase  , a->y-1) != 0 && get_pixel(a->x+desfase  , a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+1, a->y-1) != 0 && get_pixel(a->x+desfase+1, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+2, a->y-1) != 0 && get_pixel(a->x+desfase+2, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+3, a->y-1) != 0 && get_pixel(a->x+desfase+3, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+4, a->y-1) != 0 && get_pixel(a->x+desfase+4, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+5, a->y-1) != 0 && get_pixel(a->x+desfase+5, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+6, a->y-1) != 0 && get_pixel(a->x+desfase+6, a->y-1) != colorCorda) ||
                (get_pixel(a->x+desfase+7, a->y-1) != 0 && get_pixel(a->x+desfase+7, a->y-1) != colorCorda)
            );
    }

	bool blockPrecipici(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+7, a->y+8) == 0 &&
                    get_pixel(a->x+6, a->y+8) == 0 &&
                    get_pixel(a->x+5, a->y+8) == 0 &&
                    get_pixel(a->x+7, a->y+9) == 0 &&
                    get_pixel(a->x+6, a->y+9) == 0 &&
                    get_pixel(a->x+5, a->y+9) == 0
                );
        } else {
            return (get_pixel(a->x  , a->y+8) == 0 &&
                    get_pixel(a->x+1, a->y+8) == 0 &&
                    get_pixel(a->x+2, a->y+8) == 0 &&
                    get_pixel(a->x  , a->y+9) == 0 &&
                    get_pixel(a->x+1, a->y+9) == 0 &&
                    get_pixel(a->x+2, a->y+9) == 0
                );
        }
    }

	bool blockPrecipiciPasarela(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return ((get_pixel(a->x+7, a->y+8) == 0 || get_pixel(a->x+7, a->y+8) == colorEscalo) &&
                    (get_pixel(a->x+6, a->y+8) == 0 || get_pixel(a->x+6, a->y+8) == colorEscalo) &&
                    (get_pixel(a->x+5, a->y+8) == 0 || get_pixel(a->x+5, a->y+8) == colorEscalo) &&
                    (get_pixel(a->x+7, a->y+9) == 0 || get_pixel(a->x+7, a->y+9) == colorEscalo) &&
                    (get_pixel(a->x+6, a->y+9) == 0 || get_pixel(a->x+6, a->y+9) == colorEscalo) &&
                    (get_pixel(a->x+5, a->y+9) == 0 || get_pixel(a->x+5, a->y+9) == colorEscalo)
                );
        } else {
            return ((get_pixel(a->x  , a->y+8) == 0 || get_pixel(a->x  , a->y+8) == colorEscalo) &&
                    (get_pixel(a->x+1, a->y+8) == 0 || get_pixel(a->x+1, a->y+8) == colorEscalo) &&
                    (get_pixel(a->x+2, a->y+8) == 0 || get_pixel(a->x+2, a->y+8) == colorEscalo) &&
                    (get_pixel(a->x  , a->y+9) == 0 || get_pixel(a->x  , a->y+9) == colorEscalo) &&
                    (get_pixel(a->x+1, a->y+9) == 0 || get_pixel(a->x+1, a->y+9) == colorEscalo) &&
                    (get_pixel(a->x+2, a->y+9) == 0 || get_pixel(a->x+2, a->y+9) == colorEscalo)
                );
        }
    }

	bool blockNovaCorda(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+6, a->y+8+a->altura) == 0 &&
                    get_pixel(a->x+6, a->y+9+a->altura) == 0 &&
                    get_pixel(a->x+6, a->y+10+a->altura) == 0
                );
        } else {
            return (get_pixel(a->x+1, a->y+8+a->altura) == 0 &&
                    get_pixel(a->x+1, a->y+9+a->altura) == 0 &&
                    get_pixel(a->x+1, a->y+10+a->altura) == 0
                );
        }
    }

	bool blockCordaBaixar(arounder *a, int desfase)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+6-desfase, a->y+8) == colorCorda);
        } else {
            return (get_pixel(a->x+1+desfase, a->y+8) == colorCorda);
        }
    }

	bool blockCordaPujar(arounder *a, int desfase)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return (get_pixel(a->x+6-desfase, a->y+5) == colorCorda);
        } else {
            return (get_pixel(a->x+1+desfase, a->y+5) == colorCorda);
        }
    }

	bool pujarEscalo(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            return ( (get_pixel(a->x+8, a->y+6) == 0 || get_pixel(a->x+8, a->y+6) == colorEscalo) && get_pixel(a->x+8, a->y+7) != 0);
        } else {
            return ( (get_pixel(a->x-1, a->y+6) == 0 || get_pixel(a->x-1, a->y+6) == colorEscalo) && get_pixel(a->x-1, a->y+7) != 0);
        }
    }

	bool baixarEscalo(arounder *a)
    {
        return (get_pixel(a->x  , a->y+8) == 0 &&
                get_pixel(a->x+1, a->y+8) == 0 &&
                get_pixel(a->x+2, a->y+8) == 0 &&
                get_pixel(a->x+3, a->y+8) == 0 &&
                get_pixel(a->x+4, a->y+8) == 0 &&
                get_pixel(a->x+5, a->y+8) == 0 &&
                get_pixel(a->x+6, a->y+8) == 0 &&
                get_pixel(a->x+7, a->y+8) == 0 &&

               (get_pixel(a->x  , a->y+9) != 0 ||
                get_pixel(a->x+1, a->y+9) != 0 ||
                get_pixel(a->x+2, a->y+9) != 0 ||
                get_pixel(a->x+3, a->y+9) != 0 ||
                get_pixel(a->x+4, a->y+9) != 0 ||
                get_pixel(a->x+5, a->y+9) != 0 ||
                get_pixel(a->x+6, a->y+9) != 0 ||
                get_pixel(a->x+7, a->y+9) != 0
                )
            );
    }


	bool checkArounderAnt(arounder *a, int x, int y, int o)
    {
        if ( a->accio == arounders::accions::parar && (y >= a->y-8) && (y <= a->y+8) && ( (o == arounders::orientacions::dreta && a->x == x+8) || (o == arounders::orientacions::esquerra && a->x == x-8) ) ) {
            return true;
        } else {
            if (a->anterior) {
                return checkArounderAnt(a->anterior, x, y, o);
            } else {
                return false;
            }
        }
    }

	bool checkArounderSig(arounder *a, int x, int y, int o)
    {
        if ( a->accio == arounders::accions::parar && (y >= a->y-8) && (y <= a->y+8) && ( (o == arounders::orientacions::dreta && a->x == x+8) || (o == arounders::orientacions::esquerra && a->x == x-8) ) ) {
            return true;
        } else {
            if (a->siguiente) {
                return checkArounderSig(a->siguiente, x, y, o);
            } else {
                return false;
            }
        }
    }

	void doCavar(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            explosio::crear(a->x+8, a->y, 10, 200, 10, 3);
            put_pixel(a->x+8, a->y, 0);
            put_pixel(a->x+8, a->y+1, 0);
            put_pixel(a->x+8, a->y+2, 0);
            put_pixel(a->x+8, a->y+3, 0);
            put_pixel(a->x+8, a->y+4, 0);
            put_pixel(a->x+8, a->y+5, 0);
            put_pixel(a->x+8, a->y+6, 0);
            put_pixel(a->x+8, a->y+7, 0);
        } else {
            explosio::crear(a->x-1, a->y, 10, 200, 10, 3);
            put_pixel(a->x-1, a->y, 0);
            put_pixel(a->x-1, a->y+1, 0);
            put_pixel(a->x-1, a->y+2, 0);
            put_pixel(a->x-1, a->y+3, 0);
            put_pixel(a->x-1, a->y+4, 0);
            put_pixel(a->x-1, a->y+5, 0);
            put_pixel(a->x-1, a->y+6, 0);
            put_pixel(a->x-1, a->y+7, 0);
        }

    }

	void doPerforar(arounder *a)
    {
        explosio::crear(a->x+4, a->y+8, 10, 200, 10, 3);
        put_pixel(a->x  , a->y+8, 0);
        put_pixel(a->x+1, a->y+8, 0);
        put_pixel(a->x+2, a->y+8, 0);
        put_pixel(a->x+3, a->y+8, 0);
        put_pixel(a->x+4, a->y+8, 0);
        put_pixel(a->x+5, a->y+8, 0);
        put_pixel(a->x+6, a->y+8, 0);
        put_pixel(a->x+7, a->y+8, 0);
    }

	void doEscalera(arounder *a, int desfase)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            put_pixel(a->x+5, a->y+7+desfase, colorEscalo);
            put_pixel(a->x+6, a->y+7+desfase, colorEscalo);
            put_pixel(a->x+7, a->y+7+desfase, colorEscalo);
        } else {
            put_pixel(a->x+2, a->y+7+desfase, colorEscalo);
            put_pixel(a->x+1, a->y+7+desfase, colorEscalo);
            put_pixel(a->x  , a->y+7+desfase, colorEscalo);
        }
    }

	void doCorda(arounder *a)
    {
        if (a->orientacio == arounders::orientacions::dreta) {
            put_pixel(a->x+6, a->y+8+a->altura, colorCorda);
        } else {
            put_pixel(a->x+1, a->y+8+a->altura, colorCorda);
        }
    }


}
