/***************************************************************************
 *   Copyright (C) 2007 by Arnold Kraschinski                              *
 *   arnold.kra67@gmx.de                                                   *
 *                                                                         *
 *   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 "controlline.h"

// Qt header files
#include <QWidget>
#include <QPainter>
#include <QSvgRenderer>
#include <QSizePolicy>
#include <QMouseEvent>
#include <QPaintEvent>

// KDE header files
#include <kdebug.h>
#include <kpushbutton.h>
#include <kguiitem.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kglobalsettings.h>

// Project header files
#include "kverbos.h"
#include "qlearning.h"

const double ControlLine::svgWidth = 1000.0;
const double ControlLine::svgHeight = 130.0;

const double ControlLine::buttonWidth = 55.0;
const double ControlLine::buttonHeight = 55.0;
const double ControlLine::buttonScaleX = buttonWidth / svgWidth;
const double ControlLine::buttonScaleY = buttonHeight / svgHeight;
const double ControlLine::buttonWidth2 = 57.500;
const double ControlLine::buttonHeight2 = 73.500;
const double ControlLine::buttonScaleX2 = buttonWidth2 / svgWidth;
const double ControlLine::buttonScaleY2 = buttonHeight2 / svgHeight;
const double ControlLine::buttonWidth3 = 73.500;
const double ControlLine::buttonScaleX3 = buttonWidth3 / svgWidth;

// Position of the upper left corner of the button viewed from the upper left corner
const double ControlLine::configPos = 36.797;
const double ControlLine::helpPos = 151.500;
const double ControlLine::nextPos = 672.500;
const double ControlLine::menuPos = 787.500;
const double ControlLine::quitPos = 902.500;
const double ControlLine::handbookPos = 209.812;
const double ControlLine::aboutAppPos = 267.312;
const double ControlLine::aboutKDEPos = 324.812;

const double ControlLine::yPos = 37.500;
const double ControlLine::yPos2 = 28.250;

ControlLine::ControlLine(QWidget* parent)
: QWidget(parent), m_overConfig(false), m_overHelp(false), m_overNext(false),
  m_overMenu(false), m_overQuit(false), m_overHandbook(false), m_overAboutApp(false),
  m_overAboutKDE(false)
{
    m_nextText = i18n("Go On");
    setAttribute(Qt::WA_StaticContents);
    m_renderer = new QSvgRenderer(KStandardDirs::locate("appdata", "images/kverbos.svg"));

    setMouseTracking(true);

    setMinimumSize(726, 94);
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
    
    //setWhatsThis( i18n( "Control the program through this buttons" ) );
    //setToolTip( i18n( "Control the program through this buttons" ) );
}

void ControlLine::paintEvent(QPaintEvent *)
{
    QPixmap buf(width(), height());
    QPainter p(&buf);
    p.setRenderHint(QPainter::Antialiasing);

    m_renderer->render(&p, "background");

    //m_xRatio = width() / svgWidth;
    //m_yRatio = height() / svgHeight;

    double y = yPos * m_yRatio;
    if (m_overConfig) {
        p.translate( configPos * m_xRatio, y );
        p.scale(buttonScaleX, buttonScaleY);
        m_renderer->render(&p, "config_hover");
        p.resetMatrix();
        drawHelpText(p, i18n("Configure Kverbos"));
    }
    if (m_overHelp) {
        p.translate( helpPos * m_xRatio, y );
        p.scale(buttonScaleX, buttonScaleY);
        m_renderer->render(&p, "help_hover");
        p.resetMatrix();
        
        double y = yPos2 * m_yRatio;
        if(m_overHandbook) {
            p.translate( handbookPos * m_xRatio, y );
            p.scale(buttonScaleX2, buttonScaleY2);
            m_renderer->render(&p, "handbook_r_hover");
            p.resetMatrix();
            drawHelpText(p, i18n("Kverbos Handbook"));
        } else {
            p.translate( handbookPos * m_xRatio, y );
            p.scale(buttonScaleX2, buttonScaleY2);
            m_renderer->render(&p, "handbook_r");
            p.resetMatrix();
        }

        if(m_overAboutApp) {
            p.translate( aboutAppPos * m_xRatio, y );
            p.scale(buttonScaleX2, buttonScaleY2);
            m_renderer->render(&p, "appicon_r_hover");
            p.resetMatrix();
            drawHelpText(p, i18n("About Kverbos"));
        } else {
            p.translate( aboutAppPos * m_xRatio, y );
            p.scale(buttonScaleX2, buttonScaleY2);
            m_renderer->render(&p, "appicon_r");
            p.resetMatrix();
        }

        if(m_overAboutKDE) {
            p.translate( aboutKDEPos * m_xRatio, y );
            p.scale(buttonScaleX3, buttonScaleY2);
            m_renderer->render(&p, "kicon_r_hover");
            p.resetMatrix();
            drawHelpText(p, i18n("About KDE"));
        } else {
            p.translate( aboutKDEPos * m_xRatio, y );
            p.scale(buttonScaleX3, buttonScaleY2);
            m_renderer->render(&p, "kicon_r");
            p.resetMatrix();
        }
    }

    if (m_overNext) {
        p.translate( nextPos * m_xRatio, y );
        p.scale(buttonScaleX, buttonScaleY);
        m_renderer->render(&p, "next_hover");
        p.resetMatrix();
        drawHelpText(p, m_nextText );
    }

    if (m_overMenu) {
        p.translate( menuPos * m_xRatio, y );
        p.scale(buttonScaleX, buttonScaleY);
        m_renderer->render(&p, "menu_hover");
        p.resetMatrix();
        drawHelpText(p, i18n("Show Menu"));
    }

    if (m_overQuit) {
        p.translate( quitPos * m_xRatio, y );
        p.scale(buttonScaleX, buttonScaleY);
        m_renderer->render(&p, "quit_hover");
        p.resetMatrix();
        drawHelpText(p, i18n("Quit Kverbos"));
    }

    QPainter p2(this);
    p2.drawPixmap(0, 0, buf);
}

void ControlLine::drawHelpText(QPainter &p, const QString &text)
{
	p.save();
	QFont font = KGlobalSettings::generalFont();
	font.setPointSize(16);
	p.setFont(font);
	// translate to the same place as the folder plus a margin
	p.translate(400.000 * m_xRatio, 60.0 * m_yRatio);
	p.setPen(Qt::black);

	// draw the first word
	p.drawText(0, 0, text.section(' ', 0, 0));
	// draw the second word under the first
	p.drawText(0, int(30.0 * m_yRatio), text.section(' ', 1));
	p.restore();
}

void ControlLine::resizeEvent(QResizeEvent *)
{
    m_xRatio = width() / svgWidth;
    m_yRatio = height() / svgHeight;

    double w = buttonWidth2 * m_xRatio;
    double h = buttonHeight2 * m_yRatio;
    double x = handbookPos * m_xRatio;
    double y = yPos2 * m_yRatio;
    m_handbookRect = QRect( int(x), int(y), int(w), int(h) );
    x = aboutAppPos * m_xRatio;
    m_aboutAppRect = QRect( int(x), int(y), int(w), int(h) );
    w = buttonWidth3 * m_xRatio;
    x = aboutKDEPos * m_xRatio;
    m_aboutKDERect = QRect( int(x), int(y), int(w), int(h) );

    w = buttonWidth * m_xRatio;
    h = buttonHeight * m_yRatio;
    x = configPos * m_xRatio;
    y = yPos * m_yRatio;
    m_configRect = QRect( int(x), int(y), int(w), int(h) );
    x = helpPos * m_xRatio;
    m_helpRect = QRect( int(x), int(y), int(w), int(h) );
    x = nextPos * m_xRatio;
    m_nextRect = QRect( int(x), int(y), int(w), int(h) );
    x = menuPos * m_xRatio;
    m_menuRect = QRect( int(x), int(y), int(w), int(h) );
    x = quitPos * m_xRatio;
    m_quitRect = QRect( int(x), int(y), int(w), int(h) );

    update();
}

/** sets or clears flag based on whether p is in rect, and set changed if flag changes */
void ControlLine::CheckRect(const QRect &rect, const QPoint &p, bool &flag, bool &changed)
{
    bool inside = rect.contains(p);
    changed = (!inside && flag) || (!flag && inside) || changed;
    flag = inside;
}

