/*
 * Dialogs for QFitsView which are extensions to UI dialogs
 * or completely standalone
 */

#include <QSpinBox>
#include <QLineEdit>
#include <QSlider>
#include <QRadioButton>
#include <QCheckBox>
#include <QButtonGroup>
#include <QUrl>
#include <QDesktopServices>
#include <QMessageBox>
#include <QScrollArea>
#include <QScrollBar>
#include <QResizeEvent>
#include <QImageWriter>

#include "dialogs.h"
#include "QFitsMainWindow.h"
#include "QFitsMainView.h"
#include "QFitsSingleBuffer.h"
#include "QFitsGlobal.h"
#include "QFitsHeaderView.h"
#include "fits.h"
#include "qtdpuser.h"
#include "svn_revision.h"

#include "resources/splash_about.xpm"
#include "resources/mpe.xpm"

QString getSaveImageFilename(QString *selectedFilter) {
    QString filename;
    if (selectedFilter != NULL) {
        // extract available image formats into a QStringList
        QList<QByteArray>formats1(QImageWriter::supportedImageFormats());
        QStringList formatsStringList;
        for (int i = 0; i < formats1.size(); ++i) {
            formatsStringList << formats1.at(i);
        }

        // put png at front, if present
        if (formatsStringList.contains("png")) {
            formatsStringList.removeAt(formatsStringList.indexOf("png"));
            QStringList aa;
            aa << "png";
            for (int i = 0; i < formatsStringList.size(); i++) {
                aa << formatsStringList.at(i);
            }
            formatsStringList = aa;
        }

        // put QStringList into a QString, and add 'any'-filter at end
        QString formatString;
        for (int i = 0; i < formatsStringList.size(); i++) {
            formatString += "*." + formatsStringList.at(i) + ";;";
        }
        formatString += "*";

        filename = QFileDialog::getSaveFileName(NULL,
                                                "QFitsView - Save as image",
                                                settings.lastSavePath,
                                                formatString,
                                                selectedFilter);
    }
    return filename;
}

void alignLabels(QLabel *label1, QLabel *label2, QLabel *label3) {
    int maxwidth, minheight;

    label1->adjustSize();
    maxwidth = label1->width();
    minheight = (int)(label1->height() * 1.5);
    if (label2 != NULL) {
        label2->adjustSize();
        if (label2->width() > maxwidth) {
            maxwidth = label2->width();
        }
        if ((int)(label2->height() * 1.5) > minheight) {
            minheight = (int)(label2->height() * 1.5);
        }
    }
    if (label3 != NULL) {
        label3->adjustSize();
        if (label3->width() > maxwidth) {
            maxwidth = label3->width();
        }
        if ((int)(label3->height() * 1.5) > minheight) {
            minheight = (int)(label3->height() * 1.5);
        }
    }

    label1->setAlignment(Qt::AlignRight);
    label1->resize(maxwidth, minheight);
    if (label2 != NULL) {
        label2->setAlignment(Qt::AlignRight);
        label2->setGeometry(label1->x(),
                            label1->y() + minheight + 5,
                            maxwidth,
                            minheight);
    }
    if (label3 != NULL) {
        label3->setAlignment(Qt::AlignRight);
        label3->setGeometry(label1->x(),
                            label2->y() + minheight + 5,
                            maxwidth,
                            minheight);
    }
}

About::About(QWidget *parent) : QDialog(parent,
                                        Qt::WindowTitleHint | Qt::WindowSystemMenuHint) {
    setWindowTitle("About QFitsView");
//    setIcon(QPixmap((const char **)telescope_xpm));

    QPixmap pm(splash_about);
    PixmapLabel = new QFitsSimplestButton(pm, this);
//    PixmapLabel->setPixmap((const char **)splashxpm);
    PixmapLabel->setGeometry(20, 20, pm.width(), pm.height());

    QPixmap mpe(mpe_xpm);
    QLabel *MpeLabel = new QLabel(this);
    MpeLabel->setPixmap(QPixmap((const char **)mpe_xpm));
    MpeLabel->setGeometry(410,
                          10,
                          mpe.width(),
                          mpe.height());

    TextLabel1 = new QLabel(this);
    TextLabel1->setTextFormat(Qt::RichText);
    TextLabel1->setWordWrap(true);
    QString txt =   "<b><font size=\"+1\">Version " + QString(DP_VERSION) + " " + QString(GetRevString()) +
                    "</font></b>\n"
                    "<br><br>\n"
                    "This image shows the central parsec of the centre of our galaxy. The \"yellow\" "
                    "emission is called \"mini-spiral\" and shows gas streamers which can be seen in "
                    "the emission line of hydrogen. This image has been taken at the 3.5m telescope "
                    "of the Calar Alto observatory in Spain in the infrared K-Band at 2.2 microns with "
                    "the adaptive optics system ALFA.";
    TextLabel1->setText(txt);
    TextLabel1->setMinimumSize(310, 10);
    TextLabel1->adjustSize();
    TextLabel1->move(PixmapLabel->width() + 40, mpe.height() + 20);

    PixmapLabel->move(20,(TextLabel1->y()+TextLabel1->height()-PixmapLabel->height())/2+10);

    TextLabel2 = new QLabel(this);
    TextLabel2->setTextFormat(Qt::RichText);
    TextLabel2->setWordWrap(true);
    TextLabel2->setText(
        "QFitsView is a FITS file viewer which was written using the QT widget library (v" + QString(qVersion()) +
        ") in order to be portable between various flavours of UNIX, MAC OS-X, and the "
        "Windows operating system. It is developed at the Max-Planck-Institute for "
        "Extraterrestrial Physics by Thomas Ott and Alex Agudo Berbel");
    TextLabel2->setMinimumSize(PixmapLabel->width() + TextLabel1->width(), 10);
    TextLabel2->adjustSize();
    TextLabel2->move(10, TextLabel1->y() + TextLabel1->height() + 10);

    OKButton = new QPushButton(this);
    OKButton->setText("OK");
    OKButton->setGeometry(TextLabel2->x() + TextLabel2->width() / 2 - 75,
                          TextLabel2->y() + TextLabel2->height() + 10,
                          150,
                          30);
    connect( OKButton, SIGNAL( clicked() ),
             this, SLOT( accept() ) );

    adjustSize();

    setFixedSize(size());
}

//checkForUpdates::checkForUpdates(QWidget *parent) : QDialog(parent) {
//    setWindowTitle("Software update");

//    buffer = new QBuffer();

//    QVBoxLayout *mainLayout = new QVBoxLayout();
//    setLayout(mainLayout);

//    label = new QLabel("Checking for latest version...");
//    label->setGeometry(10, 10, 300, 70);
//    label->setAlignment(Qt::AlignCenter);
//    label->setWordWrap(true);
//    progress = new QProgressBar();
//    progress->setMinimum(0);
//    progress->setMaximum(0);
//    progress->setGeometry(50, 50, 200, 10);
//    button = new QPushButton("Close");
//    button->setGeometry(110, 80, 100, 25);
//    link = new QPushButton("go to the QFitsView home page");
//    link->setGeometry(10, 80, 300, 25);
//    link->hide();

//    mainLayout->addWidget(label);
//    mainLayout->addWidget(progress);
//    mainLayout->addWidget(button);
//    mainLayout->addWidget(link);

