#include <qpainter.h>
#include <qbitmap.h>
#include <qtimer.h>
#include <qwmatrix.h>

#include <kglobal.h>
#include <kwin.h>
#include <kiconloader.h>
#include <kpixmap.h>
#include <kpixmapeffect.h>
#include <klocale.h>

#include <taskmanager.h>

#include "kastasker.h"
#include "kasgrouppopup.h"
#include "kasgroupitem.h"

#ifndef KDE_USE_FINAL
/* XPM */
static const char *tiny_floppy[]={
"10 10 4 1",
". c None",
"# c #000000",
"b c #a0a0a0",
"a c #ffffff",
".########.",
".#aaaaaa#.",
".#aaaaaa#.",
".#aaaaaa#.",
".########.",
".########.",
".##bbbb##.",
".##bbbb##.",
".##bbbb##.",
".........."};
#endif

KasGroupItem::KasGroupItem( KasTasker *parent )
   : KasItem( parent ), items()
     
{
    setCustomPopup( true );
    setGroupItem( true );
    setText( i18n("Group") );
    items.setAutoDelete( false );

    connect( parent, SIGNAL( layoutChanged() ), this, SLOT( hidePopup() ) );
    connect( parent, SIGNAL( layoutChanged() ), this, SLOT( update() ) );
}

KasGroupItem::~KasGroupItem()
{
}

KasTasker *KasGroupItem::kasbar() const
{
    return static_cast<KasTasker *> (KasItem::kasbar());
}

QPixmap KasGroupItem::icon()
{
    bool usedIconLoader = false;
    Task *t = items.first();
    if (!t)
	return KGlobal::iconLoader()->loadIcon( "kicker",
						KIcon::NoGroup,
						KIcon::SizeSmall );

    switch( kasbar()->itemSize() ) {
	case KasBar::Small:
	    return t->bestIcon( KIcon::SizeSmall, usedIconLoader );
	    break;
	case KasBar::Medium:
	    return t->bestIcon( KIcon::SizeMedium, usedIconLoader );
	    break;
	case KasBar::Large:
	    return t->bestIcon( KIcon::SizeLarge, usedIconLoader );
	    break;
    }

    return KGlobal::iconLoader()->loadIcon( "error",
					    KIcon::NoGroup,
					    KIcon::SizeSmall );
}

void KasGroupItem::paint( QPainter *p )
{
    paintFrame( p );
    paintLabel( p );
    paintBackground( p );

    //
    // Paint the icon
    //
    p->drawPixmap(10, 16, icon() );

    //
    // Item summary info
    //
    int modCount = 0;
    for ( Task *t = items.first(); t != 0 ; t = items.next() ) {
	if ( t->isModified() )
	    modCount++;
    }

    p->setPen( isShowingPopup() ? kasbar()->activePenColor() : kasbar()->inactivePenColor() );

    if ( modCount ) {
	QString modCountStr;
	modCountStr.setNum( modCount );
	p->drawText( extent()-fontMetrics().width( modCountStr )-3,
		     15+fontMetrics().ascent(),
		     modCountStr );

	QPixmap floppy( tiny_floppy );
	p->drawPixmap(extent()-12, 29, floppy );
    }

    int microsPerCol;
    switch( kasbar()->itemSize() ) {
	default:
	case KasBar::Small:
	    microsPerCol = 2;
	    break;
	case KasBar::Medium:
	    microsPerCol = 4;
	    break;
	case KasBar::Large:
	    microsPerCol = 7;
	    break;
    }

    int xpos = 3;
    int ypos = 16;

    for ( int i = 0; ( i < (int) items.count() ) && ( i < microsPerCol ); i++ ) {
	Task *t = items.at( i );
	if (!t)
	    break;

	if( t->isIconified() )
	    p->drawPixmap( xpos, ypos,
			   *(kasbar()->microMinIcon()) );
	else if ( t->isShaded() )
	    p->drawPixmap( xpos, ypos,
			   *(kasbar()->microShadeIcon()) );
	else
	    p->drawPixmap( xpos, ypos,
			   *(kasbar()->microMaxIcon()) );

	ypos += 7;
    }

    if ( ((int) items.count() > microsPerCol) && ( kasbar()->itemSize() != KasBar::Small ) ) {
	QString countStr;
	countStr.setNum( items.count() );
	p->drawText( extent()-fontMetrics().width( countStr )-3,
		     extent()+fontMetrics().ascent()-16,
		     countStr );
    }
}

void KasGroupItem::mousePressEvent( QMouseEvent * )
{
    togglePopup();
    update();
}

KasPopup *KasGroupItem::createPopup()
{
    if ( items.count() ) {
	KasGroupPopup *pop = new KasGroupPopup( this );
	KasTasker *bar = pop->childBar();

	for ( Task *t = items.first(); t != 0; t = items.next() ) {
	    bar->addTask( t );
	}
	pop->resize( bar->size() );

	return pop;
    }
    return 0;

//     // Test code
//     //
//     // This generates cool looking fractal-like patterns if you keep unfolding the
//     // groups!
//     int pos = (int) this; 
//     if ( pos % 2 )
//        bar->append( new KasItem( bar ) );
//     if ( pos % 5 )
//        bar->append( new KasItem( bar ) );
//     bar->append( new KasGroupItem( bar ) );
//     if ( pos % 3 )
//        bar->append( new KasItem( bar ) );
//     if ( pos % 7 )
//        bar->append( new KasItem( bar ) );
//     ////////////
}

void KasGroupItem::addTask( Task *t )
{
    if (!t)
	return;

    items.append( t );
    if ( items.count() == 1 )
	setText( t->visibleName() );

    connect( t, SIGNAL( changed() ), this, SLOT( update() ) );
    update();
}

void KasGroupItem::removeTask( Task *t )
{
    if ( !t )
	return;

    hidePopup();
    items.remove( t );

    if ( items.count() == 1 )
	kasbar()->moveToMain( this, items.first() );
}

#include "kasgroupitem.moc"
