/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "mainwindow.h"
#include "changeproperties.h"
#include "invokemethod.h"
#include "ambientproperties.h"
#include "controlinfo.h"
#include "docuwindow.h"

#include <QtGui>
#include <qt_windows.h>
#include <ActiveQt/ActiveQt>

QT_BEGIN_NAMESPACE

QAxObject *ax_mainWindow = 0;

static QTextEdit *debuglog = 0;

static void redirectDebugOutput(QtMsgType type, const char*msg)
{
    Q_UNUSED(type);
    debuglog->append(QLatin1String(msg));
}

QT_END_NAMESPACE

QT_USE_NAMESPACE

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setupUi(this);
    setObjectName(QLatin1String("MainWindow"));

    QAxScriptManager::registerEngine(QLatin1String("PerlScript"), QLatin1String(".pl"));
    QAxScriptManager::registerEngine(QLatin1String("Python"), QLatin1String(".py"));

    dlgInvoke = 0;
    dlgProperties = 0;
    dlgAmbient = 0;
    scripts = 0;
    debuglog = logDebug;
    oldDebugHandler = qInstallMsgHandler(redirectDebugOutput);
    QHBoxLayout *layout = new QHBoxLayout(Workbase);
    workspace = new QWorkspace(Workbase);
    layout->addWidget(workspace);
    layout->setMargin(0);

    connect(workspace, SIGNAL(windowActivated(QWidget*)), this, SLOT(updateGUI()));
    connect(actionFileExit, SIGNAL(triggered()), qApp, SLOT(quit()));
}

MainWindow::~MainWindow()
{
    qInstallMsgHandler(oldDebugHandler);
    debuglog = 0;
}


void MainWindow::on_actionFileNew_triggered()
{
    QAxSelect select(this);
    if (select.exec()) {
        QAxWidget *container = new QAxWidget(workspace);
        container->setAttribute(Qt::WA_DeleteOnClose);
        container->setControl(select.clsid());
	container->setObjectName(container->windowTitle());
        workspace->addWindow(container);
        container->show();
    }
    updateGUI();
}

void MainWindow::on_actionFileLoad_triggered()
{
    QString fname = QFileDialog::getOpenFileName(this, tr("Load"), QString(), QLatin1String("*.qax"));
    if (fname.isEmpty())
	return;

    QFile file(fname);
    if (!file.open(QIODevice::ReadOnly)) {
	QMessageBox::information(this, tr("Error Loading File"), tr("The file could not be opened for reading.\n%1").arg(fname));
	return;
    }

    QAxWidget *container = new QAxWidget(workspace);
    workspace->addWindow(container);
    
    QDataStream d(&file);
    d >> *container;

    container->setObjectName(container->windowTitle());
    container->show();

    updateGUI();
}

void MainWindow::on_actionFileSave_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    QString fname = QFileDialog::getSaveFileName(this, tr("Save"), QString(), QLatin1String("*.qax"));
    if (fname.isEmpty())
	return;

    QFile file(fname);
    if (!file.open(QIODevice::WriteOnly)) {
	QMessageBox::information(this, tr("Error Saving File"), tr("The file could not be opened for writing.\n%1").arg(fname));
	return;
    }
    QDataStream d(&file);
    d << *container;
}


void MainWindow::on_actionContainerSet_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    QAxSelect select(this);
    if (select.exec())
	container->setControl(select.clsid());
    updateGUI();
}

void MainWindow::on_actionContainerClear_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (container)
	container->clear();
    updateGUI();
}

void MainWindow::on_actionContainerProperties_triggered()
{
    if (!dlgAmbient) {
	dlgAmbient = new AmbientProperties(this);
	dlgAmbient->setControl(workspace);
    }
    dlgAmbient->show();
}


void MainWindow::on_actionControlInfo_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    ControlInfo info(this);
    info.setControl(container);
    info.exec();
}

