/*
 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
#include "config.h"

#include "BridgeJSC.h"
#include "JSObject.h"
#include "JSValue.h"
#include "interpreter.h"
#include "qdebug.h"
#include "qobject.h"
#include "runtime_object.h"
#include "types.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>


class MyObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString testString READ testString WRITE setTestString)
    Q_PROPERTY(int testInt READ testInt WRITE setTestInt)

public:
    MyObject() : QObject(0), integer(0){}

    void setTestString(const QString &str) {
        qDebug() << "called setTestString" << str;
        string = str;
    }
    void setTestInt(int i) {
        qDebug() << "called setTestInt" << i;
        integer = i;
    }
    QString testString() const {
        qDebug() << "called testString" << string;
        return string;
    }
    int testInt() const {
        qDebug() << "called testInt" << integer;
        return integer;
    }
    QString string;
    int integer;

public slots:
    void foo() { qDebug() << "foo invoked"; }
};

// --------------------------------------------------------

using namespace JSC;
using namespace JSC::Bindings;

class Global : public JSNonFinalObject {
public:
  virtual UString className() const { return "global"; }
};

static char code[] =
    "myInterface.foo();\n"
    "myInterface.testString = \"Hello\";\n"
    "str = myInterface.testString;\n"
    "myInterface.testInt = 10;\n"
    "i = myInterface.testInt;\n";

int main(int argc, char** argv)
{
    // expecting a filename
    bool ret = true;
    {
        JSLock lock;
        
        // create interpreter w/ global object
        Global* global = new Global();

        // create interpreter
        RefPtr<Interpreter> interp = new Interpreter(global);
        ExecState* exec = interp->globalExec();
        
        MyObject* myObject = new MyObject;
        
        global->put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::QtLanguage, (void*)myObject));
        
        
        if (code) {
            // run
            Completion comp(interp->evaluate("", 0, code));
            
            if (comp.complType() == Throw) {
                qDebug() << "exception thrown";
                JSValue* exVal = comp.value();
                char* msg = exVal->toString(exec).ascii();
                int lineno = -1;
                if (exVal->type() == ObjectType) {
                    JSValue* lineVal = exVal->getObject()->get(exec, Identifier("line"));
                    if (lineVal->type() == NumberType)
                        lineno = int(lineVal->toNumber(exec));
                }
                if (lineno != -1)
                    fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
                else
                    fprintf(stderr,"Exception: %s\n",msg);
                ret = false;
            }
            else if (comp.complType() == ReturnValue) {
                char* msg = comp.value()->toString(interp->globalExec()).ascii();
                fprintf(stderr,"Return value: %s\n",msg);
            }
        }
        
    } // end block, so that Interpreter and global get deleted
    
    return ret ? 0 : 1;
}

#include "testqtbindings.moc"
