/***************************************************************************
 * testobject.cpp
 * This file is part of the KDE project
 * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library 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
 * Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 ***************************************************************************/

#include "testobject.h"

#include <QSize>
#include <QPoint>
#include <QRect>
#include <QDate>
#include <QTimer>
#include <QColor>
#include <QFont>
#include <QBrush>

TestObject::TestObject(QObject *parent, const QString &name)
    : QObject(parent)
{
    setObjectName(name);

    qRegisterMetaType<TestObject *>("TestObject");
    //qRegisterMetaType< QList<TestObject*> >("QList<TestObject*>");

    QTimer *timer = new QTimer(this);
    timer->setObjectName("TestTimer");

    setProperty("dynamicProperty", QVariantList() << "Some String" << 99);
}

TestObject::~TestObject()
{
}

QObject *TestObject::createThread(int steps, int msecs, bool start)
{
    TestThread *t = new TestThread(this, steps, msecs);
    if (start) {
        t->run();
    }
    return t;
}

QString TestObject::name()
{
    return objectName();
}

void TestObject::func_void()
{
    //qDebug() << "TestObject::func_void";
}

void TestObject::func_void_int(int)
{
    //qDebug() << "TestObject::func_void_int i=" << i;
}

int TestObject::func_int_int(int i)
{
    //qDebug() << "TestObject::func_int_int i=" << i;
    return i;
}

bool TestObject::func_bool_bool(bool b)
{
    //qDebug() << "TestObject::func_bool_bool b=" << b;
    return b;
}

uint TestObject::func_uint_uint(uint i)
{
    //qDebug() << "TestObject::func_uint_uint i=" << i;
    return i;
}

double TestObject::func_double_double(double d)
{
    //qDebug() << "TestObject::func_double_double d=" << d;
    return d;
}

qlonglong TestObject::func_qlonglong_qlonglong(qlonglong l)
{
    //qDebug() << "TestObject::func_qlonglong_qlonglong l=" << l;
    return l;
}

qulonglong TestObject::func_qulonglong_qulonglong(qulonglong l)
{
    //qDebug() << "TestObject::func_qulonglong_qulonglong l=" << l;
    return l;
}

void TestObject::func_void_qstring_int(QString, int)
{
    //qDebug() << "TestObject::func_void_qstring_int s=" << s << " i=" << i;
}

void TestObject::func_void_qstringlist(QStringList)
{
    //qDebug() << "TestObject::func_void_qstringlist sl=" << sl.join(",");
}

QString TestObject::func_qstring_qstring_int(QString s, int i)
{
    QString r = QString("%1,%2").arg(s).arg(i);
    //qDebug() << "TestObject::func_void_qstring_int s=" << s << " i=" << i << " returnvalue=" << r;
    return r;
}

QByteArray TestObject::func_qbytearray_qbytearray(QByteArray ba)
{
    //qDebug() << "TestObject::func_qbytearray_qbytearray ba=" << ba;
    return ba;
}

QString TestObject::func_qstring_qstring(const QString &s)
{
    //qDebug() << "TestObject::func_qstring_qstring s=" << s;
    return s;
}

QStringList TestObject::func_qstringlist_qstringlist(QStringList sl)
{
    //qDebug() << "TestObject::func_qstringlist_qstringlist sl=" << sl.join(",");
    return sl;
}

QVariantList TestObject::func_qvariantlist_qvariantlist(QVariantList vl)
{
    //qDebug() << "TestObject::func_qvariantlist_qvariantlist vl.count=" << vl.count();
    return vl;
}

QVariantMap TestObject::func_qvariantmap_qvariantmap(QVariantMap vm)
{
    //qDebug() << "TestObject::func_qvariantmap_qvariantmap vm.count=" << vm.count();
    return vm;
}

QVariantList TestObject::func_qobject2qvariantlist(QObject *obj)
{
    //qDebug()<<"TestObject::func_qobject2qvariantlist obj="<<(obj ? obj->objectName() : "NULL");
    QVariant v;
    v.setValue(obj);
    return QVariantList() << v;
}

