/*
 * Copyright (C) 2008 Instituto Nokia de Tecnologia. All rights reserved.
 *
 * This file is part of QZion.
 *
 * QZion 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 3 of the License, or
 * (at your option) any later version.
 *
 * QZion 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 QZion.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "main.h"

#include <iostream>
#include <math.h>
#include <QtGui>
#include <qzion.h>

#define NUM_OBJECTS 3

Scene::Scene(QZionAbstractCanvas *canvas, const QSize &size)
    : state(1), group(new QZionGroup(canvas))
{
    group->setSize(size);

    for (int i = 0; i < NUM_OBJECTS; ++i) {
        QZionRectangle *r = new QZionRectangle(group);
        int c = i * 255 / NUM_OBJECTS;
        r->setColor(QColor(c, c, c));
        r->setSize(QSize(100, 100));
        r->setPos(QPoint((i * 60) % 90, i * 30));
        r->show();
        objects.append(r);
    }

    text = new QZionText(group, QString("zValue sanity check"),
                         QFont("SansSerif", 20, QFont::Bold),
                         QColor(210, 105, 30));
    text->setSize(QSize(size.width() - 250, 100));
    text->setPos(QPoint(200, 50));
    text->setAlignment(QPoint(0.0, 0.0));
    text->show();

    enumeration = new QZionText(group, QString("C B A"),
                                QFont("SansSerif", 20, QFont::Bold),
                                QColor(210, 105, 30));
    enumeration->setSize(QSize(size.width() - 250, 100));
    enumeration->setPos(QPoint(200, 80));
    enumeration->setAlignment(QPoint(0.0, 0.0));
    enumeration->show();

    group->show();
}

Scene::~Scene()
{
    foreach (QZionObject *obj, objects)
        delete obj;
    delete text;
}

static void updateEnumeration(Scene *scene)
{
    QString text;
    QList <QZionObject *> ordered = scene->group->itemsAt(QPoint(90, 90));
    foreach (QZionObject *obj, ordered) {
        int idx = scene->objects.indexOf(qobject_cast<QZionRectangle *>(obj));
        if (idx < 0)
            continue;
        text.append(QString("%1 ").arg(QChar('A' + idx)));
    }
    scene->enumeration->setText(text);
}

void Scene::iterate()
{
    QZionRectangle *A = objects[0];
    QZionRectangle *B = objects[1];
    QZionRectangle *C = objects[2];

#define CASE(num, stmt)                                   \
    case num:                                             \
        stmt;                                             \
    text->raise();                                        \
    enumeration->raise();                                 \
    text->setText(#num ". " #stmt);                       \
    updateEnumeration(this);                              \
    break;

    switch (state) {

        CASE(1, A->raise());
        CASE(2, C->lower());
        CASE(3, B->stackAbove(A));
        CASE(4, A->stackBelow(C));
        CASE(5, A->setZValue(2));
        CASE(6, C->stackBelow(A));
        CASE(7, B->raise());
        CASE(8, C->stackAbove(B));

    default:
        int i = 0;
        foreach (QZionObject *obj, objects) {
            obj->setZValue(i);
            ++i;
        }
        text->raise();
        text->setText("zValue sanity check");
        enumeration->raise();
        enumeration->setText("C B A");
        state = 1;
        return;
    }

    ++state;
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QZionCanvas canvas;
    QSize size(800, 480);

    canvas.setSize(size);
    canvas.show();

    QZionRectangle *bg = new QZionRectangle(&canvas);
    bg->setColor(QColor(255, 255, 255));
    bg->setSize(size);
    bg->show();

    Scene s(&canvas, size - QSize(60, 60));
    s.group->setPos(QPoint(30, 30));

    QObject::connect(
        bg, SIGNAL(signalMousePressEvent(QZionObject *, QMouseEvent *)),
        &s, SLOT(iterate()));

    app.exec();

    return 0;
}