//    http = new QHttp(this);
//    connect(http, SIGNAL(requestFinished(int, bool)),
//            this, SLOT(httpRequestFinished(int, bool)));
//    connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
//            this, SLOT(readResponseHeader(const QHttpResponseHeader &)));
//    connect(button, SIGNAL(clicked()),
//            this, SLOT(accept()));
//    connect(link, SIGNAL(clicked()),
//            this, SLOT(linkClicked()));

//    adjustSize();
//    setFixedSize(size());
//    checkUpdate();
//}

//checkForUpdates::~checkForUpdates() {
//    if (buffer) {
//        delete buffer;
//    }
//}

//void checkForUpdates::checkUpdate(void) {
//    QUrl url("http://www.mpe.mpg.de/~ott/QFitsView/revision.txt");
//    http->setHost(url.host(), url.port(80));
//    httpRequestAborted = false;
//    httpGetId = http->get(url.path(), buffer);
//}

//void checkForUpdates::linkClicked() {
//    accept();
//    QDesktopServices::openUrl(QUrl("http://www.mpe.mpg.de/~ott/QFitsView"));
//}

//void checkForUpdates::httpRequestFinished(int requestId, bool error) {
//    if (requestId != httpGetId) {
//        return;
//    }
//    progress->hide();
//    if (httpRequestAborted) {
//        return;
//    }
//    if (error) {
//        label->setText("Error: Could not connect to update server");
//    } else {
//        if (QString(buffer->data()).toInt() > QString(GetRevString()).mid(5).toInt())
//        {
//            label->setText("A new version is available!");
//            button->hide();
//            link->show();
//        } else {
//            label->setText("You are running the latest version of QFitsView");
//        }
//    }
//}

//void checkForUpdates::readResponseHeader(const QHttpResponseHeader &responseHeader) {
//    if (responseHeader.statusCode() != 200) {
//        label->setText(QString("Download failed: ") + responseHeader.reasonPhrase());
//        httpRequestAborted = true;
//        http->abort();
//        return;
//    }
//}

moreColourmaps::moreColourmaps(QWidget *parent) : QDialog(parent) {
    resize(500, 300);
    setWindowTitle("QFitsView - More colourmaps...");

    int x = 0, y = 0;
    QList<QAction *> actions = ((QFitsMainWindow*)parent)->mapActions->actions();
    for (QList<QAction *>::iterator iter = actions.begin(); iter != actions.end(); iter++) {
        QToolButton *button = new QToolButton(this);
        button->setGeometry(x, y, 100, 30);
        x += 110;
        if (x > 500) {
            x = 0;
            y += 35;
        }
        button->setDefaultAction(*iter);
        button->setToolButtonStyle(Qt::ToolButtonTextOnly);
    }

    adjustSize();
    QPushButton *closebutton = new QPushButton("Close", this);
    closebutton->setGeometry(width() / 2 - 50,
                             height() + 10, 100, 30);
    connect(closebutton, SIGNAL(clicked()),
            this, SLOT(hide()));
    adjustSize();
}