QObject *TestObject::func_qvariantlist2qobject(QVariantList list)
{
    return list.count() > 0 ? list[0].value<QObject *>() : 0;
}

QSize TestObject::func_qsize_qsize(const QSize &s)
{
    return s;
}
QSizeF TestObject::func_qsizef_qsizef(const QSizeF &s)
{
    return s;
}
QPoint TestObject::func_qpoint_qpoint(const QPoint &p)
{
    return p;
}
QPointF TestObject::func_qpointf_qpointf(const QPointF &p)
{
    return p;
}
QRect TestObject::func_qrect_qrect(const QRect &r)
{
    return r;
}
QRectF TestObject::func_qrectf_qrectf(const QRectF &r)
{
    return r;
}
QUrl TestObject::func_qurl_qurl(const QUrl &u)
{
    return u;
}
const QUrl &TestObject::func_qurl_qstring(const QString &u)
{
    return QUrl(u);
}

QColor TestObject::func_qcolor_qcolor(const QColor &c)
{
    return c;
}
QFont TestObject::func_qfont_qfont(const QFont &f)
{
    return f;
}
QBrush TestObject::func_qbrush_qbrush(const QBrush &b)
{
    return b;
}
QTime TestObject::func_qtime_qtime(const QTime &t)
{
    return t;
}
QDate TestObject::func_qdate_qdate(const QDate &d)
{
    return d;
}
QDateTime TestObject::func_qdatetime_qdatetime(const QDateTime &dt)
{
    return dt;
}

void TestObject::func_void_qvariant(const QVariant &v)
{
    //qDebug() << "TestObject::func_void_qvariant variant.toString=" << v.toString() << " variant.type=" << v.typeName();
}

QVariant TestObject::func_qvariant_qvariant(const QVariant &v)
{
    //qDebug() << "TestObject::func_qvariant_qvariant value=" << v.toString() << " type=" << v.typeName();
    return v;
}

Kross::Object::Ptr TestObject::func_krossobject_krossobject(Kross::Object::Ptr object)
{
    //qDebug() << "TestObject::func_krossobject_krossobject";
    return object;
}

QStringList TestObject::get_krossobject_methods(Kross::Object::Ptr object)
{
    //qDebug() << "TestObject::get_krossobject_methods";
    return object->methodNames();
}

QVariant TestObject::call_krossobject_method(Kross::Object::Ptr object, const QString &methodname, const QVariantList &args)
{
    //qDebug() << "TestObject::call_krossobject_method";
    return object->callMethod(methodname, args);
}

QObject *TestObject::func_createChildTestObject(const QString &objectname)
{
    return new TestObject(this, objectname);
}

void TestObject::func_void_qobject(QObject *)
{
    //qDebug() << "TestObject::func_void_qobject " << (obj ? QString("objectName=%1 className=%2").arg(obj->objectName()).arg(obj->metaObject()->className()) : "NULL");
}

QObject *TestObject::func_qobject_qobject(QObject *obj)
{
    //qDebug() << "TestObject::func_qobject_qobject " << (obj ? QString("objectName=%1 className=%2").arg(obj->objectName()).arg(obj->metaObject()->className()) : "NULL");
    return obj;
}

QWidget *TestObject::func_qwidget_qwidget(QWidget *widget)
{
    //qDebug() << "TestObject::func_qwidget_qwidget " << (widget ? QString("objectName=%1 className=%2").arg(widget->objectName()).arg(widget->metaObject()->className()) : "NULL");
    return widget;
}

void TestObject::func_void_testobject(TestObject *obj)
{
    //qDebug() << "TestObject::func_void_testobject " << (obj ? QString("objectName=%1 className=%2").arg(obj->objectName()).arg(obj->metaObject()->className()) : "NULL");
}

