#include "sceneprimitive.h"
#include "algorithm"


int ScenePrimitive::quaderCount = 1;
int ScenePrimitive::sphereCount = 1;
int ScenePrimitive::cylinderCount = 1;
int ScenePrimitive::torusCount = 1;
int ScenePrimitive::coneCount = 1;


ScenePrimitive::ScenePrimitive(PrimitiveType type, int tesselation)
    :SceneObject()
{
    this->type = type;
    this->tesselation = tesselation;

    qobj = gluNewQuadric();
    gluQuadricNormals(qobj, GLU_SMOOTH);

    this->color = new float[3];
    this->color[0] = 0.0;
    this->color[1] = 0.0;
    this->color[2] = 0.0;

    switch (this->type) {
    case Quader:
         name = QString("Quader %1").arg(ScenePrimitive::quaderCount);
         ScenePrimitive::quaderCount++;
         this->tesselation = pow(2,tesselation);
        break;
    case Sphere:
        name = QString("Sphere %1").arg(ScenePrimitive::sphereCount);
        ScenePrimitive::sphereCount++;
        this->tesselation = 5*pow(2,tesselation);
        break;
    case Cylinder:
        name = QString("Cylinder %1").arg(ScenePrimitive::cylinderCount);
        ScenePrimitive::cylinderCount++;
        this->tesselation = 5*pow(2,tesselation);
        break;
    case Torus:
        name = QString("Torus %1").arg(ScenePrimitive::torusCount);
        ScenePrimitive::torusCount++;
        this->tesselation = 5*pow(2,tesselation);
        break;
    case Cone:
        name = QString("Cone %1").arg(ScenePrimitive::coneCount);
        ScenePrimitive::coneCount++;
        this->tesselation = 5*pow(2,tesselation);
        break;
    default:
        qDebug()<<"Enum Error";
        break;
    }
 //   qDebug()<<"Tesselation"<<this->tesselation<<getName();
}

void ScenePrimitive::draw(QGLShaderProgram *shader){
    shader->setAttributeValue(4,getID());
    glPushMatrix();
    applyTransformation();
//    qDebug()<<this->getName()<<"Matrial"<<*color<<"Trans"<<translation<<"Rot"<<rotation;
    glMaterialfv(GL_FRONT,GL_AMBIENT,color);
    GLfloat white[] = {1.0,1.0,1.0};
    glMaterialfv(GL_FRONT,GL_DIFFUSE,color);
    glMaterialfv(GL_FRONT,GL_SPECULAR,white);

    GLfloat mShininess[] = {128};
    glMaterialfv(GL_FRONT,GL_SHININESS,mShininess);

    int radius = 1;

    switch (this->type) {
    case Quader:
        drawCube(tesselation);
        break;
    case Sphere:
        gluSphere(qobj,1,tesselation,tesselation);
        break;
    case Cylinder:

        gluCylinder(qobj,radius,radius,3,tesselation,tesselation);
        gluQuadricOrientation(qobj,GLU_INSIDE);
        gluDisk( qobj, 0.0, radius, tesselation, 1);
        glTranslatef(0,0,3);
        gluQuadricOrientation(qobj,GLU_OUTSIDE);
        gluDisk( qobj, 0.0 , radius, tesselation, 1);
        break;
    case Cone:
        gluQuadricOrientation(qobj,GLU_OUTSIDE);
        gluCylinder(qobj,radius,0,3,tesselation,tesselation);
        gluQuadricOrientation(qobj,GLU_INSIDE);
        gluDisk( qobj, 0.0, radius, tesselation, 1);
        break;
    case Torus:
        glutSolidTorus(1, 2, tesselation, tesselation);
        break;
    default:
        qDebug()<<"Enum Error";
        break;
    }


    glPopMatrix();
}

void ScenePrimitive::setMaterial(float *color )
{


    this->color = new float[3];
    this->color[0] = color[0];
    this->color[1] = color[1];
    this->color[2] = color[2];
   // qDebug()<< *this->color<<" "<<this->color[0]<<" "<<this->color[1]<<" "<<this->color[2];

}


void ScenePrimitive::drawCube(int tesselation)
{
    float increment = 1.0/tesselation;

    glBegin(GL_QUADS);
    glNormal3f(0,1,0);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( x+increment, 0.5f,y);
            glVertex3f(x, 0.5f,y);
            glVertex3f(x, 0.5f, y+increment);
            glVertex3f( x+increment, 0.5f, y+increment);
        }
    }
    glEnd();

    glBegin(GL_QUADS);
    glNormal3f(0,-1,0);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( x+increment, -0.5f,y+increment);
            glVertex3f(x, -0.5f,y+increment);
            glVertex3f(x, -0.5f, y);
            glVertex3f( x+increment, -0.5f, y);
        }
    }
    glEnd();

    glBegin(GL_QUADS);
    glNormal3f(0,0,1);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( x+increment,y+increment, 0.5f);
            glVertex3f(x, y+increment, 0.5f);
            glVertex3f(x,  y, 0.5f);
            glVertex3f( x+increment, y, 0.5f);
        }
    }
    glEnd();

    glBegin(GL_QUADS);
    glNormal3f(0,0,-1);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( x+increment,y, -0.5f);
            glVertex3f(x, y,-0.5f);
            glVertex3f(x, y+increment,-0.5f);
            glVertex3f( x+increment,y+increment, -0.5f);
        }
    }
    glEnd();

    glBegin(GL_QUADS);
    glNormal3f(-1,0,0);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( -0.5f, x+increment,y+increment);
            glVertex3f( -0.5f,x+increment,y);
            glVertex3f( -0.5f,x, y);
            glVertex3f(  -0.5f,x, y+increment);
        }
    }
    glEnd();

    glBegin(GL_QUADS);
    glNormal3f(1,0,0);
    for (float x = -0.5; x < 0.5 ; x+= increment) {
        for (float y = -0.5; y < 0.5 ; y+= increment ) {
            glVertex3f( 0.5f, x+increment,y);
            glVertex3f( 0.5f,x+increment,y+increment);
            glVertex3f( 0.5f,x, y+increment);
            glVertex3f(  0.5f,x, y);
        }
    }
    glEnd();
}