CubeDisplayDialog::CubeDisplayDialog(QFitsMainWindow *parent) :
                                   QDialog(dynamic_cast<QWidget*>(parent)) {
    myParent = parent;
    n3 = 9999;
    crpix = 1.0;
    crval = 1.0;
    cdelt = 1.0;
    interactiveUpdates = true;

    setWindowTitle("CubeDisplay");

    QVBoxLayout *mainLayout = new QVBoxLayout();
    setLayout(mainLayout);

    //////////////////////////////////////////////////////
    // CUBE display & CUBE movie
    //
    QHBoxLayout *hBoxLayout = new QHBoxLayout();
    mainLayout->addLayout(hBoxLayout);
    //
    // CUBE display
    //
    buttonDisplaySingle = new QRadioButton("Single");
    buttonDisplaySingle->setChecked(true);
    buttonDisplayAverage = new QRadioButton("Average");
    buttonDisplayMedian = new QRadioButton("Median");
    buttonDisplayLinemap = new QRadioButton("Linemap");

    QButtonGroup *buttonGroupDisplay = new QButtonGroup();
    buttonGroupDisplay->addButton(buttonDisplaySingle, 1);
    buttonGroupDisplay->addButton(buttonDisplayAverage, 2);
    buttonGroupDisplay->addButton(buttonDisplayMedian, 3);
    buttonGroupDisplay->addButton(buttonDisplayLinemap, 4);

    QGroupBox *groupCubeDisplay = new QGroupBox();
    groupCubeDisplay->setTitle("CUBE display");
    QVBoxLayout *vboxCubeDisplay = new QVBoxLayout(groupCubeDisplay);
    vboxCubeDisplay->addWidget(buttonDisplaySingle);
    vboxCubeDisplay->addWidget(buttonDisplayAverage);
    vboxCubeDisplay->addWidget(buttonDisplayMedian);
    vboxCubeDisplay->addWidget(buttonDisplayLinemap);
    hBoxLayout->addWidget(groupCubeDisplay);
    //
    // CUBE movie
    //
    spinMovieSpeed = new QSpinBox();
    spinMovieSpeed->setMaximum(9999);
    spinMovieSpeed->setSingleStep(100);
    spinMovieSpeed->setValue(200);
    checkAutoScale = new QCheckBox("rescale each image");
    checkAutoScale->setChecked(true);

    QGroupBox *groupCubeMovie = new QGroupBox();
    groupCubeMovie->setTitle("CUBE movie");
    QVBoxLayout *vboxCubeMovie = new QVBoxLayout(groupCubeMovie);
    vboxCubeMovie->addWidget(new QLabel("Movie Speed"));
    vboxCubeMovie->addWidget(spinMovieSpeed);
    vboxCubeMovie->addWidget(checkAutoScale);
    hBoxLayout->addWidget(groupCubeMovie);

    ////////////////////////////////////////////////////
    // Channels, Wavelength
    //
    hBoxLayout = new QHBoxLayout();
    mainLayout->addLayout(hBoxLayout);
    //
    // --> Channels
    //
    spinLinemapCenter = new QSpinBox();
    spinLinemapCenter->setMinimum(1);
    spinLinemapCenter->setMaximum(9999);
    spinLinemapCenter->setValue(1);
    spinLinemapWidth = new QSpinBox();
    spinLinemapWidth->setMinimum(1);
    spinLinemapWidth->setMaximum(9999);
    spinLinemapWidth->setValue(1);
    checkLinemapDoCont1 = new QCheckBox();
    spinLinemapCont1 = new QSpinBox();
    spinLinemapCont1->setMinimum(-9999);
    spinLinemapCont1->setMaximum(9999);
    spinLinemapCont1->setValue(-10);
    spinLinemapWidth1 = new QSpinBox();
    spinLinemapWidth1->setMinimum(1);
    spinLinemapWidth1->setMaximum(9999);
    spinLinemapWidth1->setValue(1);
    checkLinemapDoCont2 = new QCheckBox();
    spinLinemapCont2 = new QSpinBox();
    spinLinemapCont2->setMinimum(-9999);
    spinLinemapCont2->setMaximum(9999);
    spinLinemapCont2->setValue(10);
    spinLinemapWidth2 = new QSpinBox();
    spinLinemapWidth2->setMinimum(1);
    spinLinemapWidth2->setMaximum(9999);
    spinLinemapWidth2->setValue(1);

    QGridLayout *gridLayout = new QGridLayout();
    gridLayout->addWidget(new QLabel("Channels"), 0, 1);
    gridLayout->addWidget(new QLabel("Central Frame"), 1, 0);
    gridLayout->addWidget(spinLinemapCenter, 1, 1);
    gridLayout->addWidget(new QLabel("Width"), 1, 2);
    gridLayout->addWidget(spinLinemapWidth, 1, 3);
    gridLayout->addWidget(checkLinemapDoCont1, 2, 0);
    gridLayout->addWidget(spinLinemapCont1, 2, 1);
    gridLayout->addWidget(new QLabel("Width"), 2, 2);
    gridLayout->addWidget(spinLinemapWidth1, 2, 3);
    gridLayout->addWidget(checkLinemapDoCont2, 3, 0);
    gridLayout->addWidget(spinLinemapCont2, 3, 1);
    gridLayout->addWidget(new QLabel("Width"), 3, 2);
    gridLayout->addWidget(spinLinemapWidth2, 3, 3);
    hBoxLayout->addLayout(gridLayout);
    hBoxLayout->addItem(new QSpacerItem(50, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
    //
    // --> Wavelength
    //
    lineeditLinemapCenterW = new QLineEdit();
    lineeditLinemapWidthW = new QLineEdit();
    lineeditLinemapCont1W = new QLineEdit();
    lineeditLinemapWidth1W = new QLineEdit();
    lineeditLinemapCont2W = new QLineEdit();
    lineeditLinemapWidth2W = new QLineEdit();

    gridLayout = new QGridLayout();
    gridLayout->addWidget(new QLabel("Wavelength"), 0, 1);
    gridLayout->addWidget(lineeditLinemapCenterW, 1, 0);
    gridLayout->addWidget(new QLabel("Width"), 1, 1);
    gridLayout->addWidget(lineeditLinemapWidthW, 1, 2);
    gridLayout->addWidget(lineeditLinemapCont1W, 2, 0);
    gridLayout->addWidget(new QLabel("Width"), 2, 1);
    gridLayout->addWidget(lineeditLinemapWidth1W, 2, 2);
    gridLayout->addWidget(lineeditLinemapCont2W, 3, 0);
    gridLayout->addWidget(new QLabel("Width"), 3, 1);
    gridLayout->addWidget(lineeditLinemapWidth2W, 3, 2);
    hBoxLayout->addLayout(gridLayout);

    ////////////////////////////////////////////////////
    // Spacer
    //
    hBoxLayout = new QHBoxLayout();
    mainLayout->addLayout(hBoxLayout);
    hBoxLayout->addItem(new QSpacerItem(1, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));

    ////////////////////////////////////////////////////
    // Slider
    //
    hBoxLayout = new QHBoxLayout();
    mainLayout->addLayout(hBoxLayout);
    labelWavelengthSliderLabel1 = new QLabel("1");
    labelWavelengthSliderLabel1->setAlignment(Qt::AlignLeft);
    labelLinemapInfo = new QLabel("No wavelength information available");
    labelLinemapInfo->setAlignment(Qt::AlignHCenter);
    labelWavelengthSliderLabel2 = new QLabel("9999");
    labelWavelengthSliderLabel2->setAlignment(Qt::AlignRight);
    hBoxLayout->addWidget(labelWavelengthSliderLabel1);
    hBoxLayout->addWidget(labelLinemapInfo);
    hBoxLayout->addWidget(labelWavelengthSliderLabel2);

    hBoxLayout = new QHBoxLayout();
    sliderWavelength = new QSlider();
    sliderWavelength->setMinimum(1);
    sliderWavelength->setMaximum(9999);
    sliderWavelength->setValue(500);
    sliderWavelength->setTracking(true);
    sliderWavelength->setOrientation(Qt::Horizontal);
    sliderWavelength->setTickInterval(1000);
    hBoxLayout->addWidget(sliderWavelength);
    mainLayout->addLayout(hBoxLayout);

    ////////////////////////////////////////////////////
    // OK button
    //
    hBoxLayout = new QHBoxLayout();
    mainLayout->addLayout(hBoxLayout);

    buttonOk = new QPushButton("Ok");
    hBoxLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
    hBoxLayout->addWidget(buttonOk);
    hBoxLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));

    ////////////////////////////////////////////////////
    // tab order & connects
    //
    setTabOrder(buttonDisplaySingle, buttonDisplayAverage);
    setTabOrder(buttonDisplayAverage, buttonDisplayMedian);
    setTabOrder(buttonDisplayMedian, buttonDisplayLinemap);
    setTabOrder(buttonDisplayLinemap, spinMovieSpeed);
    setTabOrder(spinMovieSpeed, checkAutoScale);
    setTabOrder(checkAutoScale, spinLinemapCenter);
    setTabOrder(spinLinemapCenter, spinLinemapWidth);
    setTabOrder(spinLinemapWidth, lineeditLinemapCenterW);
    setTabOrder(lineeditLinemapCenterW, lineeditLinemapWidthW);
    setTabOrder(lineeditLinemapWidthW, checkLinemapDoCont1);
    setTabOrder(checkLinemapDoCont1, spinLinemapCont1);
    setTabOrder(spinLinemapCont1, spinLinemapWidth1);
    setTabOrder(spinLinemapWidth1, lineeditLinemapCont1W);
    setTabOrder(lineeditLinemapCont1W, lineeditLinemapWidth1W);
    setTabOrder(lineeditLinemapWidth1W, checkLinemapDoCont2);
    setTabOrder(checkLinemapDoCont2, spinLinemapCont2);
    setTabOrder(spinLinemapCont2, spinLinemapWidth2);
    setTabOrder(spinLinemapWidth2, lineeditLinemapCont2W);
    setTabOrder(lineeditLinemapCont2W, lineeditLinemapWidth2W);
    setTabOrder(lineeditLinemapWidth2W, sliderWavelength);
    setTabOrder(sliderWavelength, buttonOk);

    connect(buttonOk, SIGNAL(clicked()),
            this, SLOT(accept()));
    connect(sliderWavelength, SIGNAL(valueChanged(int)),
            spinLinemapCenter, SLOT(setValue(int)));
    connect(spinLinemapCenter, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapCenterW(int)));
    connect(lineeditLinemapCenterW, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapCenterC(const QString &)));
    connect(spinLinemapWidth, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapWidthW(int)));
    connect(lineeditLinemapWidthW, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapWidthC(const QString &)));
    connect(spinLinemapCont1, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapCont1W(int)));
    connect(lineeditLinemapCont1W, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapCont1C(const QString &)));
    connect(spinLinemapWidth1, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapWidth1W(int)));
    connect(lineeditLinemapWidth1W, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapWidth1C(const QString &)));
    connect(spinLinemapCont2, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapCont2W(int)));
    connect(lineeditLinemapCont2W, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapCont2C(const QString &)));
    connect(spinLinemapWidth2, SIGNAL(valueChanged(int)),
            this, SLOT(setLinemapWidth2W(int)));
    connect(lineeditLinemapWidth2W, SIGNAL(textChanged(const QString &)),
            this, SLOT(setLinemapWidth2C(const QString &)));
    connect(checkAutoScale, SIGNAL(toggled(bool)),
            myParent->main_view, SLOT(setAutoScale(bool)));
    connect(spinMovieSpeed, SIGNAL(valueChanged(int)),
            myParent->main_view, SLOT(setMovieSpeed(int)));
    connect(buttonOk, SIGNAL(clicked()),
            myParent, SLOT(updateCubeOptions()));
    connect(spinLinemapCenter, SIGNAL(valueChanged(int)),
            myParent, SLOT(updateLinemapInfo(int)));
    connect(spinLinemapWidth, SIGNAL(valueChanged(int)),
            myParent, SLOT(updateLinemapInfo(int)));

}

