/*
 *  Copyright (C) 2001-2002, Richard J. Moore <rich@kde.org>
 *
 *  This library 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 library 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 library; see the file COPYING.LIB.  If not, write to
 *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *  Boston, MA 02111-1307, USA.
 */

#include <qcombobox.h>
#include <qfile.h>
#include <qhbox.h>
#include <qlayout.h>
#include <qpushbutton.h>

#include <kdebug.h>
#include <kdialog.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kpopupmenu.h>

#include <kjs/interpreter.h>
#include <kjs/ustring.h>
#include <kjs/types.h>

#include "jsbinding.h"
#include "messagelogwidget.h"
#include "kjsembedpart.h"

#include "jsconsolewidget.h"
#include "jsconsolewidget.moc"

//
// JScript Widget
//

namespace KJSEmbed {

class Private
{
public:
    KPopupTitle *title;
};

JSConsoleWidget::JSConsoleWidget( KJS::Interpreter *js, QWidget *parent, const char *name )
    : QFrame( parent, name ? name : "JSConsoleWidget" )
{
    d = new Private;
    setFocusPolicy( QWidget::StrongFocus );
    createView();
    this->js = js;
}

JSConsoleWidget::~JSConsoleWidget()
{
    delete d;
}

KPopupTitle *JSConsoleWidget::title() const
{
    return d->title;
}

void JSConsoleWidget::createView()
{
    d->title = new KPopupTitle( this, "Title" );
    d->title->setText( i18n("Javascript Console") );
    QPixmap px( KGlobal::iconLoader()->loadIcon("konsole", KIcon::NoGroup, KIcon::SizeSmall) );
    d->title->setIcon( px );

    log = new MessageLogWidget( this, "LogView" );

    QHBox *hbox = new QHBox( this, "HBox" );
    hbox->setSpacing( KDialog::spacingHint() );

    cmd = new QComboBox( true, hbox, "CmdEdit" );
    cmd->setInsertionPolicy( QComboBox::AtTop );
    cmd->setFocus();

    run = new QPushButton( i18n("&Run"), hbox, "RunButton" );
    run->setFixedSize( run->sizeHint() );

    connect( cmd, SIGNAL( activated(int) ), run, SLOT( animateClick() ) );
    connect( run, SIGNAL( clicked() ), SLOT( execute() ) );

    //
    // Layout
    //
    QVBoxLayout *vertical = new QVBoxLayout( this, KDialog::marginHint(), KDialog::spacingHint() );
    vertical->addWidget( d->title );
    vertical->addWidget( log );
    vertical->addWidget( hbox );

    log->message( i18n("-- Enter a JS expression and press enter --") );
}

void JSConsoleWidget::print( const QString &text )
{
    log->message( text );
}

void JSConsoleWidget::warn( const QString &text )
{
    log->error( text );
}

void JSConsoleWidget::execute()
{
    QString code = cmd->currentText();
    log->raw( QString( "<b>kjs&gt; %1</b>" ).arg( code ) );
    execute( code );
}

bool JSConsoleWidget::execute( const QString &cmd )
{
    KJS::Completion jsres = js->evaluate( KJS::UString(cmd), js->globalObject() );

    KJS::UString s;
    KJS::ComplType ct = jsres.complType();
    bool res  = false;

    // Report Errors
    if ( (ct == KJS::Throw) || (ct == KJS::Break) || ct == KJS::Continue ) {
	kdDebug() << "jsconsolewidget: Error returned" << endl;

	s = jsres.value().toString( js->globalExec() );
	if ( !s.isNull() )
	    log->error( s.qstring() );
	else {
	    kdDebug() << "jsconsolewidget: Null error message" << endl;
	}

	res = false;
    }
    // Handle Normal
    else if ( ct == KJS::Normal ) {
	kdDebug() << "jsconsolewidget: Normal result" << endl;
	res = true;

	// Handle Return Values
	if ( jsres.isValueCompletion() ) {
	    kdDebug() << "jsconsolewidget: Value returned" << endl;

	    KJS::Value ret = jsres.value();
	    if ( ret.type() == KJS::StringType || ret.type() == KJS::NumberType )
		s = ret.toString( js->globalExec() );
	    else if ( ret.type() == KJS::ListType ) {
		s = KJS::UString( "====list====" );
	    }
	    else {
		s = ret.toString( js->globalExec() );
		if ( s.isNull() )
		    s = KJS::UString( "====object====" );
	    }

	    if ( s.isNull() )
		log->message( i18n("Return Value, <Unable to display result>") );
	    else
		log->message( s.qstring() );

	    res = true;
	}
    }

    return res;
}

}; // namespace KJSEmbed

// Local Variables:
// c-basic-offset: 4
// End:
