/***************************************************************************
                          balloonwidget.cpp  -  description
                             -------------------
    begin                : Mon May 19 2003
    copyright            : (C) 2003 by Michael Curtis
    email                : michael@kmess.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "balloonwidget.h"

#include <qevent.h>
#include <qobject.h>
#include <qpoint.h>
#include <qpointarray.h>
#include <qlayout.h>
#include <qwidget.h>

#include <kapp.h>
#include <kdebug.h>

#include "notificationwidget.h"
#include "notificationitem.h"

BalloonWidget::BalloonWidget(QWidget *parent, const char *name ) :
  CurvedWidget( parent,name, WStyle_StaysOnTop | WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WX11BypassWM ),
  anchorWidget_(0)
{
  setPaletteBackgroundColor( "#1F939B" );

  notificationWidgets_.clear();

  verticalBox_ = new QVBoxLayout( 0, 0, 5 );

  getRootLayout()->addLayout( verticalBox_, 0, 0 );
}

BalloonWidget::~BalloonWidget()
{
  delete verticalBox_;
}



// Get an "anchor" point from the system tray widget
QPoint BalloonWidget::getAnchor() const
{
  QPoint point;

  if ( anchorWidget_ != 0 )
  {
    point = anchorWidget_->mapToGlobal( anchorWidget_->pos() );
  }

  return point;
}



// called when a notificationwidget becomes devoid of items
void BalloonWidget::empty( NotificationWidget * emptyOne )
{
  NotificationWidget *widget;
  unsigned int numberOfWidgetsShown = 0;

  // hide the empty one
  emptyOne->hide();

  for ( widget = notificationWidgets_.first(); widget; widget = notificationWidgets_.next() )
  {
    if ( widget->isShown() ) numberOfWidgetsShown++;
  }

  if ( numberOfWidgetsShown > 0 )
  {
    adjustSize();
  }
  else
  {
    // disappear, as we're surplus to requirements
    hide();
  }
}



// general Qt QObject event, which we use for detecting children added to/deleted from us
bool BalloonWidget::event( QEvent *event )
{
  QObject *childObject = ((QChildEvent *) event)->child();

  if( event->type() == QEvent::ChildInserted  )
  {
    if ( childObject->inherits( "NotificationWidget" ) )
    {
      verticalBox_->addWidget( (NotificationWidget *) childObject );

      connect( (NotificationWidget *) childObject, SIGNAL( empty( NotificationWidget * ) ),
               this                              , SLOT  ( empty( NotificationWidget * ) ) );
      connect( (NotificationWidget *) childObject, SIGNAL(  full( NotificationWidget * ) ),
               this                              , SLOT  (  full( NotificationWidget * ) ) );

      notificationWidgets_.append( (NotificationWidget *) childObject );

      return true;
    }
  }

  if( event->type() == QEvent::ChildRemoved  )
  {
      notificationWidgets_.remove( (NotificationWidget *) childObject );
  }

  CurvedWidget::event( event );

  return false;
}



// called when a notification widget gains an item
void BalloonWidget::full( NotificationWidget * fullOne )
{
  if ( isHidden() )
  {
    show();
  }

  // show the full one
  fullOne->show();
  fullOne->adjustSize();

  // adjust size
  adjustSize();
}



void BalloonWidget::setAnchorWidget( QWidget *anchorWidget )
{
  anchorWidget_ = anchorWidget;

  updateMask();
}



// add an arrow to the mask, and move the widget so that the arrow points from the anchor point
void BalloonWidget::updateMask()
{
  QPoint anchor = getAnchor();

  CurvedWidget::updateMask();

 // Added/Updated by Scott Morgan - 2002-10-16
  int screen = kapp->desktop()->screenNumber( anchor );
  QRect screenSize = kapp->desktop()->screenGeometry(screen);

  bool bottom = (anchor.y() + height()) > (screenSize.height() - 48);
  bool right  = (anchor.x() + width())  > (screenSize.width() - 48);
  // End of changes

  QPointArray arrow(4);
  arrow.setPoint(0, QPoint(right ? width() : 0, bottom ? height() : 0));
  arrow.setPoint(1, QPoint(right ? width() - 10 : 10, bottom ? height() - 30 : 30));
  arrow.setPoint(2, QPoint(right ? width() - 30 : 30, bottom ? height() - 10 : 10));
  arrow.setPoint(3, arrow[0]);
  *ourMask_ += arrow;
  setMask( *ourMask_ );

  move(right ? anchor.x() - width() : anchor.x(),
       bottom ? anchor.y() - height() : anchor.y());
}



#include "balloonwidget.moc"