TestObject *TestObject::func_testobject_testobject(TestObject *obj)
{
    //qDebug() << "TestObject::func_testobject_testobject " << (obj ? QString("objectName=%1 className=%2").arg(obj->objectName()).arg(obj->metaObject()->className()) : "NULL");
    return obj;
}

TestObject *TestObject::func_testobject_qobject(QObject *obj)
{
    TestObject *tobj = dynamic_cast<TestObject *>(obj);
    return tobj;
}

void TestObject::func_void_testobjectlist(QList<TestObject *> l)
{
    //qDebug() << "TestObject::func_void_testobjectlist " << l.count();
    foreach (TestObject *obj, l) {
        qDebug() << "  " << (obj ? obj->objectName() : "NULL");
    }
}

QList<TestObject *> TestObject::func_testobjectlist_testobjectlist(QList<TestObject *> l)
{
    //qDebug() << "TestObject::func_testobjectlist_testobjectlist " << l.count();
    return l;
}

void TestObject::connectCallTestFunction(Kross::Action *krossAction, QObject *sender, const QString &signal)
{
    m_krossAction = krossAction;

    QString signalName = signal;
    if (!signalName.startsWith('2')) {
        signalName = QString("2%1").arg(signal);
    }

    connect(sender, signalName.toLatin1().constData(), this, SLOT(callTestFunction()));
}

void TestObject::callTestFunction()
{
    QVariantList arguments;
    arguments << 42;
    m_testFunctionReturnedValue = m_krossAction->callFunction("testFunction", arguments);
}

void TestObject::connectCallTestFunctionException(Kross::Action *krossAction, QObject *sender, const QString &signal)
{
    m_krossAction = krossAction;

    QString signalName = signal;
    if (!signalName.startsWith('2')) {
        signalName = QString("2%1").arg(signal);
    }

    connect(sender, signalName.toLatin1().constData(), this, SLOT(callTestFunctionException()));
}

void TestObject::callTestFunctionException()
{
    QVariantList arguments;
    arguments << 42;
    m_testFunctionReturnedValue = m_krossAction->callFunction("testFunctionException", arguments);
}

QVariant TestObject::testFunctionReturnedValue()
{
    return m_testFunctionReturnedValue;
}

/*****************************************************************************************
 * OtherObject
 */

OtherObject *TestObject::func_otherobject(const QByteArray &name)
{
    if (OtherObject *obj = findChild<OtherObject *>(name)) {
        return obj;
    }
    return new OtherObject(this, name);
}

OtherObject *TestObject::func_otherobject_otherobject(OtherObject *obj)
{
    return obj;
}

QList<OtherObject *> TestObject::func_otherobjectlist_otherobjectlist(QList<OtherObject *> l)
{
    return l;
}

/*****************************************************************************************
 * TestThread
 */

TestThread::TestThread(TestObject *parent, int steps, int msecs)
    : QThread(parent)
    , m_testobject(parent)
    , m_steps(steps)
    , m_msecs(msecs)
{
    //qDebug() << "TestThread::TestThread()";
}

TestThread::~TestThread()
{
    //qDebug() << "TestThread::~TestThread()";
}

void TestThread::emitStepDone(int step)
{
    //qDebug() << "TestThread::emitStepDone() step=" << step;
    emit stepDone(step);
}

QVariant TestThread::callFunction(QObject *action, const QString &functionname, QVariantList arguments)
{
    Kross::Action *a = dynamic_cast<Kross::Action *>(action);
    Q_ASSERT(a);
    return a->callFunction(functionname, arguments);
}

void TestThread::run()
{
    //qDebug() << "TestThread::run()";
    for (int i = 0; i < m_steps; ++i) {
        //qDebug() << "TestThread::run() 1 step=" << i << "m_steps=" << m_steps << "m_msecs=" << m_msecs;
        emit stepDone(i);
        //m_testobject->emitSignalVoid();
        msleep(m_msecs);
    }
}

#include "moc_testobject.cpp"
