

#include <math.h>

#include "Split.hpp"
#include "../mathematics.hpp"
#include "../primitives.hpp"

#ifdef _DEBUG
	#include <stdlib.h>
	#include "../mmgr.h"
#endif

void Split::draw()
{
	const float pos = (time - startTime) / (endTime - startTime);
	float alpha = 1.0f;

	const float fadeinstart = 0.0f;
	const float fadeinstop = 0.1f;
	const float fadeoutstart = 0.90f;
	const float fadeoutstop = 1.0f;

	if (pos >= fadeinstart && pos <= fadeinstop)
		alpha *= (pos-fadeinstart) / (fadeinstop-fadeinstart);
	if (pos >= fadeoutstart && pos <= fadeoutstop)
		alpha *= 1-(pos-fadeoutstart) / (fadeoutstop-fadeoutstart);

//    filter.init(true);
	renderScene(pos, alpha);
//    filter.glow(8, 0.005f, 0.005f, 0.92f, -1.0f, 1.0f);
}

void Split::renderScene(float pos, float alpha)
{
    Vector cam = Vector(0, 0, -7);
    Vector tgt = Vector(0, 0, 0);
    Vector upw = Vector(0, 1, 0);

    glLoadIdentity();
    gluLookAt(cam.x, cam.y, cam.z, tgt.x, tgt.y, tgt.z, upw.x, upw.y, upw.z);

    int count = drawlist.size();
    vector<SplitSquare*>::iterator it;

    glDisable(GL_DEPTH_TEST); 
    glDisable(GL_TEXTURE_2D);
    for (it = drawlist.begin(); it < drawlist.end(); it++)
    {
        SplitSquare *s = *it;
        glColor3fv((float *)&s->color);
        glDisable(GL_BLEND);
        glBegin(GL_QUADS);
        glVertex3fv((float *)&s->v1);
        glVertex3fv((float *)&s->v2);
        glVertex3fv((float *)&s->v3);
        glVertex3fv((float *)&s->v4);
        glEnd();
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA,GL_ONE);
        glColor4f(1,1,1,0.8f);
        glBegin(GL_LINE_LOOP);
        glVertex3fv((float *)&s->v1);
        glVertex3fv((float *)&s->v2);
        glVertex3fv((float *)&s->v3);
        glVertex3fv((float *)&s->v4);
        glEnd();


    }



}


void Split::divide(SplitSquare *s, int generation)
{
    if (generation > 66)
    {
        return;
    }

    bool pysty = ((rand()%2)==0)?true:false;

    float t = 0.1f;//+0.15f*Mathematics::randFloat();
    float wobble = 0.1f*(Mathematics::randFloat()-0.5f);
    float wobble_a = 0.0f;
    float wobble_b = 0.0f;

    if (pysty)
    {
        Vector n1 = s->v1 * (1-(t-wobble*wobble_a)) + s->v2*(t+wobble*wobble_b);
        Vector n2 = s->v4 * (1-(t-0.05f-wobble*wobble_a)) + s->v3*(t-0.05f+wobble*wobble_b);

        /*
            v1_____n1______v2
            |     |       |
            |     |       |
            |     |       | 
            |    t|       |
            |     |       |
            |     |       |
            |     |       |
            |v4___|n2_____|v3


        */

        if (t > 0.5f) //piirtolistaan menee oikea puoli ja divisioon vasen
        {
            SplitSquare *rekursio = new SplitSquare();
            SplitSquare *piirto = new SplitSquare();
            
            rekursio->v1 = s->v1;
            rekursio->v2 = n1;
            rekursio->v3 = n2;
            rekursio->v4 = s->v4;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());

            piirto->v1 = n1;
            piirto->v2 = s->v2;
            piirto->v3 = s->v3;
            piirto->v4 = n2;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());
            drawlist.push_back(piirto);

            divide(rekursio, generation + 1);
        }
        else //piirtolistaan vasen puoli ja divisioon oikea
        {
            SplitSquare *rekursio = new SplitSquare();
            SplitSquare *piirto = new SplitSquare();

            rekursio->v1 = n1;
            rekursio->v2 = s->v2;
            rekursio->v3 = s->v3; 
            rekursio->v4 = n2;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());
            
            piirto->v1 = s->v1;
            piirto->v2 = n1;
            piirto->v3 = n2;
            piirto->v4 = s->v4;
            piirto->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());

//            drawlist.push_back(piirto);

            divide(rekursio, generation + 1);
        }
    }
    else
    {
        Vector n1 = s->v1 * (1-(t+0.04f-wobble*wobble_a)) + s->v4*(t+0.04f+wobble*wobble_b);
        Vector n2 = s->v2 * (1-(t-wobble*wobble_a)) + s->v3*(t+wobble*wobble_b);

        /*
            v1_____________v2
             |             |
             |             |
            n1_____t_______|n2
             |             |
             |             |
             |             |
             |             |
             |             |
            v4_____________|v3

        */
        if (t > 0.5f) //piirtolistaan menee alapuoli ja divisioon ylä
        {
            SplitSquare *rekursio = new SplitSquare();
            SplitSquare *piirto = new SplitSquare();
            
            rekursio->v1 = s->v1;
            rekursio->v2 = s->v2;
            rekursio->v3 = n2;
            rekursio->v4 = n1;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());

            piirto->v1 = n1;
            piirto->v2 = n2;
            piirto->v3 = s->v3;
            piirto->v4 = s->v4;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());
            drawlist.push_back(piirto);

            divide(rekursio, generation + 1);
        }
        else //piirtolistaan yläpuoli ja divisioon ala
        {
            SplitSquare *rekursio = new SplitSquare();
            SplitSquare *piirto = new SplitSquare();

            rekursio->v1 = n1;
            rekursio->v2 = n2;
            rekursio->v3 = s->v3; 
            rekursio->v4 = s->v4;
            rekursio->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());
            
            piirto->v1 = s->v1;
            piirto->v2 = s->v2;
            piirto->v3 = n2;
            piirto->v4 = n1;
            piirto->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());

            drawlist.push_back(piirto);

            divide(rekursio, generation + 1);
        }
    }







}


Split::Split()
{
    float size = 2.0f;

    srand(timeGetTime());
    SplitSquare *s = new SplitSquare();
    s->v1 = Vector(-size, -size, 0);
    s->v2 = Vector( size, -size, 0);
    s->v3 = Vector( size,  size, 0);
    s->v4 = Vector(-size,  size, 0);
    s->color = Vector(Mathematics::randFloat(), Mathematics::randFloat(), Mathematics::randFloat());
    
    drawlist.push_back(s);

    divide(s, 0);
}

Split::~Split()
{
}


bool Split::init(unsigned long s, unsigned long e)
{
	startTime = s;
	endTime = e;
	return true;
}

