/*
 *   This file is part of Dianara
 *   Copyright 2012-2016  JanKusanagi JRR <jancoding@gmx.com>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .
 */

#include "pageselector.h"


PageSelector::PageSelector(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle(tr("Jump to page") + " - Dianara");
    this->setWindowIcon(QIcon::fromTheme("go-next-view-page",
                                         QIcon(":/images/button-next.png")));
    this->setWindowFlags(Qt::Dialog);
    this->setWindowModality(Qt::ApplicationModal);

    this->initialPage = 1;

    // Top
    this->messageLabel = new QLabel(tr("Page number:"),
                                    this);

    this->pageNumberSpinbox = new QSpinBox(this);
    pageNumberSpinbox->setRange(1, 1); // 1 to totalPages, but initially 1-1
    pageNumberSpinbox->setValue(1);
    connect(pageNumberSpinbox, SIGNAL(editingFinished()),
            this, SLOT(onPageNumberEntered()));
    connect(pageNumberSpinbox, SIGNAL(valueChanged(int)),
            this, SLOT(toggleGoButton(int)));

    this->rangeLabel = new QLabel(this);


    this->firstButton = new QPushButton(QIcon::fromTheme("go-first-view-page",
                                                            QIcon(":/images/button-previous.png")),
                                           tr("&First", "As in: first page"),
                                           this);
    connect(firstButton, SIGNAL(clicked()),
            this, SLOT(setToFirstPage()));

    this->lastButton = new QPushButton(QIcon::fromTheme("go-last-view-page",
                                                            QIcon(":/images/button-next.png")),
                                           tr("&Last", "As in: last page"),
                                           this);
    connect(lastButton, SIGNAL(clicked()),
            this, SLOT(setToLastPage()));


    // Middle
    this->newerLabel = new QLabel("< " + tr("Newer",
                                            "As in: newer pages"), this);

    this->pageNumberSlider = new QSlider(Qt::Horizontal, this);
    pageNumberSlider->setRange(1, 1);  // Initially
    pageNumberSlider->setValue(1);
    pageNumberSlider->setTickPosition(QSlider::TicksBelow);


    // Make spinbox and slider keep in sync
    connect(pageNumberSpinbox, SIGNAL(valueChanged(int)),
            pageNumberSlider, SLOT(setValue(int)));
    connect(pageNumberSlider, SIGNAL(valueChanged(int)),
            pageNumberSpinbox, SLOT(setValue(int)));


    this->olderLabel = new QLabel(tr("Older",
                                     "As in: older pages") + " >", this);



    // Bottom
    this->goButton = new QPushButton(QIcon::fromTheme("go-next-view-page",
                                                      QIcon(":/images/button-next.png")),
                                     "  " + tr("&Go") + " >>  ",
                                     this);
    goButton->setDisabled(true);
    connect(goButton, SIGNAL(clicked()),
            this, SLOT(goToPage()));


    this->closeButton = new QPushButton(QIcon::fromTheme("dialog-cancel",
                                                         QIcon(":/images/button-cancel.png")),
                                        tr("&Cancel"),
                                        this);
    connect(closeButton, SIGNAL(clicked()),
            this, SLOT(hide()));


    closeAction = new QAction(this);
    closeAction->setShortcut(QKeySequence(Qt::Key_Escape));
    connect(closeAction, SIGNAL(triggered()),
            this, SLOT(hide()));
    this->addAction(closeAction);


    // Layout
    this->topLayout = new QHBoxLayout();
    topLayout->addWidget(messageLabel);
    topLayout->addSpacing(4);
    topLayout->addWidget(pageNumberSpinbox);
    topLayout->addSpacing(4);
    topLayout->addWidget(rangeLabel);
    topLayout->addSpacing(8);
    topLayout->addStretch(1);
    topLayout->addWidget(firstButton);
    topLayout->addWidget(lastButton);


    this->middleLayout = new QHBoxLayout();
    middleLayout->addWidget(newerLabel);
    middleLayout->addSpacing(4);
    middleLayout->addWidget(pageNumberSlider);
    middleLayout->addSpacing(4);
    middleLayout->addWidget(olderLabel);


    this->bottomLayout = new QHBoxLayout();
    bottomLayout->setAlignment(Qt::AlignRight);
    bottomLayout->addWidget(goButton);
    bottomLayout->addWidget(closeButton);


    this->mainLayout = new QVBoxLayout();
    mainLayout->addLayout(topLayout);
    mainLayout->addSpacing(24);
    mainLayout->addStretch(1);
    mainLayout->addLayout(middleLayout);
    mainLayout->addStretch(2);
    mainLayout->addSpacing(32);
    mainLayout->addLayout(bottomLayout);
    this->setLayout(mainLayout);


    qDebug() << "PageSelector created";
}

PageSelector::~PageSelector()
{
    qDebug() << "PageSelector destroyed";
}

/*
 * To be called from TimeLine()
 *
 * Set current page based on current Timeline page, and total page count
 *
 */
void PageSelector::showForPage(int currentPage, int totalPageCount)
{
    this->initialPage = currentPage;

    this->pageNumberSpinbox->setRange(1, totalPageCount);
    this->pageNumberSpinbox->setValue(currentPage);

    this->pageNumberSlider->setRange(1, totalPageCount);
    // Value will get sync'ed from pageNumberSpinbox
    this->pageNumberSlider->setTickInterval(totalPageCount / 4); // One tick every 1/4th

    this->rangeLabel->setText(QString("[ 1 - %1 ]")
                              .arg(QLocale::system().toString(totalPageCount)));

    this->show();
    this->pageNumberSpinbox->setFocus();
}


////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// SLOTS /////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


void PageSelector::setToFirstPage()
{
    this->pageNumberSpinbox->setValue(this->pageNumberSpinbox->minimum());
}


void PageSelector::setToLastPage()
{
    this->pageNumberSpinbox->setValue(this->pageNumberSpinbox->maximum());
}


void PageSelector::goToPage()
{
    emit pageJumpRequested(this->pageNumberSpinbox->value());

    this->hide();
}



void PageSelector::onPageNumberEntered()
{
    // If spinbox still has focus, it means ENTER was pressed
    if (this->pageNumberSpinbox->hasFocus())
    {
        this->goToPage();
    }

    // If not, it means focus when somewhere else,
    // which also causes editingFinished() to be emitted
}

/*
 * Enable/disable 'Go' button depending on currently selected page
 *
 */
void PageSelector::toggleGoButton(int selectedPage)
{
    this->goButton->setDisabled(selectedPage == this->initialPage);
}


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// PROTECTED ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


void PageSelector::hideEvent(QHideEvent *event)
{
    this->goButton->setDisabled(true); // Disabled for next use of the dialog
    event->accept();
}