void MainWindow::on_actionControlProperties_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    if (!dlgProperties) {
	dlgProperties = new ChangeProperties(this);
	connect(container, SIGNAL(propertyChanged(QString)), dlgProperties, SLOT(updateProperties()));
    }
    dlgProperties->setControl(container);
    dlgProperties->show();
}

void MainWindow::on_actionControlMethods_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    if (!dlgInvoke)
	dlgInvoke = new InvokeMethod(this);
    dlgInvoke->setControl(container);
    dlgInvoke->show();
}

void MainWindow::on_VerbMenu_aboutToShow()
{
    VerbMenu->clear();

    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    QStringList verbs = container->verbs();
    for (int i = 0; i < verbs.count(); ++i) {
        VerbMenu->addAction(verbs.at(i));
    }

    if (!verbs.count()) { // no verbs?
        VerbMenu->addAction(tr("-- Object does not support any verbs --"))->setEnabled(false);
    }
}

void MainWindow::on_VerbMenu_triggered(QAction *action)
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    container->doVerb(action->text());
}

void MainWindow::on_actionControlDocumentation_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;
    
    QString docu = container->generateDocumentation();
    if (docu.isEmpty())
	return;

    DocuWindow *docwindow = new DocuWindow(docu, workspace, container);
    workspace->addWindow(docwindow);
    docwindow->show();
}


void MainWindow::on_actionControlPixmap_triggered()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
	return;

    QPixmap pm = QPixmap::grabWidget(container);

    QLabel *label = new QLabel(workspace);
    label->setAttribute(Qt::WA_DeleteOnClose);
    label->setPixmap(pm);
    label->setWindowTitle(tr("%1 - Pixmap").arg(container->windowTitle()));

    workspace->addWindow(label);
    label->show();
}

void MainWindow::on_actionScriptingRun_triggered()
{
#ifndef QT_NO_QAXSCRIPT
    if (!scripts)
	return;

    // If we have only one script loaded we can use the cool dialog
    QStringList scriptList = scripts->scriptNames();
    if (scriptList.count() == 1) {
	InvokeMethod scriptInvoke(this);
	scriptInvoke.setWindowTitle(tr("Execute Script Function"));
	scriptInvoke.setControl(scripts->script(scriptList[0])->scriptEngine());
	scriptInvoke.exec();
	return;
    }

    bool ok = false;
    QStringList macroList = scripts->functions(QAxScript::FunctionNames);
    QString macro = QInputDialog::getItem(this, tr("Select Macro"), tr("Macro:"), macroList, 0, true, &ok);

    if (!ok)
	return;

    QVariant result = scripts->call(macro);
    if (result.isValid())
	logMacros->append(tr("Return value of %1: %2").arg(macro).arg(result.toString()));
#endif
}

void MainWindow::on_actionScriptingLoad_triggered()
{
#ifndef QT_NO_QAXSCRIPT
    QString file = QFileDialog::getOpenFileName(this, tr("Open Script"), QString(), QAxScriptManager::scriptFileFilter());

    if (file.isEmpty())
	return;

    if (!scripts) {
	scripts = new QAxScriptManager(this);
	scripts->addObject(this);
    }

    QWidgetList widgets = workspace->windowList();
    QWidgetList::Iterator it(widgets.begin());
    while (it != widgets.end()) {
	QAxBase *ax = (QAxBase*)(*it)->qt_metacast("QAxBase");
	++it;
	if (!ax)
	    continue;
	scripts->addObject(ax);
    }

    QAxScript *script = scripts->load(file, file);
    if (script) {
	connect(script, SIGNAL(error(int,QString,int,QString)),
		this,   SLOT(logMacro(int,QString,int,QString)));
	actionScriptingRun->setEnabled(true);
    }
#else
    QMessageBox::information(this, tr("Function not available"),
	tr("QAxScript functionality is not available with this compiler."));
#endif
}

