/**********************************************************************************************
    Copyright (C) 2007 Oliver Eichler oliver.eichler@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., 59 Temple Place - Suite 330, Boston, MA 02111 USA

**********************************************************************************************/

#include "CMenu.h"
#include "CCanvas.h"

#include <QtGui>

#define SPACING 10
#define PADDING 10

CMenu::CMenu(QWidget * parent)
: QWidget(parent, Qt::Popup)
, current(0)
{
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu);

    setMouseTracking(true);

    int w = 200;
    if(parent){
        w = parent->width() * 80 / 100;
        if(w > 400) w = 400;
    }

    resize(w,w);
}

CMenu::~CMenu()
{

}

void CMenu::paintEvent(QPaintEvent */*e*/)
{
    int i;
    QPainter p(this);
    p.setRenderHint(QPainter::Antialiasing);

    QRect r = frameGeometry();
    r.moveTo(0,0);
    r.setWidth(r.width() - 1);
    r.setHeight(r.height() - 1);

    p.setBrush(Qt::lightGray);
    p.setPen(QPen(Qt::black,3));
    p.drawRoundedRect(r,10,10);


    for(i=0; i< 9; ++i){
        if(entries[i].a){
            if(current == &entries[i]){

                QRect r = entries[i].r;
                p.setBrush(QBrush(QColor(200,200,255)));
                p.setPen(QPen(Qt::yellow,3));
                p.drawRoundedRect(r, 10, 10);

                r.setTopLeft(r.topLeft() + QPoint(PADDING,PADDING));
                r.setBottomRight(r.bottomRight() - QPoint(PADDING,PADDING));

                QPixmap pixmap = entries[i].a->icon().pixmap(r.size(), QIcon::Normal).scaled(r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
                p.drawPixmap(r.topLeft(), pixmap);

                QString text = entries[i].a->text();
                CCanvas::drawText(text,p,r.center() + QPoint(0,r.height()>>1), Qt::blue);

            }
            else{
                QRect r = entries[i].r;
                p.setBrush(QBrush(QColor(0,0,255)));
                p.setPen(QPen(Qt::white,3));
                p.drawRoundedRect(r, 10, 10);

                r.setTopLeft(r.topLeft() + QPoint(PADDING,PADDING));
                r.setBottomRight(r.bottomRight() - QPoint(PADDING,PADDING));

                QPixmap pixmap = entries[i].a->icon().pixmap(r.size(), QIcon::Normal).scaled(r.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
                p.drawPixmap(r.topLeft(), pixmap);

                QString text = entries[i].a->text();
                CCanvas::drawText(text,p,r.center() + QPoint(0,r.height()>>1), Qt::black);
            }
        }
        else{
            p.setBrush(QBrush(QColor(100,100,100)));
            p.setPen(QPen(Qt::darkGray,3));
            p.drawRoundedRect(entries[i].r, 10, 10);
        }

    }


}

void CMenu::hideEvent(QHideEvent *)
{
    eventLoop.exit();
}

void CMenu::mouseMoveEvent(QMouseEvent *e)
{
    int i;
    QPoint pos = e->pos();

    for(i=0; i<9; ++i){
        if(entries[i].a && entries[i].r.contains(pos)){
            current = &entries[i];
            break;
        }
    }

    update();
    return QWidget::mouseMoveEvent(e);
}

void CMenu::mousePressEvent(QMouseEvent *e)
{
    if(current && current->a && current->r.contains(e->pos())){
        qDebug() << "trigger:" << current->a->text();
        current->a->activate(QAction::Trigger);
        hide();
    }
    else{
        QWidget::mousePressEvent(e);
    }
}

void CMenu::keyPressEvent(QKeyEvent *e)
{
    int key = e->key();
    bool consumed = false;
    int i;
    for(i = 0; i < 9; ++i){
        if(&entries[i] ==  current) break;
    }

    switch(key){
        case Qt::Key_Up:
            consumed = true;
            if(i < 3) break;
            if(entries[i-3].a){
                i -= 3;
            }
            break;

        case Qt::Key_Down:
            consumed = true;
            if(i > 5) break;
            if(entries[i+3].a){
                i += 3;
            }
            break;

        case Qt::Key_Left:
            consumed = true;
            if((i % 3) == 0) break;
            if(entries[i-1].a){
                i -= 1;
            }
            break;

        case Qt::Key_Right:
            consumed = true;
            if(((i+1) % 3) == 0) break;
            if(entries[i+1].a){
                i += 1;
            }
            break;

        case Qt::Key_Space:
        case Qt::Key_Select:
        case Qt::Key_Enter:
        case Qt::Key_Return:
            consumed = true;
            if(current && current->a) current->a->activate(QAction::Trigger);
            hide();
            break;
    }

    current = &entries[i];

    if (consumed){
        e->accept();
        update();
    }
    else{
        e->ignore();
    }

}

QAction * CMenu::addAction(int idx, const QString& text, const QIcon& icon, QObject * obj, const QString& slot)
{
    if(idx < 0 || idx > 8) return 0;

    entries[idx].a = new QAction(icon, text, this);

    if(obj){
        connect(entries[idx].a, SIGNAL(triggered()), obj, slot.toLatin1());
    }

    current = &entries[idx];

    return current->a;
}

void CMenu::popup(const QPoint& pos)
{
    int w = (width() - SPACING * 4) / 3;

    entries[0].r = QRect(SPACING, SPACING, w, w);
    entries[1].r = QRect(SPACING+w+SPACING, SPACING, w, w);
    entries[2].r = QRect(SPACING+w+SPACING+w+SPACING, SPACING,w,w);
    entries[3].r = QRect(SPACING, SPACING+w+SPACING, w, w);
    entries[4].r = QRect(SPACING+w+SPACING, SPACING+w+SPACING, w, w);
    entries[5].r = QRect(SPACING+w+SPACING+w+SPACING, SPACING+w+SPACING,w,w);
    entries[6].r = QRect(SPACING, SPACING+w+SPACING+w+SPACING, w, w);
    entries[7].r = QRect(SPACING+w+SPACING, SPACING+w+SPACING+w+SPACING, w, w);
    entries[8].r = QRect(SPACING+w+SPACING+w+SPACING, SPACING+w+SPACING+w+SPACING,w,w);

    move(pos);
    show();

}

QAction * CMenu::exec(const QPoint pos)
{
    createWinId();

    popup(pos);

    QPointer<QObject> guard = this;
    (void) eventLoop.exec();
    if (guard.isNull())
        return 0;

    //post processing

    return 0;
}
