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

#include <math.h>

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

void Displace::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);
//    const float blurval = (0.5f+0.5f*cosf(pos*19))*0.01f;
//    filter.blur(5, blurval, blurval);//
//    filter.glow(5, 0.007f, 0.007f, 0.89f, -1.0f, 1.0f);
}

void Displace::renderScene(float pos, float alpha)
{
    int i;
/*
    Vector cam = Vector(0, 0, 11);
    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);
*/
    cam->useCamera(0);
    glRotatef(70+pos*860 , 0.4f, 0.8f, 1.0f);

    int facecount = object->getFaceCount();
    Vector *vertices = object->getVertices();
    Vector *normals = object->getNormals();

    Face *faces = object->getFaces();
    TexCoord *uv = object->getUV();
    
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);
    glColor4f(1,1,1,1);
    
    //texture0 = texture
	glActiveTextureARB(GL_TEXTURE0_ARB);
    glBindTexture(GL_TEXTURE_2D, dmsGetTexture("maasto.jpg")->getID());

    //texture1 = displace
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, dmsGetTexture("49.jpg")->getID());
/*
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);	
*/
	shaders.displace->bind();
	shaders.displace->setUniform1i("texunit0", 0);  
	shaders.displace->setUniform1i("texunit1", 1);  
    shaders.displace->setUniform1f("displace_amount", 0.3f+0.1f*cosf(pos*18));
    shaders.displace->setUniform1f("alpha", 1.0f);

    int count = (int)(facecount*alpha);
    glBegin(GL_TRIANGLES);

    const float dispX = pos*3;
    const float dispY = pos*2;

    for (i=0;i<count;i++)
    {
        Face &f = faces[i];
        Vector &v1 = vertices[faces[i].v1];
        Vector &v2 = vertices[faces[i].v2];
        Vector &v3 = vertices[faces[i].v3];

        TexCoord uv1 = uv[faces[i].v1];
        TexCoord uv2 = uv[faces[i].v2];
        TexCoord uv3 = uv[faces[i].v3];

        const float texscale = 2.0f;
        uv1.u *= texscale;
        uv1.v *= texscale;
        uv2.u *= texscale;
        uv2.v *= texscale;
        uv3.u *= texscale;
        uv3.v *= texscale;

        Vector &n1 = normals[faces[i].v1];
        Vector &n2 = normals[faces[i].v2];
        Vector &n3 = normals[faces[i].v3];

        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, uv1.u, uv1.v);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, uv1.u + dispX, uv1.v + dispY);
        glNormal3fv((float *)&n1);
        glVertex3fv((float *)&v1);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, uv2.u, uv2.v);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, uv2.u + dispX, uv2.v + dispY);
        glNormal3fv((float *)&n2);
        glVertex3fv((float *)&v2);
        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, uv3.u, uv3.v);
        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, uv3.u + dispX, uv3.v + dispY);
        glNormal3fv((float *)&n3);
        glVertex3fv((float *)&v3);
    }
    glEnd();

    shaders.unbind();

	glActiveTextureARB(GL_TEXTURE1_ARB);
//	glDisable(GL_TEXTURE_GEN_S);
//	glDisable(GL_TEXTURE_GEN_T);	
    glDisable(GL_TEXTURE_2D);

    glActiveTextureARB(GL_TEXTURE0_ARB);
    glDisable(GL_TEXTURE_2D);

}




Displace::Displace()
{	
    object = new Mesh();
//    object->buildSphere(1.35f, 64, 64,1.0f);
    object->buildTorus(3, 0.87f, 64, 64);
}

Displace::~Displace()
{
	// kaataa!?
//	object->destroy();
//	delete object;
}


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

