#include <qpainter.h>
#include <qdrawutil.h>
#include <qtimer.h>

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

#include "kasitem.h"

#include "kaspopup.h"
#include "kasitem.moc"

/* XPM */
static const char *tiny_arrow[]={
"5 9 2 1",
". c None",
"# c #ffffff",
"....#",
"...##",
"..###",
".####",
"#####",
".####",
"..###",
"...##",
"....#"};

KasItem::KasItem( KasBar *parent )
   : QObject( parent ),
     kas( parent ), pop( 0 ), popupTimer( 0 ), dragTimer( 0 ),
     title( i18n( "Kasbar" ) ),
     mouseOver( false ), activated( false ), customPopup( false ), groupItem( false )
{
    update();
}

KasItem::~KasItem()
{
    delete pop;
}

void KasItem::setActive( bool yesno )
{
    if ( activated == yesno )
	return;

    activated = yesno;
    update();
}

void KasItem::setText( const QString &text )
{
    if ( title == text )
	return;

    title = text;
    update();
}

void KasItem::mouseEnter()
{
   static const int POPUP_DELAY = 300;

   if ( (!customPopup) && (popupTimer == 0) ) {
      popupTimer = new QTimer( this, "popupTimer" );
      connect( popupTimer, SIGNAL( timeout() ), SLOT( showPopup() ) );
      popupTimer->start( POPUP_DELAY, true );
   }

   mouseOver = true;
   update( false );
}

void KasItem::dragEnter()
{
   static const int DRAG_SWITCH_DELAY = 1000;

   if ( dragTimer == 0 ) {
      dragTimer = new QTimer( this, "dragTimer" );
      connect( dragTimer, SIGNAL( timeout() ), SLOT( dragOverAction() ) );
      dragTimer->start( DRAG_SWITCH_DELAY, true );
   }

   mouseOver = true;
   update( false );
}

void KasItem::mouseLeave()
{
   if ( popupTimer ) {
      delete popupTimer;
      popupTimer = 0;
   }
   if ( (!customPopup) && pop )
      hidePopup();

   mouseOver = false;
   update( false );
}

void KasItem::dragLeave()
{
   if ( dragTimer ) {
      delete dragTimer;
      dragTimer = 0;
   }

   mouseOver = false;
   update( false );
}

void KasItem::showPopup()
{
   if ( pop )
      return;

   activated = true;
   pop = createPopup();
   if ( pop )
      pop->show();
   update();
}

void KasItem::hidePopup()
{
    delete pop;
   pop = 0;
   activated = false;
   update();
}

void KasItem::togglePopup()
{
   if ( pop )
      hidePopup();
   else
      showPopup();
}

void KasItem::paintFrame( QPainter *p )
{
   qDrawShadePanel(p, 0, 0, extent(), extent(), colorGroup(), false, 2);

   if ( mouseOver )
      p->setPen(Qt::white);
   else
      p->setPen(Qt::black);

   p->drawRect(0, 0, extent(), extent());
}

void KasItem::paintLabel( QPainter *p )
{
    QString text = title;

    if ( !groupItem ) {
	p->fillRect( 2, 2, extent()-4, 13, QBrush( Qt::black ) );
	p->setFont( KGlobalSettings::taskbarFont() );
	p->setPen( Qt::white );

	if ( fontMetrics().width( text ) > extent()-4 )
	    p->drawText( 2, 2, extent()-4, 12, AlignLeft | AlignVCenter, text );
	else
	    p->drawText( 2, 2, extent()-4, 12, AlignCenter, text );

	return;
    }
    else {
	QPixmap arrow( tiny_arrow );

	QPoint popupPos = KasPopup::calcPosition( this, 10, 10 );
	QPoint iPos = kasbar()->mapToGlobal( kasbar()->itemPos( this ) );
	QWMatrix turn;

	if ( popupPos.x() < iPos.x() ) {
	    paintArrowLabel( p, arrow.width(), true );
	    p->drawPixmap( 3, 4, arrow );
	}
	else if ( popupPos.x() == iPos.x() ) {
	    if ( popupPos.y() < iPos.y() ) {
		turn.rotate( 90.0 );
		arrow = arrow.xForm( turn );
		paintArrowLabel( p, arrow.width(), true );
		p->drawPixmap( 3, 6, arrow );
	    }
	    else {
		turn.rotate( 270.0 );
		arrow = arrow.xForm( turn );
		paintArrowLabel( p, arrow.width(), false );
		p->drawPixmap( extent()-12, 6, arrow );
	    }
	}
	else {
	    turn.rotate( 180.0 );
	    arrow = arrow.xForm( turn );
	    paintArrowLabel( p, arrow.width(), false );
	    p->drawPixmap( extent()-8, 4, arrow );
	}
    }
}

void KasItem::paintArrowLabel( QPainter *p, int arrowSize, bool arrowOnLeft )
{
    QString text = title;
    int lx = 2;
    int ly = 2;
    int w = extent()-4;
    int h = 13;
    arrowSize+=2; // Add a space

    p->fillRect( lx, ly, w, h, QBrush( Qt::black ) );

    // Adjust for arrow
    if ( arrowOnLeft ) {
	lx += arrowSize;
	w -= arrowSize;
    }
    else {
	w -= arrowSize;
    }

    p->setFont( KGlobalSettings::taskbarFont() );
    p->setPen( Qt::white );
    if ( fontMetrics().width( text ) > w )
	p->drawText( lx, ly, w, h-1, AlignLeft | AlignVCenter, text );
    else
	p->drawText( lx, ly, w, h-1, AlignCenter, text );
}

void KasItem::paintBackground( QPainter *p )
{
    if ( activated )
	p->drawPixmap( 2, 15, *(kas->activeBg()) );
    else {
	if ( !kas->isTransparent() )
	    p->drawPixmap( 2, 15, *(kas->inactiveBg()) );
	else
	    p->fillRect( 2, 15, extent()-4, extent()-17, kasbar()->backgroundBrush() );
    }
}

void KasItem::paintProgress( QPainter *p, int percent )
{
    double angle = 360*16;
    angle = angle * (percent/100.0L);

    QRect pos;
    pos.setRect( 6, 18, 30, 30 );

    p->setPen( Qt::black );
    p->setBrush( QBrush( Qt::black ) );
    p->drawEllipse( pos );

    p->setPen( Qt::gray );
    p->setBrush( QBrush( Qt::gray ) );
    p->drawPie( pos, 90*16, -angle );

    p->setPen( Qt::white );
    QString text = i18n("%1%");
    p->drawText( pos, AlignCenter, text.arg(percent) );
}

void KasItem::paint( QPainter *p )
{
   //
   // Basic item.
   //
   paintFrame( p );
   paintLabel( p );
   paintBackground( p );

   QPixmap pixmap = KGlobal::iconLoader()->loadIcon( "wizard",
						     KIcon::NoGroup,
						     KIcon::SizeMedium );

   if ( !pixmap.isNull() )
      p->drawPixmap( 4, 16, pixmap );
}

void KasItem::paint( QPainter *p, int x, int y )
{
    QSize sz( extent(), extent() );
    QPixmap buff( sz );
//    buff.fill( Qt::red );

    // Paint offscreen buffer
    QPainter op( &buff );
    kas->paintBackground( &op, QRect( QPoint(x,y), sz ) );
    paint( &op );

    // Apply buffer
    p->drawPixmap( x, y, buff );
}

void KasItem::update()
{
   kas->repaintItem( this );
}

void KasItem::update( bool erase )
{
   kas->repaintItem( this, erase );
}

