#include "poly2d.h"
#include "math.h"
#include "stdio.h"
#include "iostream"
#include "glness.h"


extern float crossz(vector2d a, vector2d b);
list<wallrangeT>::iterator rangei;//WARNING!! this is prob actauly fine, but it should probably *not* be shared!

//list<wallrangeT>::iterator c1,c2;
wallrangeT walladd;
void lc::checkagainst(lc& other) {
    if (l == other.l) {
        alone = 0;
        other.alone = 0;
        /*c1 = range.begin();
        c2 = other.range.begin();
        if(range.size() == 1 && other.range.size() == 1 && c1->low == c2->low && c1-> high == c2->high) {
            cout << "MATCH!" << endl;
            range.clear();
            other.range.clear();
        }else {
        }*/
        if(low >= other.low && high >= other.high) {
            walladd.low = other.high;
            walladd.high = high;
            range.push_back(walladd);
        }
        if(low <= other.low && high <= other.high) {
            walladd.low = low;
            walladd.high = other.low;
            range.push_back(walladd);
        }
        if(low <= other.low && high >= other.high) {
            walladd.low = low;
            walladd.high = other.low;
            range.push_back(walladd);
            walladd.low = other.high;
            walladd.high = high;
            range.push_back(walladd);
        }
    }
}

int poly2d::pnpoly(float x, float y) {
    int i, j, c = 0;
    for (i = 0; i < lnum; i++) {
        if ((((l[i].l->p1->y <= y) && (y < l[i].l->p2->y)) ||
                ((l[i].l->p2->y <= y) && (y < l[i].l->p1->y))) &&
                (x < (l[i].l->p2->x - l[i].l->p1->x) * (y - l[i].l->p1->y) / (l[i].l->p2->y - l[i].l->p1->y) + l[i].l->p1->x))
            c = !c;
    }
    return c;
}

float newfloor;
void poly2d::docolfloor(physpoint& player, bool& onground) {
    newfloor=floor+0.25;//TODO scaleme
    if(pnpoly(player.c.x, player.c.y)) {
        if(player.c.z < newfloor && player.o.z >= floor ){
            player.c.z = newfloor;
            onground = 1;
        }
            //onground = 1;
    }
    for (int lid = 0; lid <lnum;lid++) {
        if(l[lid].l->docol(player, l[lid].flipped, newfloor))
            onground = 1;
    }
}

void poly2d::docolwall(physpoint& player, bool& onground) {
    for (int lid = 0; lid <lnum;lid++) {
        for (rangei = l[lid].range.begin(); rangei != l[lid].range.end();rangei++) {
            if(player.c.z > rangei->low && player.c.z < rangei->high)
                if(l[lid].l->docol(player, l[lid].flipped));//onground = 1;//uncomment this for wall jumping
        }
    }
}


void poly2d::sortflipped() {
    for (int lid = 0; lid <lnum;lid++) {
        float ztest = crossz(*l[lid].l->p2 - *l[lid].l->p1, centre - *l[lid].l->p1);
        //cout << ztest << endl;
        if (ztest < 0) {
            l[lid].flipped = 0;
        }
        else {
            l[lid].flipped = 1;
        }
    }
}


void poly2d::getcentre() {
    for (int lid = 0; lid <lnum;lid++) {
        centre += *l[lid].l->p1;
        centre += *l[lid].l->p2;
    }
    centre.divf(lnum*2);

    furthestpointdist = 0;
    vector2d dist;
    for (int lid = 0; lid <lnum;lid++) {
        dist = centre - *l[lid].l->p1;
        if (dist.magsqr() > furthestpointdist)
            furthestpointdist = dist.magsqr();
        dist = centre - *l[lid].l->p2;
        if (dist.magsqr() > furthestpointdist)
            furthestpointdist = dist.magsqr();
    }
}

float dx,dy,dx2,dy2;
void poly2d::draw()//TODO fix this
{
    if(floortex != -1) {
        glBindTexture( GL_TEXTURE_2D, floortex );
        glBegin(GL_POLYGON);
        for(int i = lnum-1; i > -1; i--) {
            if (!l[i].flipped) {
                dx = l[i].l->p1->x;
                dy = l[i].l->p1->y;
            }
            else {
                dx = l[i].l->p2->x;
                dy = l[i].l->p2->y;
            }
            glTexCoord2f(dx/5, dy/5);//TODO scaleme
            glVertex3f( dx, dy, floor);
        }
        glEnd();
    }

    if(rooftex != -1) {
        glBindTexture( GL_TEXTURE_2D, rooftex );
        glBegin(GL_POLYGON);
        for(int i = 0; i < lnum; i++) {
            if (!l[i].flipped) {
                dx = l[i].l->p1->x;
                dy = l[i].l->p1->y;
            }
            else {
                dx = l[i].l->p2->x;
                dy = l[i].l->p2->y;
            }
            glTexCoord2f(dx/5, dy/5);//TODO scaleme
            glVertex3f( dx, dy, roof);
        }
        glEnd();
    }

    /*for(int i = 0; i < lnum; i++) {
    for(int i = 0; i < lnum; i++) {
        dx = l[i].l->p1->x;
        dy = l[i].l->p1->y;
        glTexCoord2f(dx/100, dy/100);
        glVertex3f( dx, dy, roof);
    }
    }*/

    for(int i = 0; i < lnum; i++) {
        if(l[i].ltexid != -1) {
            glBindTexture( GL_TEXTURE_2D, l[i].ltexid );

            for(rangei = l[i].range.begin();rangei != l[i].range.end();rangei++) {
                if (!l[i].flipped) {
                    dx = l[i].l->p1->x;
                    dy = l[i].l->p1->y;
                    dx2 = l[i].l->p2->x;
                    dy2 = l[i].l->p2->y;
                }
                else {
                    dx2 = l[i].l->p1->x;
                    dy2 = l[i].l->p1->y;
                    dx = l[i].l->p2->x;
                    dy = l[i].l->p2->y;
                }
                glBegin(GL_QUADS);
                glTexCoord2f(0.0f, 1);
                glVertex3f( dx, dy, rangei->low);
                glTexCoord2f(l[i].l->len/5,1);//TODO scaleme
                glVertex3f( dx2, dy2, rangei->low);
                glTexCoord2f(l[i].l->len/5, 0.0f);//TODO scaleme
                glVertex3f( dx2, dy2, rangei->high);
                glTexCoord2f(0, 0.0f);
                glVertex3f( dx, dy, rangei->high);
                glEnd();
            }
        }
    }

}