void ControlLine::mouseMoveEvent(QMouseEvent *e)
{
    QPoint p = e->pos();
    bool haveToUpdate = false;

    CheckRect(m_configRect, p, m_overConfig, haveToUpdate);
    CheckRect(m_helpRect, p, m_overHelp, haveToUpdate);
    if (m_overHelp) {
        // extend the rect
        m_helpRect = QRect(int(helpPos * m_xRatio), int(yPos * m_yRatio), int(226.291 * m_xRatio), int(buttonHeight * m_yRatio));
        CheckRect(m_handbookRect, p, m_overHandbook, haveToUpdate);
        CheckRect(m_aboutAppRect, p, m_overAboutApp, haveToUpdate);
        CheckRect(m_aboutKDERect, p, m_overAboutKDE, haveToUpdate);
    } else {
        // calculate the normal rect
        m_helpRect = QRect(int(helpPos * m_xRatio), int(yPos * m_yRatio), int(buttonWidth * m_xRatio), int(buttonHeight * m_yRatio));
        m_overHandbook = m_overAboutApp = m_overAboutKDE = false;
    }
    CheckRect(m_nextRect, p, m_overNext, haveToUpdate);
    CheckRect(m_menuRect, p, m_overMenu, haveToUpdate);
    CheckRect(m_quitRect, p, m_overQuit, haveToUpdate);

    if(m_overConfig || m_overHelp || m_overNext || m_overMenu || m_overQuit || m_overAboutKDE || m_overHandbook || m_overAboutApp )
    {
        this->setCursor(Qt::PointingHandCursor);
    }
    else {
        this->unsetCursor();
    }

    if (haveToUpdate) {
        update();
    }
}

