#ifndef CUBE_3D_VTK_H
#define CUBE_3D_VTK_H

#include <QImage>
#include <QResizeEvent>

#include "QFitsBaseWidget.h"
#include "QFitsGlobal.h"
#include "fits.h"

#include "QVTKWidget.h"

class Fits;
class QFitsMainView;
class QFitsMarkers;
class QFitsView3D;
class QVTKInteractor;
class vtkRenderer;
class vtkPiecewiseFunction;
class vtkColorTransferFunction;
class vtkVolumeProperty;
class vtkVolumeRayCastMapper;
class vtkVolumeRayCastCompositeFunction;
class vtkVolume;
class vtkCamera;
class vtkCubeAxesActor2D;
class vtkImageImport;

//------------------------------------------------------------------------------
//         QFitsWidget3D
//------------------------------------------------------------------------------
// Adapter-pattern
class QFitsWidget3D : public QFitsBaseWidget {
    Q_OBJECT
//----- Functions -----
public:
    QFitsWidget3D(QFitsBaseBuffer*);
    ~QFitsWidget3D();

    //
    // overloaded abstract base functions
    //
    void setZoom(double);
    void updateScaling();
    void reset();
    void newData3D();
    void setupColours();
    void setImageCenter(double, double);
    QFitsBaseView* getView()                { return NULL; }

protected:
    void resizeEvent(QResizeEvent *r);

//----- Slots -----
//----- Signals -----
//----- Members -----
public:  // public for testing purpose
//private:
    QFitsView3D *cubeViewer;
};

//------------------------------------------------------------------------------
//         QFitsView3D
//------------------------------------------------------------------------------
class QFitsView3D : public QVTKWidget {
    Q_OBJECT
//----- Functions -----
public:
    QFitsView3D(QFitsWidget3D* parent);
    ~QFitsView3D();

    void updateScaling();

protected:
    void paintEvent(QPaintEvent *e);
    void keyPressEvent( QKeyEvent *e );
    void updateData();
    void calcZoomedRanges(int *x1, int *x2, int *y1, int *y2,
                                  int *z1, int *z2);
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void calcZoomedVisibleArea();
    void newColourtable();
    void enterEvent(QEvent*);
    void leaveEvent(QEvent*);

//----- Slots -----
public slots:
    void updateColourtable();
    void setImageCenter(double, double);
    void newData();
    void newData2();
    void applyZoom();
    void paintQuickAndDirty();
    void paintSlowAndNice();
    void ResetCamera(bool init = true, bool setPosition = true,
                     bool defReset = false);
    void updateZRange3D(double, double);

//----- Signals -----
signals:
    void flipX();
    void flipY();
    void decRot();
    void updateMagnifier(QPixmap &pix);

//----- Members -----
private:
    int previousBuffer;
    bool initialized;
    double default_cam_viewUp[3];
    double default_cam_position[3];
    Fits subcube;
    vtkImageImport *importer;
    vtkRenderer *renderer;
    vtkPiecewiseFunction *opacityTransferFunction;
    vtkColorTransferFunction *colorTransferFunction;
    vtkVolumeProperty *volProperty;
    vtkVolumeRayCastMapper *volMapper;
    vtkVolumeRayCastCompositeFunction *compositeFunction;
    vtkVolume *vol;
    QVTKInteractor *iren;
    vtkCamera *camera;
    bool colourtableDirty;
    bool scalingDirty;
    vtkCubeAxesActor2D *axes;
    double zmin;
    double zmax;
    QFitsWidget3D* myParent;
};

//------------------------------------------------------------------------------
//         cameraSettings
//------------------------------------------------------------------------------
class cameraSettings {
//----- Functions -----
public:
    cameraSettings();
    ~cameraSettings();

    void getSettings(vtkCamera* camera);
    void setSettings(vtkCamera* camera);

//----- Slots -----
//----- Signals -----
//----- Members -----
protected:
    double pos1, pos2, pos3;
    double focal1, focal2, focal3;
    double viewup1, viewup2, viewup3;
    double roll;
    double parscale;

    double shear1, shear2, shear3;
    double plane1, plane2, plane3;
    double center1, center2;
    double viewangle, thick;
    double eyeangle, focalplane;
    double cliprange1, cliprange2;
};

#endif /* CUBE_3D_VTK_H */
