/****************************************************************************
**
** 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);
}