void ControlLine::mousePressEvent(QMouseEvent *e)
{
    if ( m_configRect.contains(e->pos()) ) {
        emit signalConfig();
    }

    if  (m_handbookRect.contains(e->pos()) && m_overHelp ) {
        emit signalHandbook();
    }

    if ( m_aboutAppRect.contains(e->pos()) && m_overHelp ) {
        emit signalAboutApp();
    }

    if ( m_aboutKDERect.contains(e->pos()) && m_overHelp ) {
        emit signalAboutKDE();
    }

    if ( m_nextRect.contains(e->pos()) ) {
        emit signalNext();
    }

    if ( m_menuRect.contains(e->pos()) ) {
        emit signalMenu();
    }

    if ( m_quitRect.contains(e->pos()) ) {
        emit signalQuit();
    }
}

void ControlLine::connectButtons(Kverbos* kverbos)
{
    connect( this, SIGNAL( signalConfig() ), kverbos, SLOT( slotConfig() ) );
    connect( this, SIGNAL( signalHandbook() ), kverbos, SLOT( slotHandbook() ) );
    connect( this, SIGNAL( signalAboutApp() ), kverbos, SLOT( slotAboutApp() ) );
    connect( this, SIGNAL( signalAboutKDE() ), kverbos, SLOT( slotAboutKDE() ) );
    connect( this, SIGNAL( signalNext() ), kverbos, SLOT( slotNext() ) );
    connect( this, SIGNAL( signalMenu() ), kverbos, SLOT( slotMenu() ) );
    connect( this, SIGNAL( signalQuit() ), kverbos, SLOT( slotExit() ) );
}

void ControlLine::connectNextButton(QLearning* learning)
{
    connect( this, SIGNAL( signalNext() ), learning, SLOT( slotNext() ) );
}

void ControlLine::slotSetNextText(QString text)
{
    m_nextText = text;
    update();
}


#include "controlline.moc"
