#include <QResizeEvent>
#include <QFileDialog>
#include <QtPrintSupport/QPrinter>
#include <QtPrintSupport/QPrintDialog>
#include <QPainter>
#include <QScrollBar>
#include <QClipboard>

#include "QFitsMainWindow.h"
#include "QFitsMainView.h"
#include "QFitsMarkers.h"
#include "QFitsScroller.h"
#include "QFitsWidget2D.h"
#include "QFitsSingleBuffer.h"
#include "QFitsCubeSpectrum.h"
#include "QFitsTools.h"
#include "QFitsViewingTools.h"
#include "fits.h"
#include "QFitsWedge.h"

QFitsWidget2D::QFitsWidget2D(QFitsBaseBuffer *bb) : QFitsBaseWidget(bb) {
    doUpdate = true;
    scroller = new QFitsScroller(this);
    scroller->horizontalScrollBar()->setInvertedControls(true);
    viewer = new QFitsView2D(scroller, this);
    scroller->setWidget(viewer);

    connect(scroller->horizontalScrollBar(), SIGNAL(sliderReleased()),
            this, SLOT(scrollerMoved()));
    connect(scroller->verticalScrollBar(), SIGNAL(sliderReleased()),
            this, SLOT(scrollerMoved()));

    connect(scroller->horizontalScrollBar(), SIGNAL(valueChanged(int)),
            this, SLOT(scrollerValueChanged(int)));
    connect(scroller->verticalScrollBar(), SIGNAL(valueChanged(int)),
            this, SLOT(scrollerValueChanged(int)));

    connect(viewer, SIGNAL(mouseClicked(int, int)),
            scroller, SLOT(processMouseClick(int, int)));
}

QFitsWidget2D::~QFitsWidget2D() {
    if (viewer != NULL) {
        delete viewer;
        viewer = NULL;
    }
    if (scroller != NULL) {
        delete scroller;
        scroller = NULL;
    }
}

void QFitsWidget2D::saveImage() {
    if (myBuffer->getImage() != NULL) {
        QString selectedFilter;
        QString filename = getSaveImageFilename(&selectedFilter);

        if (!filename.isNull()) {
            selectedFilter.remove(0,1);
            if (!filename.endsWith(selectedFilter)) {
                filename += selectedFilter;
            }

            if (fabs(myBuffer->getZoomFactor() - 1.) < 0.001) {
                // 100%
                myBuffer->getImage()->save(filename.toStdString().c_str());
            } else {
                QImage  scaledimage;
                int     imagewidth  = myBuffer->getImage()->width() * myBuffer->getZoomFactor(),
                        imageheight = myBuffer->getImage()->height() * myBuffer->getZoomFactor();

                scaledimage = myBuffer->getImage()->scaled(imagewidth, imageheight);
                scaledimage.save(filename.toStdString().c_str());
            }
            QFileInfo finfo(filename);
            settings.lastSavePath = finfo.absoluteDir().path();
            settings.lastSavePath.replace("\\", "/");
        }
    }
}

void QFitsWidget2D::orientationChanged() {
    viewer->applyZoom();

    viewer->setScrollerImageCenter(getMyBuffer()->getXcenter(),
                                   getMyBuffer()->getYcenter());
}

void QFitsWidget2D::setFlipX(bool b) {
    viewer->setFlipX(b);
}

void QFitsWidget2D::setFlipY(bool b) {
    viewer->setFlipY(b);
}

void QFitsWidget2D::setRotation(int i) {
    viewer->setRotation(i);
}

void QFitsWidget2D::setZoom(double zoomFactor) {
    myBuffer->setZoomFactor(zoomFactor);
    viewer->applyZoom();
}

void QFitsWidget2D::setupColours() {
    viewer->update();
}

void QFitsWidget2D::setImageCenter(double x, double y) {
    viewer->setScrollerImageCenter(x, y);
}

void QFitsWidget2D::scrollerMoved() {
    viewer->scrollerMoved(scroller->horizontalScrollBar()->value(),
                          scroller->verticalScrollBar()->value());
}

void QFitsWidget2D::scrollerValueChanged(int) {
    // Check if slider is pressed, only then update the slider-values
    // It happened, that TotalView is updated before slider-values have been changed
    if (scroller->isSliderActive()) {
        scrollerMoved();
    }
}

void QFitsWidget2D::setMouseTrackingView(bool track) {
    viewer->setMouseTracking(track);
}

QFitsMarkers* QFitsWidget2D::getSourceMarkers() {
    return viewer->getSourceMarkers();
}

void QFitsWidget2D::copyImage(int copymode) {
    // Copy the currently displayed image to the clipboard
    // The variable copymode can have 3 values:
    // 0: copy complete image with zoom = 100%
    // 1: copy what's displayed (will crop)
    // 2: copy complete image at current zoom (default)
    QImage *img = myBuffer->getImage();
    if (img != NULL) {
       QApplication::setOverrideCursor(Qt::WaitCursor);
       switch (copymode) {
           case 0:
               QApplication::clipboard()->setImage(*img, QClipboard::Clipboard);
               break;
           case 1:
               QApplication::clipboard()->setPixmap(viewer->grab());
               break;
           case 2:
               if (fabs(myBuffer->getZoomFactor() -1.) < 0.001) {
                   // 100%
                   QApplication::clipboard()->setImage(*img, QClipboard::Clipboard);
               } else {
                   int imagewidth  = img->width() * myBuffer->getZoomFactor(),
                       imageheight = img->height() * myBuffer->getZoomFactor();
                   QImage scaledimage = img->scaled(imagewidth, imageheight);
                   QApplication::clipboard()->setImage(scaledimage);
               }
               break;
           default:
               break;
       }
       QApplication::restoreOverrideCursor();
    }
}

void QFitsWidget2D::resizeEvent(QResizeEvent *r) {
    scroller->setGeometry(0, 0, r->size().width(), r->size().height());

    viewer->applyZoom();
}

void QFitsWidget2D::printImage() {
    viewer->printImage();
}
