/*
 * dependlistview.cc
 *
 * Copyright (c) 2002, 2003 Frerich Raabe <raabe@kde.org>
 *
 * This program 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. For licensing and distribution details, check the
 * accompanying file 'COPYING'.
 */
#include "dependlistview.h"

#include <kiconloader.h>
#include <klocale.h>

using namespace Barry;

class DependancyListItem : public KListViewItem
{
	friend class DependancyList;
	public:
		DependancyListItem( DependancyList *parent, const Port &port );
		DependancyListItem( DependancyListItem *parent, const Port &port );

		virtual void setup();
		virtual void setOpen( bool open );

		Port port() const { return m_port; }
		virtual PortList dependencies() const = 0;

	protected:
		virtual void clone( DependancyListItem *parent, const Port &port ) = 0;
	
	private:
		DependancyListItem( const DependancyListItem &rhs );
		DependancyListItem &operator=( const DependancyListItem &rhs );
		void load();
		
		Port m_port;
};

class BuildDependancyItem : public DependancyListItem
{
	public:
		BuildDependancyItem( DependancyList *parent, const Port &port );
		BuildDependancyItem( DependancyListItem *parent, const Port &port );

		virtual PortList dependencies() const;

	protected:
		virtual void clone( DependancyListItem *parent, const Port &port );
};

class RunDependancyItem : public DependancyListItem
{
	public:
		RunDependancyItem( DependancyList *parent, const Port &port );
		RunDependancyItem( DependancyListItem *parent, const Port &port );

		virtual PortList dependencies() const;

	protected:
		virtual void clone( DependancyListItem *parent, const Port &port );
};

DependancyListItem::DependancyListItem( DependancyListItem *parent, const Port &port )
	: KListViewItem( parent ),
	m_port( port )
{
}

DependancyListItem::DependancyListItem( DependancyList *parent, const Port &port )
	: KListViewItem( parent ),
	m_port( port )
{
}

void DependancyListItem::setup()
{
	KListViewItem::setup();
	
	setText( 0, m_port.name() );
	setText( 1, m_port.version() );

	if ( !dependencies().empty() )
		setExpandable( true );

	if ( isOpen() )
		setPixmap( 0, SmallIcon( QString::fromLatin1( "folder_blue_open" ) ) );
	else
		setPixmap( 0, SmallIcon( QString::fromLatin1( "folder_blue" ) ) );
}

void DependancyListItem::setOpen( bool open )
{
	KListViewItem::setOpen( open );

	if ( open && childCount() == 0 && !dependencies().empty() ) {
		listView()->setUpdatesEnabled( false );
		load();
		listView()->setUpdatesEnabled( true );
	}

	if ( open && childCount() > 0 )
		setPixmap( 0, SmallIcon( QString::fromLatin1( "folder_blue_open" ) ) );
	else
		setPixmap( 0, SmallIcon( QString::fromLatin1( "folder_blue" ) ) );
}

void DependancyListItem::load()
{
	const PortList deps = dependencies();
	PortList::ConstIterator it = deps.begin();
	PortList::ConstIterator end = deps.end();
	for ( ; it != end; ++it )
		clone( this, *it );
}

BuildDependancyItem::BuildDependancyItem( DependancyList *parent, const Port &port )
	: DependancyListItem( parent, port )
{
}

BuildDependancyItem::BuildDependancyItem( DependancyListItem *parent, const Port &port )
	: DependancyListItem( parent, port )
{
}

PortList BuildDependancyItem::dependencies() const
{
	return port().buildDeps();
}

void BuildDependancyItem::clone( DependancyListItem *parent, const Port &port )
{
	new BuildDependancyItem( parent, port );
}

RunDependancyItem::RunDependancyItem( DependancyList *parent, const Port &port )
	: DependancyListItem( parent, port )
{
}

RunDependancyItem::RunDependancyItem( DependancyListItem *parent, const Port &port )
	: DependancyListItem( parent, port )
{
}

PortList RunDependancyItem::dependencies() const
{
	return port().runDeps();
}

void RunDependancyItem::clone( DependancyListItem *parent, const Port &port )
{
	new RunDependancyItem( parent, port );
}

DependancyList::DependancyList( QWidget *parent, Type type )
	: KListView( parent, "DependancyList" ),
	m_type( type )
{
	connect( this, SIGNAL( executed( QListViewItem * ) ),
	         this, SLOT( itemSelected( QListViewItem * ) ) );
	connect( this, SIGNAL( returnPressed( QListViewItem * ) ),
	         this, SLOT( itemSelected( QListViewItem * ) ) );

	setAllColumnsShowFocus( true );
	setShowSortIndicator( true );
	addColumn( i18n( "Name" ) );
	addColumn( i18n( "Version" ) );
}

void DependancyList::setPort( const Port &port )
{
	if ( m_port == port )
		return;
	
	m_port = port;

	setUpdatesEnabled( false );
	clear();
	DependancyListItem *item;
	if ( m_type == BuildDeps )
		item = new BuildDependancyItem( this, port );
	else
		item = new RunDependancyItem( this, port );
	item->setOpen( true );
	setUpdatesEnabled( true );
}

void DependancyList::itemSelected( QListViewItem *item )
{
	item->setOpen( !item->isOpen() );
}

#include "dependlistview.moc"
// vim:ts=4:sw=4:noet:list
