/*
    This file is part of Akonadi Contact.

    Copyright (c) 2008 Volker Krause <vkrause@kde.org>

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

    This library 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.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "waitingoverlay_p.h"

#include <KDebug>
#include <KJob>
#include <KLocalizedString>

#include <QtCore/QEvent>
#include <QBoxLayout>
#include <QLabel>
#include <QPalette>
//#include <QProgressBar>

//@cond PRIVATE

WaitingOverlay::WaitingOverlay( KJob *job, QWidget *baseWidget, QWidget * parent )
  : QWidget( parent ? parent : baseWidget->window() ),
    mBaseWidget( baseWidget )
{
  Q_ASSERT( baseWidget );
  Q_ASSERT( parentWidget() != baseWidget );

  connect( baseWidget, SIGNAL(destroyed()), SLOT(deleteLater()) );
  connect( job, SIGNAL(result(KJob*)), SLOT(deleteLater()) );
  mPreviousState = mBaseWidget->isEnabled();

  QBoxLayout *topLayout = new QVBoxLayout( this );
  topLayout->addStretch();
  QLabel *description = new QLabel( this );
  description->setText( i18n( "<p style=\"color: white;\"><b>Waiting for operation</b><br/></p>" ) );
  description->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
  topLayout->addWidget( description );
  topLayout->addStretch();

  QPalette p = palette();
  p.setColor( backgroundRole(), QColor( 0, 0, 0, 128 ) );
  setPalette( p );
  setAutoFillBackground( true );

  mBaseWidget->installEventFilter( this );

  reposition();
}

WaitingOverlay::~ WaitingOverlay()
{
  if ( mBaseWidget ) {
    mBaseWidget->setEnabled( mPreviousState );
  }
}

void WaitingOverlay::reposition()
{
  if ( !mBaseWidget ) {
    return;
  }

  // reparent to the current top level widget of the base widget if needed
  // needed eg. in dock widgets
  if ( parentWidget() != mBaseWidget->window() ) {
    setParent( mBaseWidget->window() );
  }

  // follow base widget visibility
  // needed eg. in tab widgets
  if ( !mBaseWidget->isVisible() ) {
    hide();
    return;
  }
  show();

  // follow position changes
  const QPoint topLevelPos = mBaseWidget->mapTo( window(), QPoint( 0, 0 ) );
  const QPoint parentPos = parentWidget()->mapFrom( window(), topLevelPos );
  move( parentPos );

  // follow size changes
  // TODO: hide/scale icon if we don't have enough space
  resize( mBaseWidget->size() );
}

bool WaitingOverlay::eventFilter(QObject * object, QEvent * event)
{
  if ( object == mBaseWidget &&
      ( event->type() == QEvent::Move || event->type() == QEvent::Resize ||
        event->type() == QEvent::Show || event->type() == QEvent::Hide ||
        event->type() == QEvent::ParentChange ) ) {
    reposition();
  }
  return QWidget::eventFilter( object, event );
}

//@endcond