void CubeDisplayDialog::show(void) {
    QFitsSingleBuffer *sb = dynamic_cast<QFitsSingleBuffer*>(getCurrentBuffer());
    if ((sb != NULL) &&
        (sb->getDpData()->type == typeFits) &&
        (sb->getDpData()->fvalue != NULL))
    {
        interactiveUpdates = false;

        buffersLock.lockForRead();
        Fits *f = sb->getDpData()->fvalue;
        double crpix = f->getCRPIX(3);
        double cdelt = f->getCDELT(3);
        double crval = f->getCRVAL(3);
        long n3 = f->Naxis(3);
        buffersLock.unlock();

        setDisplayMode(sb->getCubeMode());
        spinLinemapCenter->setMaximum(n3);
        spinLinemapCont1->setMaximum(n3);
        spinLinemapCont2->setMaximum(n3);
        spinLinemapCont1->setMinimum(-n3);
        spinLinemapCont2->setMinimum(-n3);
        sliderWavelength->setMaximum(n3);

        lineeditLinemapCenterW->setText(
                QString::number(crval + (sb->getCubeCenter(QFV::Wavelength) - crpix) * cdelt));
        spinLinemapCenter->setValue(
                (int)(sb->getCubeCenter(QFV::Wavelength) + 0.5));
        lineeditLinemapWidthW->setText(
                QString::number(sb->getLineWidth(QFV::Wavelength) * cdelt));
        spinLinemapWidth->setValue(
                (int)(sb->getLineWidth(QFV::Wavelength) + 0.5));
        lineeditLinemapCont1W->setText(
                QString::number((double)(sb->getLineCont1Center()) * cdelt));
        spinLinemapCont1->setValue(sb->getLineCont1Center());
        lineeditLinemapWidth1W->setText(
                QString::number((double)(sb->getLineCont1Width()) * cdelt));
        spinLinemapWidth1->setValue(sb->getLineCont1Width());
        lineeditLinemapCont2W->setText(
                QString::number((double)(sb->getLineCont2Center()) * cdelt));
        spinLinemapCont2->setValue(sb->getLineCont2Center());
        lineeditLinemapWidth2W->setText(
                QString::number((double)(sb->getLineCont2Width()) * cdelt));
        spinLinemapWidth2->setValue(sb->getLineCont2Width());

        checkLinemapDoCont1->setChecked(sb->getLineCont1());
        checkLinemapDoCont2->setChecked(sb->getLineCont2());

        interactiveUpdates = true;

        QDialog::show();
    }
}

QFitsBaseBuffer* CubeDisplayDialog::getCurrentBuffer() {
    return myParent->getCurrentBuffer();
}

void CubeDisplayDialog::setDisplayMode(dpCubeMode newmode) {
    buttonDisplaySingle->setChecked(false);
    buttonDisplayAverage->setChecked(false);
    buttonDisplayMedian->setChecked(false);
    buttonDisplayLinemap->setChecked(false);
    switch (newmode) {
        case DisplayCubeSingle:
            buttonDisplaySingle->setChecked(true);
            break;
        case DisplayCubeAverage:
            buttonDisplayAverage->setChecked(true);
            break;
        case DisplayCubeMedian:
            buttonDisplayMedian->setChecked(true);
            break;
        case DisplayCubeLinemap:
            buttonDisplayLinemap->setChecked(true);
            break;
        default:
            break;
    }
}

void CubeDisplayDialog::setCubeDisplayOptions(double cr, double cd,
                                              double cv, int n) {
    crpix = cr;
    cdelt = cd;
    crval = cv;
    n3 = n;
}

void CubeDisplayDialog::setLinemapCenterW(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapCenterW->hasFocus())
        lineeditLinemapCenterW->setText(
                QString::number(crval + ((double)(newvalue) - crpix) * cdelt));
}

