/****************************************************************************
** $Id: quickclassbrowser.cpp  beta1   edited Dec 10 13:07 $
**
** Copyright (C) 2001-2002 Trolltech AS.  All rights reserved.
**
** This file is part of the Qt Script for Applications framework (QSA).
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding a valid QSA Beta Evaluation Version license may use
** this file in accordance with the QSA Beta Evaluation Version License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about QSA Commercial License Agreements.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
*****************************************************************************/

#include "quickclassbrowser.h"
#include "quickide.h"
#include "quickdebuggerfrontend.h"
#include "../kernel/quickclassparser.h"
#include "../shared/globaldefs.h"
#include <qheader.h>
#include <qpainter.h>
#include <qpopupmenu.h>

QuickClassBrowserItem::QuickClassBrowserItem( QListView *parent, QListViewItem *after, Type t )
    : QListViewItem( parent, after ), type ( t )
{
}

QuickClassBrowserItem::QuickClassBrowserItem( QListViewItem *parent, QListViewItem *after, Type t )
    : QListViewItem( parent, after ), type( t )
{
}

QuickClassBrowserItem::~QuickClassBrowserItem()
{
}

void QuickClassBrowserItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align )
{
    QColorGroup g( cg );
    g.setColor( QColorGroup::Base, backgroundColor() );
    g.setColor( QColorGroup::Foreground, Qt::black );
    g.setColor( QColorGroup::Text, Qt::black );
    p->save();

    QListViewItem::paintCell( p, g, column, width, align );
    p->setPen( QPen( cg.dark(), 1 ) );
    if ( column == 0 )
	p->drawLine( 0, 0, 0, height() - 1 );
    if ( listView()->firstChild() != this ) {
	if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) {
	    int d = depth() - itemBelow()->depth();
	    p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 );
	}
    }
    p->drawLine( 0, height() - 1, width, height() - 1 );
    p->drawLine( width - 1, 0, width - 1, height() );
    p->restore();
}

void QuickClassBrowserItem::paintBranches( QPainter * p, const QColorGroup & cg,
				       int w, int y, int h )
{
    QColorGroup g( cg );
    g.setColor( QColorGroup::Base, backgroundColor() );
    QListViewItem::paintBranches( p, g, w, y, h );
}

QColor QuickClassBrowserItem::backgroundColor()
{
    updateBackColor();
    return backColor;
}

void QuickClassBrowserItem::updateBackColor()
{
    if ( listView()->firstChild() == this ) {
 	backColor = *backColor1;
	return;
    }

    QListViewItemIterator it( this );
    --it;
    if ( it.current() ) {
	if ( ( ( QuickClassBrowserItem*)it.current() )->backColor == *backColor1 )
	    backColor = *backColor2;
	else
	    backColor = *backColor1;
    } else {
	backColor == *backColor1;
    }
}





QuickClassBrowser::QuickClassBrowser( QWidget *parent, const char * )
    : QListView( parent, "quick_debugger_classbrowser" )
{
    init_colors();
    header()->hide();
    setResizeMode( AllColumns );
    setRootIsDecorated( TRUE );
    addColumn( "" );
    setSorting( -1 );
    setHScrollBarMode( AlwaysOff );
    setVScrollBarMode( AlwaysOn );
    connect( this, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint &, int ) ),
	     this, SLOT( showContextMenu( QListViewItem *, const QPoint &, int ) ) );
}

void QuickClassBrowser::update( const QString &code )
{
    clear();
    QuickClassParser parser;
    parser.parse( code );
    QValueList<QuickClass> classes = parser.classes();
    QListViewItem *lastClass = 0;
    QuickClassBrowserItem *currentClass = 0;
    for ( QValueList<QuickClass>::Iterator it = classes.begin(); it != classes.end(); ++it ) {
	if ( (*it).type == QuickClass::Global ) {
	    currentClass = new QuickClassBrowserItem( this, 0, QuickClassBrowserItem::Global );
	    currentClass->setText( 0, tr( "Global" ) );
	    currentClass->setOpen( TRUE );
	} else {
	    QuickClassBrowserItem::Type t;
	    switch ( (*it).type ) {
	    case QuickClass::Global:
		t = QuickClassBrowserItem::Global;
		break;
	    case QuickClass::Class:
		t = QuickClassBrowserItem::Class;
		break;
	    }
	    currentClass = new QuickClassBrowserItem( this, lastClass, t );
	    if ( (*it).type != QuickClass::Class || (*it).access == "public" )
		currentClass->setText( 0, (*it).name );
	    else
		currentClass->setText( 0, (*it).name + " [" + (*it).access + "]" );
	    currentClass->setOpen( TRUE );
	    lastClass = currentClass;
	}
	currentClass->setPixmap( 0, QPixmap::fromMimeSource( "class.png" ) );

	QValueList<LanguageInterface::Function> funcs = (*it).functions;
	QListViewItem *last = 0;
	for ( QValueList<LanguageInterface::Function>::Iterator fit = funcs.begin();
	      fit != funcs.end(); ++fit ) {
	    last = new QuickClassBrowserItem( currentClass, last, QuickClassBrowserItem::Function );
	    if ( (*it).type != QuickClass::Global && (*fit).access != "public" )
		last->setText( 0, (*fit).name + " [" + (*fit).access + "]" );
	    else
		last->setText( 0, (*fit).name );
	    last->setPixmap( 0, QPixmap::fromMimeSource( "function.png" ) );
	}
	QStringList vars = (*it).variables;
	for ( QStringList::Iterator vit = vars.begin(); vit != vars.end(); ++vit ) {
	    last = new QuickClassBrowserItem( currentClass, last, QuickClassBrowserItem::Variable );
	    QString var = *vit;
	    if ( var.startsWith( "var" ) )
		var = var.mid( 3 ).stripWhiteSpace();
	    else if ( var.startsWith( "const" ) )
		var = var.mid( 5 ).stripWhiteSpace() + " [const]";
	    else if ( var.startsWith( "static" ) )
		var = var.mid( 6 ).stripWhiteSpace() + " [static]";
	    last->setText( 0, var );
	    last->setPixmap( 0, QPixmap::fromMimeSource( "variable.png" ) );
	}
    }
}

void QuickClassBrowser::showContextMenu( QListViewItem *i, const QPoint &pos, int )
{
    if ( !i )
	return;
    if ( i->rtti() != QuickClassBrowserItem::Function &&
	 i->rtti() != QuickClassBrowserItem::Variable )
	return;
    enum { EDIT, RUN_FUNCTION };
    QPopupMenu menu( this );
    menu.setCheckable( TRUE );
    menu.insertItem( tr( "&Edit %1" ).arg( i->rtti() == QuickClassBrowserItem::Function ? "Function" : "Variable" ),
		     EDIT );
    if ( i->rtti() == QuickClassBrowserItem::Function &&
	 i->parent()->rtti() == QuickClassBrowserItem::Global )
	menu.insertItem( tr( "&Run Function" ), RUN_FUNCTION );
    switch ( menu.exec( pos ) ) {
    case EDIT:
	emit clicked( i );
	break;
    case RUN_FUNCTION:
	QuickIdeInterfaceImpl::debuggerInterface()->runFunction( i->text( 0 ).left( i->text( 0 ).find( '(' ) ) );
	break;
    }
}
