#ifndef RGBDialog_H
#define RGBDialog_H

#include <QDialog>
#include <QImage>
#include <QLabel>
#include <QString>
#include <QFrame>
#include <QScrollArea>
#include <QComboBox>
#include "QFitsGlobal.h"
#include "fits.h"

class QSpinBox;
class QLineEdit;
class QGroupBox;
class QCheckBox;
class QDoubleSpinBox;
class RGBOptions;
class QFitsSingleBuffer;
class QFitsScroller;

/*
 * A simple class to display FITS images
 */
class QFitsDisplay : public QWidget {
    Q_OBJECT
public:
    QFitsDisplay(QWidget *parent = NULL);

    bool LoadFile(char *fname, int extension = 0);
    void setupColours(void);
    void setScaling(int);
    void setColourmap(int);
    void ScaleImage();
    void setScaleMin(double newmin);
    void setScaleMax(double newmax);
    void setScaleMinMax(double newmin, double newmax);
    void setZoom(int);
    void incZoom();
    void decZoom();
    void newColourtable();
    void setBrightnessContrast(int, int);
    void setBrightness(int);
    void setContrast(int);
    void setInvertColourMap(bool);
    void setIgnore(bool, double);

protected:
    void paintEvent(QPaintEvent*);
    void resizeEvent(QResizeEvent*);
    virtual void mouseMoveEvent(QMouseEvent*);

signals:
    void colourtableChanged();
    void mouseClicked(int, int);
    void newBrightness(int);
    void newContrast(int);
    void newMinMax(double, double);
    void recenter();
    void fileChanged(const QString&);

public:
    QImage *image;
    Fits    work,
            data;
    int     Mode,
            mx, my,
            xcenter, ycenter,
            oldx, oldy,
            oldwidth, oldlength,
            oldangle,
            colourmap,
            zoom,
            scaling,
            brightness,
            contrast,
            xoffset, yoffset;
    bool    invertColourmap,
            autoScale,
            ignoreInCube;
    double  ignoreValue,
            scalemin,
            scalemax;
protected:
    unsigned char colors[NCOLORS];
};

class QFitsDisplayWidget : public QWidget {
    Q_OBJECT
public:
    QFitsDisplayWidget(QWidget *parent = NULL);

protected:
    void resizeEvent(QResizeEvent*);

public slots:
    void LoadClicked();
    void setScaling(int i)                      { viewer->setScaling(i); }
    void setColourmap(int i)                    { viewer->setColourmap(i); }
    void ScaleImage(void)                       { viewer->ScaleImage(); }
    void setScaleMin(double min)                { viewer->setScaleMin(min); }
    void setScaleMax(double max)                { viewer->setScaleMin(max); }
    void setZoom(int i)                         { viewer->setZoom(i); }
    void incZoom()                              { viewer->incZoom(); }
    void decZoom()                              { viewer->decZoom(); }
    void newColourtable()                       { viewer->newColourtable(); }
    void setBrightnessContrast(int i, int j)    { viewer->setBrightnessContrast(i, j); }
    void setBrightness(int i)                   { viewer->setBrightness(i); }
    void setContrast(int i)                     { viewer->setContrast(i); }
    void setInvertColourMap(bool b)             { viewer->setInvertColourMap(b); }
    void recenterViewer();

public:
    QFitsScroller   *scroller;
    QFitsDisplay    *viewer;
};

class ResultWidget : public QWidget {
    Q_OBJECT
public:
    ResultWidget(QWidget*);

protected:
    void paintEvent(QPaintEvent*);

public:
    QImage *result;
};

class RGBDialog : public QDialog {
    Q_OBJECT
public:
    RGBDialog(QWidget*);

public slots:
    void updateColourImage();
    void ScrollX(int);
    void ScrollY(int);
    void LoadRed();
    void LoadGreen();
    void LoadBlue();
    void updateRedMinMax();
    void updateGreenMinMax();
    void updateBlueMinMax();
    void showRedMinMax(double, double);
    void showGreenMinMax(double, double);
    void showBlueMinMax(double, double);
    void alignImages();
    void saveColourImage();

public:
    QPushButton *ZoomInButton,
                *ZoomOutButton,
                *AlignButton,
                *SaveButton,
                *CloseButton;
    QGroupBox   *GroupBox1,
                *GroupBox1_2,
                *GroupBox1_2_2;
    QCheckBox   *GreenActive,
                *RedActive,
                *BlueActive;
    QLineEdit   *GreenMax,
                *GreenMin,
                *GreenFileName,
                *RedMax,
                *RedMin,
                *RedFileName,
                *BlueMax,
                *BlueMin,
                *BlueFileName;
    QComboBox   *GreenScaling,
                *GreenMap,
                *RedScaling,
                *RedMap,
                *BlueScaling,
                *BlueMap;
    QSpinBox    *GreenXShift,
                *GreenYShift,
                *RedXShift,
                *RedYShift,
                *BlueXShift,
                *BlueYShift;
    QPushButton *GreenFileButton,
                *RedFileButton,
                *BlueFileButton;
private:
    QFitsDisplayWidget *r, *g, *b;
    QScrollArea *resultscroller;
    QLabel      *resultviewer;
    QWidget     *options;
};

class dpPopup : public QComboBox {
    Q_OBJECT
public:
    dpPopup(QWidget*);
    void populateAndSelect(const QString = "");
    virtual void showPopup();
};

class dpCombineItem : public QFrame {
    Q_OBJECT
public:
    dpCombineItem(QWidget*);

signals:
    void somethingChanged();

public:
    dpPopup         *buffer;
    QDoubleSpinBox  *xshift,
                    *yshift,
                    *scale;
};

class dpCombineDialog : public QDialog {
    Q_OBJECT
public:
    dpCombineDialog(QWidget*);

protected:
    void resizeEvent(QResizeEvent*);
    void mapChannel(QFitsSingleBuffer*, QImage*, int, int, double, int*, int*);

public slots:
    void updateColourImage();
    void copyImage();
    void saveImage();
    void alignBuffers();

private:
    bool            dontupdate;
    QImage          result;
    QScrollArea     *resultscroller;
    QLabel          *resultviewer;
    QPushButton     *copyButton,
                    *saveButton,
                    *alignButton;
    dpCombineItem   *buf1,
                    *buf2,
                    *buf3;
};

#endif /* RGBDialog_H */