void CubeDisplayDialog::setLinemapCenterC(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapCenter->hasFocus())
        spinLinemapCenter->setValue(
                (int)(crpix + (newvalue.toDouble() - crval) / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapWidthW(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapWidthW->hasFocus())
        lineeditLinemapWidthW->setText(QString::number((double)newvalue * cdelt));
}

void CubeDisplayDialog::setLinemapWidthC(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapWidth->hasFocus())
        spinLinemapWidth->setValue((int)(newvalue.toDouble() / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapCont1W(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapCont1W->hasFocus())
        lineeditLinemapCont1W->setText(QString::number((double)(newvalue) * cdelt));
}

void CubeDisplayDialog::setLinemapCont1C(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapCont1->hasFocus())
        spinLinemapCont1->setValue((int)(newvalue.toDouble() / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapWidth1W(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapWidth1W->hasFocus())
        lineeditLinemapWidth1W->setText(QString::number((double)(newvalue) * cdelt));
}

void CubeDisplayDialog::setLinemapWidth1C(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapWidth1->hasFocus())
        spinLinemapWidth1->setValue((int)(newvalue.toDouble() / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapCont2W(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapCont2W->hasFocus())
        lineeditLinemapCont2W->setText(QString::number((double)(newvalue) * cdelt));
}

void CubeDisplayDialog::setLinemapCont2C(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapCont2->hasFocus())
            spinLinemapCont2->setValue((int)(newvalue.toDouble() / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapWidth2W(int newvalue) {
    if (interactiveUpdates && !lineeditLinemapWidth2W->hasFocus())
        lineeditLinemapWidth2W->setText(QString::number((double)(newvalue) * cdelt));
}

void CubeDisplayDialog::setLinemapWidth2C(const QString &newvalue) {
    if (interactiveUpdates && !spinLinemapWidth2->hasFocus())
        spinLinemapWidth2->setValue((int)(newvalue.toDouble() / cdelt + 0.5));
}

void CubeDisplayDialog::setLinemapCenterMaxValue(int val) {
    spinLinemapCenter->setMaximum(val);
}

void CubeDisplayDialog::setLinemapCont1MaxValue(int val) {
    spinLinemapCont1->setMaximum(val);
}

void CubeDisplayDialog::setLinemapCont2MaxValue(int val) {
    spinLinemapCont2->setMaximum(val);
}

void CubeDisplayDialog::setLinemapSliderWavelength(int val) {
    sliderWavelength->setMaximum(val);
}

void CubeDisplayDialog::setLinemapCenterValue(int val) {
    spinLinemapCenter->setValue(val);
}

void CubeDisplayDialog::setLinemapWavelengthSliderInformation(QString *label1, QString *info, QString *label2) {
    if (label1 != NULL) {
        labelWavelengthSliderLabel1->setText(*label1);
    }
    labelLinemapInfo->setText(*info);
    if (label2 != NULL) {
        labelWavelengthSliderLabel2->setText(*label2);
    }
}

int CubeDisplayDialog::getLinemapCenterValue() {
    return spinLinemapCenter->value();
}
int CubeDisplayDialog::getLinemapWidthValue() {
    return spinLinemapWidth->value();
}
int CubeDisplayDialog::getLinemapCont1Value() {
    return spinLinemapCont1->value();
}
int CubeDisplayDialog::getLinemapCont2Value() {
    return spinLinemapCont2->value();
}
int CubeDisplayDialog::getLinemapWidth1Value() {
    return spinLinemapWidth1->value();
}
int CubeDisplayDialog::getLinemapWidth2Value() {
    return spinLinemapWidth2->value();
}

bool CubeDisplayDialog::getButtonDisplaySingleChecked() {
    return buttonDisplaySingle->isChecked();
}
bool CubeDisplayDialog::getButtonDisplayAverageChecked() {
    return buttonDisplayAverage->isChecked();
}
bool CubeDisplayDialog::getButtonDisplayMedianChecked() {
    return buttonDisplayMedian->isChecked();
}
bool CubeDisplayDialog::getButtonDisplayLinemapChecked() {
    return buttonDisplayLinemap->isChecked();
}
bool CubeDisplayDialog::getCheckLinemapDoCont1Checked() {
    return checkLinemapDoCont1->isChecked();
}
bool CubeDisplayDialog::getCheckLinemapDoCont2Checked() {
    return checkLinemapDoCont2->isChecked();
}








ImageDisplay::ImageDisplay(QWidget* parent) : QDialog(parent) {
    setWindowTitle("QFitsView - Image Display");

    QLabel *labelBright = new QLabel();
    labelBright->setText("Brightness");
    QLabel *labelContrast= new QLabel();
    labelContrast->setText("Contrast");

    sliderBrightness = new QSlider();
    sliderBrightness->setMaximum(999);
    sliderBrightness->setValue(500);
    sliderBrightness->setOrientation(Qt::Horizontal);

    spinboxBrightness = new QSpinBox();
    spinboxBrightness->setMaximum(999);
    spinboxBrightness->setValue(500);

    sliderContrast = new QSlider();
    sliderContrast->setMaximum(999);
    sliderContrast->setValue(99);
    sliderContrast->setOrientation(Qt::Horizontal);

    spinboxContrast = new QSpinBox();
    spinboxContrast->setMaximum(999);
    spinboxContrast->setValue(99);

    checkboxIgnoreValue = new QCheckBox();
    checkboxIgnoreValue->setChecked(true);
    checkboxIgnoreValue->setText("Ignore value of:");

    lineeditIgnoreValue = new QLineEdit();
    lineeditIgnoreValue->setText("-1e10");


    buttonClose = new QPushButton();
    buttonClose->setText("Close");

    QGridLayout *gridLayout = new QGridLayout();
    gridLayout->addWidget(labelBright, 0, 0);
    gridLayout->addWidget(sliderBrightness, 0, 1);
    gridLayout->addWidget(spinboxBrightness, 0, 2);
    gridLayout->addWidget(labelContrast, 1, 0);
    gridLayout->addWidget(sliderContrast, 1, 1);
    gridLayout->addWidget(spinboxContrast, 1, 2);
    gridLayout->addWidget(checkboxIgnoreValue, 2, 1);
    gridLayout->addWidget(lineeditIgnoreValue, 2, 2);

    QGroupBox *groupBox = new QGroupBox();
    groupBox->setTitle("Image display");
    groupBox->setLayout(gridLayout);

    QHBoxLayout *hLayout = new QHBoxLayout();
    hLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
    hLayout->addWidget(buttonClose);
    hLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));

    QVBoxLayout *mainLayout = new QVBoxLayout();
    mainLayout->addWidget(groupBox);
    mainLayout->addLayout(hLayout);
    setLayout(mainLayout);

    // signals and slots connections
    connect( sliderBrightness, SIGNAL( valueChanged(int) ),
             spinboxBrightness, SLOT( setValue(int) ) );
    connect( sliderContrast, SIGNAL( valueChanged(int) ),
             spinboxContrast, SLOT( setValue(int) ) );
    connect( spinboxBrightness, SIGNAL( valueChanged(int) ),
             sliderBrightness, SLOT( setValue(int) ) );
    connect( spinboxContrast, SIGNAL( valueChanged(int) ),
             sliderContrast, SLOT( setValue(int) ) );
    connect( checkboxIgnoreValue, SIGNAL( toggled(bool) ),
             lineeditIgnoreValue, SLOT( setEnabled(bool) ) );
    connect( buttonClose, SIGNAL( clicked() ),
             this, SLOT( accept() ) );
}

/*
 *  Destroys the object and frees any allocated resources
 */
ImageDisplay::~ImageDisplay()
{
    // no need to delete child widgets, Qt does it all for us
}

BlinkDialog::BlinkDialog(QWidget *parent): QDialog(parent) {
    list = new QListWidget(this);
    list->setGeometry(10, 10, 400, 300);

    QPushButton *selectAllButton = new QPushButton("Select All", this);
    selectAllButton->setGeometry(10, 320, 80, 30);
    connect(selectAllButton, SIGNAL(clicked()),
            this, SLOT(selectAll()));
    QPushButton *deselectAllButton = new QPushButton("Deselect All", this);
    deselectAllButton->setGeometry(100, 320, 80, 30);
    connect(deselectAllButton, SIGNAL(clicked()),
            this, SLOT(deselectAll()));

    QLabel *timeoutLabel = new QLabel("Time step", this);
    timeoutLabel->setGeometry(190, 320, 120, 30);
    timeoutLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    timeout = new QSpinBox(this);
    timeout->setGeometry(320, 320, 90, 30);
    timeout->setMinimum(0);
    timeout->setMaximum(10000);
    timeout->setSuffix("ms");
    timeout->setSingleStep(100);
    timeout->setValue(200);
    timeout->setSpecialValueText("fastest");

    cancelButton = new QPushButton("Cancel", this);
    cancelButton->setGeometry(90, 360, 100, 30);
    connect(cancelButton, SIGNAL(clicked()),
            this, SLOT(reject()));

    okButton = new QPushButton("Ok", this);
    okButton->setGeometry(230, 360, 100, 30);
    connect(okButton, SIGNAL(clicked()),
            this, SLOT(accept()));

    adjustSize();
    setFixedSize(size());
}

void BlinkDialog::selectAll() {
    for (int row = 0; row < list->count(); row++) {
        list->item(row)->setCheckState(Qt::Checked);
    }
}

void BlinkDialog::deselectAll() {
    for (int row = 0; row < list->count(); row++) {
        list->item(row)->setCheckState(Qt::Unchecked);
    }
}

PlotOptionsDialog::PlotOptionsDialog(QWidget *parent) : QDialog(parent) {
//    setIcon(QPixmap((const char **)telescope_xpm));
    setWindowTitle("QFitsView - Plot Options");

    QGroupBox *SpectraGroup = new QGroupBox("Cuts Plot", this);
    SpectraGroup->setGeometry(10, 10, 150, 100);

    QLabel *TextLabel1 = new QLabel("Style", SpectraGroup);
    TextLabel1->move(20, 30);

    QLabel *TextLabel2 = new QLabel("Width", SpectraGroup);

    alignLabels(TextLabel1, TextLabel2);

    CutsStyle = new QComboBox(SpectraGroup);
    CutsStyle->addItem("horizontal");
    CutsStyle->addItem("vertical");
    CutsStyle->addItem("radial average");
    CutsStyle->setGeometry(TextLabel1->x() + TextLabel1->width() + 5,
                           TextLabel1->y(), 100, TextLabel1->height());

    CutsWidth = new QSpinBox(SpectraGroup);
    CutsWidth->setSuffix(" Pixels");
    CutsWidth->setRange(1, 300);
    CutsWidth->setValue(30);
    CutsWidth->setSingleStep(5);
    CutsWidth->setGeometry(TextLabel2->x() + TextLabel2->width() + 5,
                           TextLabel2->y(), 100, TextLabel2->height());

    PlotTakeLimits = new QCheckBox("Plot limits from display", SpectraGroup);
    PlotTakeLimits->setGeometry(TextLabel2->x(),
                                TextLabel2->y() + TextLabel2->height() + 10,
                                TextLabel2->width() + CutsWidth->width() + 5,
                                TextLabel2->height());

    SpectraGroup->adjustSize();

    closeButton = new QPushButton("Close", this);
    closeButton->setGeometry(SpectraGroup->x() + SpectraGroup->width() / 2 - 50,
                             SpectraGroup->y() + SpectraGroup->height() + 20,
                             100,
                             25);
    connect(closeButton, SIGNAL(clicked()),
            this, SLOT(accept()));

    adjustSize();
    setFixedSize(size());
}

dpImportDialog::dpImportDialog(QWidget *parent, const QString &fname) : QDialog(parent) {
    setWindowTitle("Import File");

    highlighter = NULL;
    filename = fname;

    importText = new QRadioButton("Import as text", this);
    importText->move(20, 20);
    importText->adjustSize();
    QLabel *importTextExplanation = new QLabel("Each text line in the file will be\nimported as an element of a string list", this);
    importTextExplanation->move(20, importText->y() + importText->height() + 5);
    importTextExplanation->adjustSize();

    importNumber = new QRadioButton("Import as Numbers", this);
    importNumber->move(20, importTextExplanation->y() + importTextExplanation->height() + 10);
    importNumber->adjustSize();
    importNumber->setChecked(true);
    QLabel *importNumberExplanation = new QLabel("The content of the file will be interpreted\naccording to these options:", this);
    importNumberExplanation->move(20, importNumber->y() + importNumber->height() + 5);
    importNumberExplanation->adjustSize();

    QGroupBox *optionsBox = new QGroupBox(this);
    optionsBox->move(30, importNumberExplanation->y() + importNumberExplanation->height() + 10);
    QGridLayout *layout = new QGridLayout(optionsBox);

    QLabel *l1 = new QLabel("Number of columns", optionsBox);
    layout->addWidget(l1, 0, 0);
    columns = new QSpinBox(optionsBox);
    columns->setRange(0, 9999);
    columns->setSpecialValueText("Auto");
    layout->addWidget(columns, 0, 1);

    QLabel *l2 = new QLabel("Column separator", optionsBox);
    layout->addWidget(l2, 1, 0);
    delimiter = new QComboBox(optionsBox);
    delimiter->addItem("  (Whitespace [Space, Tab])");
    delimiter->addItem(", (Comma)");
    delimiter->addItem("; (Semicolon)");
    delimiter->setEditable(true);
    layout->addWidget(delimiter, 1, 1);

    useComment = new QCheckBox("Don't import Lines Starting with ", optionsBox);
    useComment->setChecked(false);
    layout->addWidget(useComment, 2, 0);
    comment = new QLineEdit(optionsBox);
    comment->setMaxLength(1);
    comment->setText("#");
    comment->setEnabled(false);
    layout->addWidget(comment, 2, 1);
    connect(useComment, SIGNAL(toggled(bool)), comment, SLOT(setEnabled(bool)));

    QLabel *l3 = new QLabel("Number of lines to skip at beginning: ", optionsBox);
    layout->addWidget(l3, 3, 0);
    skiplines = new QSpinBox(optionsBox);
    skiplines->setRange(0, 9999);
    skiplines->setSpecialValueText("None");
    layout->addWidget(skiplines, 3, 1);

    optionsBox->adjustSize();

    preview = new QTextEdit(this);
    preview->setGeometry(10, optionsBox->y() + optionsBox->height() + 10, optionsBox->width(), 200);
    preview->setLineWrapMode(QTextEdit::NoWrap);
    preview->setStyleSheet("font-family: monospace; font-size: 10pt");
    preview->setReadOnly(true);
    QFile file(fname);
    file.open(QIODevice::ReadOnly | QIODevice::Text);
//    preview->setText(file.readAll());
    preview->setText(file.read(10000));
    file.close();

    updatePreview();

    cancelButton = new QPushButton("Cancel", this);
    cancelButton->setGeometry(preview->x() + preview->width() / 2 - 130, preview->y() + preview->height() + 20, 100, 30);
    connect(cancelButton, SIGNAL(clicked()),
            this, SLOT(reject()));

    okButton = new QPushButton("Ok", this);
    okButton->setGeometry(preview->x() + preview->width() / 2 + 30, preview->y() + preview->height() + 20, 100, 30);
    connect(okButton, SIGNAL(clicked()),
            this, SLOT(accept()));

    connect(importText, SIGNAL(clicked()), this, SLOT(updatePreview()));
    connect(importNumber, SIGNAL(clicked()), this, SLOT(updatePreview()));
    connect(delimiter, SIGNAL(editTextChanged(const QString &)), this, SLOT(updatePreview2(const QString &)));
    connect(useComment, SIGNAL(clicked()), this, SLOT(updatePreview()));
    connect(comment, SIGNAL(textEdited(const QString &)), this, SLOT(updatePreview2(const QString &)));
    connect(skiplines, SIGNAL(valueChanged(int)), this, SLOT(updatePreview3(int)));
    adjustSize();
    setFixedSize(size());
}

void dpImportDialog::updatePreview(void) {
    QString delimiterText, commentText;

    delimiterText = delimiter->currentText().left(1);

    if (useComment->isChecked()) commentText = comment->text();
    else commentText = "";

    if (highlighter != NULL) {
        highlighter->setDocument(0);
        delete highlighter;
        highlighter = NULL;
    }

    QTextCharFormat singleLineCommentFormat;
    singleLineCommentFormat.setForeground(Qt::black);
    QTextCursor *lineselector = new QTextCursor(preview->document());
    lineselector->setPosition(0);
    lineselector->movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
    lineselector->setCharFormat(singleLineCommentFormat);

    if (importNumber->isChecked()) {
        highlighter = new PreviewHighlighter(preview->document(), commentText, delimiterText);

        if (skiplines->value() > 0) {
            singleLineCommentFormat.setForeground(Qt::gray);
            lineselector->setPosition(0);
            lineselector->movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, skiplines->value());
            lineselector->setCharFormat(singleLineCommentFormat);

        }
        highlighter->rehighlight();
    }
}

void dpImportDialog::updatePreview2(const QString &bla) {
    updatePreview();
}

void dpImportDialog::updatePreview3(int bla) {
    updatePreview();
}

dpPushButton::dpPushButton(const QString &text, QWidget *parent, int row, int col, int maxWidth) : QPushButton(text, parent) {
    r = row;
    c = col;
    connect(this, SIGNAL(clicked()), this, SLOT(wasclicked()));
    if (maxWidth > 0) {
//        setMaximumWidth(maxWidth);
    }
}

void dpPushButton::wasclicked() {
    emit dpPushButtonClicked(r, c);
}

dpFitsExtensionDialog::dpFitsExtensionDialog(QWidget *parent, const QString &fname, bool newBuffer, bool fromCmdLine)
    : QDialog(parent)
{
    filename = fname;
    extension = column = 0;
    isNewBuffer = newBuffer;

    headerView = new QFitsHeaderViewExt(this);
    headerView->setWindowFlags(headerView->windowFlags() | Qt::WindowStaysOnTopHint);

    setWindowTitle("Select FITS file extension - " + filename);

    QWidget *mainWidget = new QWidget(this);
    mainWidget->move(0, 0);

    QScrollArea *scrollareaMain = new QScrollArea(this);
    scrollareaMain->setWidget(mainWidget);
    scrollareaMain->setFrameShape(QFrame::NoFrame);

    QFrame *extensionFrame = new QFrame(mainWidget);
    extensionFrame->setFrameShape(QFrame::StyledPanel);
    QGridLayout *extensionLayout = new QGridLayout(extensionFrame);
    extensionLayout->setHorizontalSpacing(20);
    extensionLayout->setVerticalSpacing(0);

    QFrame *columnFrame = new QFrame(mainWidget);
    columnFrame->setFrameShape(QFrame::StyledPanel);

    QScrollArea *scrollareaColumn = new QScrollArea(mainWidget);
    scrollareaColumn->setFrameShape(QFrame::NoFrame);
    scrollareaColumn->setWidget(columnFrame);

    QGridLayout *columnLayout = new QGridLayout(columnFrame);
    columnLayout->setHorizontalSpacing(0);
    columnLayout->setVerticalSpacing(0);

    Fits _tmp;
    int  labelHeight = 0;
    if (_tmp.OpenFITS(filename.toLocal8Bit())) {
        int          columns = 0,
                     ext = 1;
        QLabel       *label = NULL;
        dpPushButton *button = NULL;
        QString      sizeString,
                     s;
        char         keyValue[81],
                     columnKey[9];

        // write titles in extension frame
        label = new QLabel("<b>Extension</b>");
        label->adjustSize();
        extensionLayout->addWidget(label, 0, 1, Qt::AlignCenter);
        label = new QLabel("<b>Header</b>");
        label->adjustSize();
        extensionLayout->addWidget(label, 0, 2, Qt::AlignCenter);
        tlabel = new QLabel("<b>Type</b>");
        tlabel->adjustSize();
        extensionLayout->addWidget(tlabel, 0, 3, Qt::AlignCenter);
        label = new QLabel("<b>Size</b>");
        label->adjustSize();
        extensionLayout->addWidget(label, 0, 4, Qt::AlignCenter);

        //
        // write primary in extension frame
        //

        // read primary header
        _tmp.ReadFitsHeader();
        _tmp.getHeaderInformation();

        button = new dpPushButton("PRIMARY", this, 0, -1);
        extensionLayout->addWidget(button, 1, 1);
        connect(button, SIGNAL(dpPushButtonClicked(int&, int&)),
                this, SLOT(extensionButtonClicked(int&, int&)));

        QString H = "...";
        int hWidth = 20;
        button = new dpPushButton(H.trimmed(), this, 0, -1, hWidth);
        extensionLayout->addWidget(button, 1, 2);
        connect(button, SIGNAL(dpPushButtonClicked(int&, int&)),
                this, SLOT(headerButtonClicked(int&, int&)));

        label = new QLabel("IMAGE");
        label->adjustSize();
        extensionLayout->addWidget(label, 1, 3, Qt::AlignCenter);

        if (_tmp.Naxis(1) == 0) {
            sizeString = "empty";
        } else {
            sizeString = QString::number(_tmp.Naxis(1));
            for (int i = 2; i <= _tmp.Naxis(0); i++) {
                sizeString += " x " + QString::number(_tmp.Naxis(i));
            }
        }
        label = new QLabel(sizeString);
        extensionLayout->addWidget(label, 1, 4, Qt::AlignCenter);

        button = new dpPushButton("load", this, 0, -1);
        columnLayout->addWidget(button, 1, 0);
        connect(button, SIGNAL(dpPushButtonClicked(int&, int&)),
                this, SLOT(extensionButtonClicked(int&, int&)));

        // loop through extensions
        int nrColHeadersAdded = 0;
        while (_tmp.ReadFitsExtensionHeader(ext, TRUE) > 0) {
            QLabel *labeli = new QLabel(QString::number(ext), this);
            extensionLayout->addWidget(labeli, ext+1, 0);

            _tmp.getHeaderInformation();
            if (_tmp.GetStringKey("EXTNAME", keyValue)) {
                s = keyValue;
            } else {
                s = QString("ext ") + QString::number(ext);
            }

            // create a button to open all columns in a fitsarr
            int row = ext;
            int col = 0;
            if (_tmp.extensionType == IMAGE) {
                col = -1;
            }
            dpPushButton *cbutton = new dpPushButton(s.trimmed(), this, row, col);
            extensionLayout->addWidget(cbutton, ext+1, 1);
            connect(cbutton, SIGNAL(dpPushButtonClicked(int&, int&)),
                    this, SLOT(extensionButtonClicked(int&, int&)));

            button = new dpPushButton(H.trimmed(), this, row, col, hWidth);
            extensionLayout->addWidget(button, ext+1, 2);
            connect(button, SIGNAL(dpPushButtonClicked(int&, int&)),
                    this, SLOT(headerButtonClicked(int&, int&)));

            switch (_tmp.extensionType) {
                case IMAGE:     s = "IMAGE";        break;
                case TABLE:     s = "TABLE";        break;
                case BINTABLE:  s = "BINARY TABLE"; break;
                case UNKNOWN:   s = "UNKNOWN";      break;
                default:        s = "PRIMARY";      break;
            }

            QLabel *labeltype = new QLabel(s, this);
            extensionLayout->addWidget(labeltype, ext+1, 3, Qt::AlignCenter);
            if (_tmp.Naxis(1) == 0) sizeString = "empty";
            else {
                switch (_tmp.extensionType) {
                    case IMAGE:
                        sizeString = QString::number(_tmp.Naxis(1));
                        for (int i = 2; i <= _tmp.Naxis(0); i++) {
                            sizeString += " x " + QString::number(_tmp.Naxis(i));
                        }
                        break;
                    case BINTABLE:
                        _tmp.GetIntKey("TFIELDS", &columns);
                        sizeString = QString::number(columns);
                        sizeString += " x " + QString::number(_tmp.Naxis(2));
                        break;
                    default:
                        sizeString = "";
                        break;
                }
            }
            QLabel *labelsize = new QLabel(sizeString);
            extensionLayout->addWidget(labelsize, ext+1, 4, Qt::AlignCenter);

            if (_tmp.extensionType == BINTABLE) {
                QString s, t;
                int width = 0, repeat = 0;
                char fieldtype;

                for (column = 1; column <= columns; column++) {
                    if (nrColHeadersAdded < column) {
                        label = new QLabel("<b>#" + QString::number(column) + "</b>");
                        columnLayout->addWidget(label, 0, column-1, Qt::AlignCenter);
                        nrColHeadersAdded++;
                    }

                    sprintf(columnKey, "TTYPE%i", column);
                    if (_tmp.GetStringKey(columnKey, keyValue)) {
                        s = keyValue;
                    } else {
                        s = QString::number(column);
                    }
                    if (_tmp.tfieldWidth(column, &width, &repeat, &fieldtype)) {
                        t = QString::number(repeat);
                        t += " column";
                        if (repeat > 1) {
                            t += "s";
                        }
                        sprintf(columnKey, "TDIM%i", column);
                        if (_tmp.GetStringKey(columnKey, keyValue)) {
                            t += " ";
                            t += QString(keyValue).trimmed();
                        }
                        switch (fieldtype) {
                            case 'A': t += ", ASCII string";    break;
                            case 'B': t += ", B";               break;
                            case 'L': t += ", 1 byte integers"; break;
                            case 'I': t += ", 2 byte integers"; break;
                            case 'J': t += ", 4 byte integers"; break;
                            case 'E': t += ", 4 byte floats";   break;
                            case 'D': t += ", 8 byte doubles";  break;
                            case 'C': t += ", 8 byte float complex";  break;
                            case 'M': t += ", 16 byte double complex";  break;
                            default:                            break;
                        }
                    } else {
                        t = "";
                    }

                    dpPushButton *cbutton = new dpPushButton(s.trimmed(), this, ext, column);
                    if (labelHeight == 0) {
                        cbutton->adjustSize();
                        labelHeight = cbutton->height();
                    }
                    if (t.length() > 0) {
                        cbutton->setToolTip(t);
                    }
                    columnLayout->addWidget(cbutton, ext+1, column-1);
                    connect(cbutton, SIGNAL(dpPushButtonClicked(int&, int&)),
                            this, SLOT(extensionButtonClicked(int&, int&)));
                }
            } else if (_tmp.extensionType == IMAGE) {
                if (nrColHeadersAdded < 1) {
                    label = new QLabel("<b>#1</b>");
                    columnLayout->addWidget(label, 0, 0, Qt::AlignCenter);
                    nrColHeadersAdded++;
                }
                column = -1;
                dpPushButton *cbutton = new dpPushButton("load", this, ext, column);
                if (labelHeight == 0) {
                    cbutton->adjustSize();
                    labelHeight = cbutton->height();
                }
                columnLayout->addWidget(cbutton, ext+1, 0);
                connect(cbutton, SIGNAL(dpPushButtonClicked(int&, int&)),
                        this, SLOT(extensionButtonClicked(int&, int&)));
            }
            ext++;
        }
    }
    _tmp.CloseFITS();

    int height = labelHeight + 2,
        extCnt = extensionLayout->rowCount(),
        colCnt = columnLayout->rowCount(),
        shiftScrollareaColumn = 20;
#ifdef Q_OS_MACX
    height = labelHeight-5,
    extCnt = 1,
    colCnt = 1;
#endif
    for (int i = 0; i < extCnt; i++) {
        extensionLayout->setRowMinimumHeight(i, height);
    }
    for (int i = 0; i < colCnt; i++) {
        columnLayout->setRowMinimumHeight(i, height);
    }

    extensionFrame->adjustSize();
    columnFrame->adjustSize();

    int dlgWidth = 500;
    if (columnFrame->width() < dlgWidth) {
        dlgWidth = columnFrame->width()+1;
    }
    scrollareaColumn->setGeometry(extensionFrame->x() + extensionFrame->width() + 5, extensionFrame->y(),
                                  dlgWidth, extensionFrame->height()+20);

    int dlgHeight = 400;
    mainWidget->adjustSize();
    if (mainWidget->height() < dlgHeight) {
        dlgHeight = mainWidget->height();
        shiftScrollareaColumn = 0;
    }
    scrollareaMain->setGeometry(10, 10, mainWidget->width()+20, dlgHeight);

    scrollareaColumn->horizontalScrollBar()->setParent(this);
    scrollareaColumn->horizontalScrollBar()->setMinimumWidth(scrollareaColumn->width());
    scrollareaColumn->horizontalScrollBar()->move(scrollareaColumn->x() + mainWidget->x() + 10,
                                                  scrollareaMain->height() + shiftScrollareaColumn);

    if (columnFrame->width() < scrollareaColumn->width()) {
        scrollareaColumn->horizontalScrollBar()->hide();
    }

    if (fromCmdLine && (!isNewBuffer)) {
        exitButton = new QPushButton("Exit", this);
        connect(exitButton, SIGNAL(clicked()), this, SLOT(exitClicked()));
        exitButton->setGeometry(10, scrollareaMain->height() + 10 + shiftScrollareaColumn, 100, 30);
        exitButton->setDefault(true);
    } else {
        cancelButton = new QPushButton("Cancel", this);
        connect(cancelButton, SIGNAL(clicked()), this, SLOT(closeDialog()));
        cancelButton->setGeometry(10, scrollareaMain->height() + 10 + shiftScrollareaColumn, 100, 30);
        cancelButton->setDefault(true);
    }

    okButton = new QPushButton("Read All", this);
    okButton->setGeometry(10+200, scrollareaMain->height() + 10 + shiftScrollareaColumn, 100, 30);
    okButton->setDefault(true);
    connect(okButton, SIGNAL(clicked()),
            this, SLOT(readAllExtensionsClicked()));

    connect(this, SIGNAL(rejected()),
            this, SLOT(rejectDialog()));

    adjustSize();
    setFixedSize(size());
}


dpFitsExtensionDialog::~dpFitsExtensionDialog() {
    rejectDialog();
}

void dpFitsExtensionDialog::updateExtensionNumber(const int &ext) {
	extension = ext;
}

void dpFitsExtensionDialog::updateColumnNumber(const int &col) {
	column = col;
}

void dpFitsExtensionDialog::extensionButtonClicked(int &ext, int &col) {
    QString cmd;

    if (isNewBuffer) {
        cmd = freeBufferName().c_str();
    } else {
        cmd = QString(svariables[fitsMainWindow->getCurrentBufferIndex()].c_str());
    }
    if (col >= 0) {
        cmd += " = ";
        cmd += "readfitsbintable(\"";
        cmd += filename;
        cmd += "\", ";
        cmd += QString::number(ext);
        cmd += ", ";
        cmd += QString::number(col);
        cmd += ")";
    } else {
        cmd += " = ";
        if (ext == 0) {
            cmd += "readfits(\"";
            cmd += filename;
            cmd += "\")";
        } else  {
            cmd += "readfitsextension(\"";
            cmd += filename;
            cmd += "\", ";
            cmd += QString::number(ext);
            cmd += ")";
        }
    }
    dpuser_widget->executeCommand(cmd);

    QFileInfo finfo(filename);
    settings.lastOpenPath = finfo.absoluteDir().path();
    settings.lastOpenPath.replace("\\", "/");

    closeDialog();
}

void dpFitsExtensionDialog::headerButtonClicked(int &ext, int&) {
    bool ok = false;
    Fits _tmp;
    if (_tmp.OpenFITS(filename.toLocal8Bit())) {
        if (ext == 0) {
            if (_tmp.ReadFitsHeader() > 0) {
                ok = true;
            }
        } else if (ext > 0) {
            if (_tmp.ReadFitsExtensionHeader(ext, TRUE) > 0) {
                ok = true;
            }
        }
    }
    if (ok) {
        if (!headerView->isVisible()) {
            headerView->move(mapToGlobal(tlabel->pos()));
        }
        headerView->showUp(&_tmp);
    }
}

void dpFitsExtensionDialog::readAllExtensionsClicked() {
    QString cmd;
    if (isNewBuffer) {
        cmd = freeBufferName().c_str();
    } else {
        cmd = QString(svariables[fitsMainWindow->getCurrentBufferIndex()].c_str());
    }
    cmd += " = readfitsall(\"" + filename + "\")";
    dpuser_widget->executeCommand(cmd);

    QFileInfo finfo(filename);
    settings.lastOpenPath = finfo.absoluteDir().path();
    settings.lastOpenPath.replace("\\", "/");

    closeDialog();
}

void dpFitsExtensionDialog::rejectDialog() {
    delete headerView; headerView = NULL;
}

void dpFitsExtensionDialog::closeDialog() {
    // done() emits a rejected() SIGNAL
    // which in return calls closeDialog() again
    // and thus deletes headerView
    done(0);
}

void dpFitsExtensionDialog::exitClicked() {
    // done() emits a rejected() SIGNAL
    // which in return calls closeDialog() again
    // and thus deletes headerView
    dpuser_widget->executeCommand(QString("exit"));
    dpuserthread.wait(1000);

    ::exit(0);
    done(0);
}
