#ifndef ESCENA_H
#define ESCENA_H

#define GL_GLEXT_PROTOTYPES 1

#include <stdio.h>
#include <Common.h>
#include <QGLShaderProgram>

#include <cmath>
#include <iostream>
#include <stdlib.h>

#include <QtOpenGL>
#include <QGLWidget>
#include <QtGui>

#include <list>
#include <vector>
#include <string>

#include <camera.h>
#include <objecte.h>
#include <cub.h>
#include <llum.h>
#include <volumen.h>
#include <lut.h>
#include <gpu.h>

using namespace std;

class Escena : public QGLWidget
{
    Q_OBJECT

public:

    Escena();
    ~Escena();

    Camera getCamera();
    Capsa3D getCapsaMinima();
    Llum* getLlum();
    volumen* getVolum();

    int xRotation();
    int yRotation();
    int zRotation();

    void refresh();
    void guardar();
    void initializeGL();
    void setLut(const char *nombreFichero);
    void setVolumen(const char *nombreFichero, int anchura, int altura, int profundidad, QString tipoUnsigned);
    void addVolumen(volumen *v);

    void CalculCamera(bool retallat, bool centrat);
    void CapsaMinCont3DEscena();
    void CameraToGL();
    void setRayCastingFlag(int mode);
    void startRaycasting();

    void setOpacitat(float op);
    void setSaturacio(float sat);
    void setCrem(float sat);
    void setSampling(float samp);
    void setGamma(float gamma);
    void setColorMode(int mode);
    void setGPU(GPU* gpu);

    void setOneStepRaycastingMode(bool mode);
    void setMipMode(bool mode);

    void setRampColorTable(QVector<unsigned int> qrgbcolors);
    void setInitialLUT(QVector<unsigned int> qrgbcolors);

    void eliminaCub();

    static const int NumVerticesCUB = 4*6; //4 vertex * 6 cares
    vec3 tex_coords3D[NumVerticesCUB];
    int Index;

    void cargarVolumen(char* fitxer,float anch, float alt,float profu,QString tipoUns);
    void setLoadedLUT();
    Lut* getLut();
    Lut *LUT;
     float gammaMida;
    GLubyte* getLutBytes(Lut *lutActual);
    GLuint texturaLut;
    float anchVolum, altVolum, profVolum;
    void activaMask(bool p);
    void onlyMask(bool p);
    void setColorMask(QColor);
    void setTamanyVolum(vec4*);
    void showLut();
    void cambibackground();
    void setK(float);
    void resizeGL(int width, int height);


public slots:
    void Pan(int dx, int dy);
    void Zoom(int positiu);
    void setXRotation(int angle);
    void setYRotation(int angle);
    void setZRotation(int angle);
signals:

    void RotationChanged(int dx, int dy);
    void PanChanged(int dx, int dy);
    void ZoomChanged(int positiu);
    void xRotationChanged(int angle);
    void yRotationChanged(int angle);
    void zRotationChanged(int angle);

protected:

    void paintGL();

    int pointAtPosition(const QPoint &pos);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);

private slots:

private:

    void normalizeAngle(int *angle);

    void InitShader( const char* vertexShaderFile,
                       const char* fragmentShaderFile );

    void initShadersGPU();
    void initBackfaceBuffers();
    void vertex(float x, float y, float z);
    void drawQuads(float x, float y, float z);
    void renderBackface();
    void textures2DtoGPU(GLuint texName1);
    void creaTextura3D();
    void dadesRCtoGPU();
    void texturaLutToGPU();

    GLuint BFframebuffer;
    GLuint backface;
    GLuint BFrenderbuffer;
    GLuint texturaVolum;
    GLuint texturaMask;

    QPoint lastPos;
    GPU* gpu;
    Camera camera;
    Capsa3D capsaMinima;
    bool mascara;
    bool background;
    mat4 modelView;
    mat4 projection;

    float opacitat, sampling;
    float saturacio;
    float crem;
    int colorMode;
    bool oneStepMode, mipMode;
    float K;
    QVector<unsigned int> colorTable;

    volumen* obj;
    Cub *cub;
    Llum *llum;
    QWidget *w;
    QLineEdit *nombreEditado;
    QGLShaderProgram *program;
    vec4 ColorMask;
    vec4 *tamanyVolum;

};

#endif // escena_H