void MainWindow::updateGUI()
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());

    bool hasControl = container && !container->isNull();
    actionFileNew->setEnabled(true);
    actionFileLoad->setEnabled(true);
    actionFileSave->setEnabled(hasControl);
    actionContainerSet->setEnabled(container != 0);
    actionContainerClear->setEnabled(hasControl);
    actionControlProperties->setEnabled(hasControl);
    actionControlMethods->setEnabled(hasControl);
    actionControlInfo->setEnabled(hasControl);
    actionControlDocumentation->setEnabled(hasControl);
    actionControlPixmap->setEnabled(hasControl);
    VerbMenu->setEnabled(hasControl);
    if (dlgInvoke)
	dlgInvoke->setControl(hasControl ? container : 0);
    if (dlgProperties)
	dlgProperties->setControl(hasControl ? container : 0);

    QWidgetList list = workspace->windowList();
    QWidgetList::Iterator it = list.begin();
    while (it != list.end()) {
	QWidget *container = *it;

	QAxWidget *ax = qobject_cast<QAxWidget*>(container);
	if (ax) {
	    container->disconnect(SIGNAL(signal(QString,int,void*)));
	    if (actionLogSignals->isChecked())
		connect(container, SIGNAL(signal(QString,int,void*)), this, SLOT(logSignal(QString,int,void*)));

	    container->disconnect(SIGNAL(exception(int,QString,QString,QString)));
	    connect(container, SIGNAL(exception(int,QString,QString,QString)),
		this, SLOT(logException(int,QString,QString,QString)));

	    container->disconnect(SIGNAL(propertyChanged(QString)));
	    if (actionLogProperties->isChecked()) 
		connect(container, SIGNAL(propertyChanged(QString)), this, SLOT(logPropertyChanged(QString)));
	    container->blockSignals(actionFreezeEvents->isChecked());
	}

	++it;
    }
}


void MainWindow::logPropertyChanged(const QString &prop)
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    QVariant var = container->property(prop.toLatin1());
    logProperties->append(tr("%1: Property Change: %2 - { %3 }").arg(container->windowTitle(), prop, var.toString()));
}

void MainWindow::logSignal(const QString &signal, int argc, void *argv)
{
    QAxWidget *container = qobject_cast<QAxWidget*>(workspace->activeWindow());
    if (!container)
        return;

    QString paramlist;
    VARIANT *params = (VARIANT*)argv;
    for (int a = argc-1; a >= 0; --a) {
	if (a == argc-1)
	    paramlist = QLatin1String(" - {");
	QVariant qvar = VARIANTToQVariant(params[a], 0);
	paramlist += QLatin1String(" ") + qvar.toString();
	if (a > 0)
	    paramlist += QLatin1String(",");
	else
	    paramlist += QLatin1String(" ");
    }
    if (argc)
	paramlist += QLatin1String("}");
    logSignals->append(container->windowTitle() + QLatin1String(": ") + signal + paramlist);
}

void MainWindow::logException(int code, const QString&source, const QString&desc, const QString&help)
{
    Q_UNUSED(desc);
    QAxWidget *container = qobject_cast<QAxWidget*>(sender());
    if (!container)
        return;

    QString str = tr("%1: Exception code %2 thrown by %3").
	arg(container->windowTitle()).arg(code).arg(source);
    logDebug->append(str);
    logDebug->append(tr("\tDescription: %1").arg(desc));

    if (!help.isEmpty())
	logDebug->append(tr("\tHelp available at %1").arg(help));
    else
	logDebug->append(tr("\tNo help available."));
}

void MainWindow::logMacro(int code, const QString &description, int sourcePosition, const QString &sourceText)
{
    /* FIXME This needs to be rewritten to not use string concatentation, such
     * that it can be translated in a sane way. */
    QString message = tr("Script: ");
    if (code)
	message += QString::number(code) + QLatin1String(" ");
    message += QLatin1String("'") + description + QLatin1String("'");
    if (sourcePosition)
	message += tr(" at position ") + QString::number(sourcePosition);
    if (!sourceText.isEmpty())
	message += QLatin1String(" '") + sourceText + QLatin1String("'");

    logMacros->append(message);
}
