#include <QResizeEvent>

#include "QFitsMainWindow.h"
#include "QFitsGlobal.h"
#include "QFitsHeaderView.h"
#include "imred.h"

#define FITS_EMPTY "                                                                                "

QFitsHeaderContent::QFitsHeaderContent(QWidget *parent)
    : QTextEdit(parent) {
    setMouseTracking(TRUE);
}

void QFitsHeaderContent::mouseMoveEvent(QMouseEvent *m) {
    QTextEdit::ExtraSelection highlight;
    highlight.cursor = cursorForPosition(m->pos());
    QList<QTextEdit::ExtraSelection> extras;
    if (!highlight.cursor.atEnd()) {
        highlight.cursor.select(QTextCursor::LineUnderCursor);
        if (highlight.cursor.selectedText() != FITS_EMPTY) {
            highlight.format.setProperty(QTextFormat::FullWidthSelection, true);
            highlight.format.setBackground( Qt::green );

            extras << highlight;
        }
    }
    setExtraSelections(extras);
}

QFitsHeaderView::QFitsHeaderView(QWidget *parent) : QDialog(parent) {
    setWindowTitle("QFitsView - Header Display");

    QFont theFont(settings.textfont, settings.textsize);
    QFontMetrics f(theFont);
    int pwidth = f.width("MM") * 44;

    content = new QFitsHeaderContent(this);
    content->setGeometry(0, 25, pwidth, 300);
    content->setReadOnly(true);
    content->setWordWrapMode(QTextOption::NoWrap);
    content->setMouseTracking(TRUE);

    searchLabel = new QLabel("Search:", this);
    searchLabel->setGeometry(0, 0, 150, 25);
    searchLabel->setAlignment(Qt::AlignRight|Qt::AlignVCenter);

    searchTerm = new QLineEdit(this);

    searchAgain = new QPushButton("next", this);
    searchAgain->setEnabled(false);

    connect(searchTerm, SIGNAL(textEdited(const QString &)),
            this, SLOT(dosearch(const QString &)));
    connect(searchAgain, SIGNAL(clicked()),
            this, SLOT(dosearchagain()));

    content->setStyleSheet(content->styleSheet() + "; selection-background-color: yellow; selection-color: black; font-family: " + settings.textfont + "; font-size: " + QString::number(settings.textsize) + "pt");
//    content->setStyleSheet("selection-background-color: yellow; selection-color: black; border: none; font-family: " + settings.textfont + "; font-size: " + QString::number(settings.textsize) + "pt");

    oldfont = settings.textfont;
    oldfontsize = settings.textsize;

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

    editWCSButton = new QPushButton("Edit WCS", this);
    editWCSButton->setGeometry(0, 0, 100, 25);
    connect(editWCSButton, SIGNAL(clicked()),
            this, SLOT(editWCS()));
}

void QFitsHeaderView::showUp(Fits *f) {
    if (f != NULL) {
        if (buffersLock.tryLockForWrite()) {
            f->updateHeader();
            buffersLock.unlock();
        }
        buffersLock.lockForRead();
        QString header = f->GetHeader();
        buffersLock.unlock();

        QString text = "";
        for (int i = 0; i < header.length(); i += 80) {
            text += header.mid(i, 80);
            text += '\n';
        }
        text.chop(1);
        content->setText(text);
        show();
    }
}

void QFitsHeaderView::resizeEvent(QResizeEvent *e) {
    searchLabel->setGeometry(100, 0, e->size().width() - 155 - 100, 25);
    searchTerm->setGeometry(e->size().width() - 150, 0, 100, 25);
    searchAgain->setGeometry(e->size().width() - 50, 0, 50, 25);
    content->setGeometry(0, 25, e->size().width(), e->size().height() - 40 - 25);
    closeButton->setGeometry(e->size().width() / 2 - 50, e->size().height() - 30, 100, 30);
    editWCSButton->setGeometry(0, 0, 100, 25);
}

void QFitsHeaderView::keyPressEvent(QKeyEvent *e) {
    if ((e->key() == Qt::Key_F) && (e->modifiers() & Qt::CTRL)) {
        searchTerm->setFocus();
    } else if (e->key() == Qt::Key_F3) {
        dosearchagain();
    } else {
        QDialog::keyPressEvent(e);
    }
//    if ((e->key() == Qt::Key_F3) && (e->modifiers() & Qt::SHIFT)) {
//        dosearchagain2(QTextDocument::FindBackward);
//    }
}

void QFitsHeaderView::dosearch(const QString &text) {
    QPalette palette = searchTerm->palette();
    if (!text.isEmpty()) {
        content->moveCursor(QTextCursor::Start);
        if (content->find(text)) {
            searchAgain->setEnabled(true);
            searchLabel->setText("Search:");
            palette.setColor(QPalette::Active, QPalette::Base, Qt::white);
            palette.setColor(QPalette::Active, QPalette::Text, Qt::black);
        } else {
            searchLabel->setText("not found");
            searchAgain->setEnabled(false);
            palette.setColor(QPalette::Active, QPalette::Base, Qt::red);
            palette.setColor(QPalette::Active, QPalette::Text, Qt::white);
        }
    } else {
        searchAgain->setEnabled(false);
        searchLabel->setText("Search:");
        palette.setColor(QPalette::Active, QPalette::Base, Qt::white);
        palette.setColor(QPalette::Active, QPalette::Text, Qt::black);
    }
    searchTerm->setPalette(palette);
}

void QFitsHeaderView::dosearchagain() {
    if (!searchTerm->text().isEmpty()) {
        if (!content->find(searchTerm->text())) {
            dosearch(searchTerm->text());
        }
    }
}

void QFitsHeaderView::fontchanged() {
    if ((oldfont != settings.textfont) || (oldfontsize != settings.textsize)) {
        oldfont = settings.textfont;
        oldfontsize = settings.textsize;
        content->setStyleSheet("selection-background-color: yellow; "
                               "selection-color: black; "
                               "border: none; "
                               "font-family: " + settings.textfont + "; "
                               "font-size: " + QString::number(settings.textsize) +
                               "pt");
    }
}

void QFitsHeaderView::editWCS() {
    imRedSetWCS::showDialog(fitsMainWindow);
}

QFitsHeaderViewExt::QFitsHeaderViewExt(QWidget *parent) : QFitsHeaderView(parent) {
    editWCSButton->hide();
}

void QFitsHeaderViewExt::showUp(Fits *f) {
    if (f != NULL) {
        QString header = f->GetHeader(),
                text = "";
        for (int i = 0; i < header.length(); i += 80) {
            text += header.mid(i, 80);
            text += '\n';
        }
        text.chop(1);
        content->setText(text);
        show();
        raise();
    }
}
