/*
    This file is part of KAddressBook.
    Copyright (c) 2003 Tobias Koenig <tokoe@kde.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.

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

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of TQt, and distribute the resulting executable,
    without including the source code for TQt in the source distribution.
*/

#include <tdeabc/picture.h>
#include <kdebug.h>
#include <kdialog.h>
#include <tdefiledialog.h>
#include <tdeglobalsettings.h>
#include <kiconloader.h>
#include <kimageio.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kurldrag.h>
#include <libtdepim/kpixmapregionselectordialog.h>

#include <tqapplication.h>
#include <tqdragobject.h>
#include <tqeventloop.h>
#include <tqgroupbox.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqpixmap.h>
#include <tqpopupmenu.h>

#include <unistd.h>

#include "imagewidget.h"

ImageLoader::ImageLoader( TQWidget *parent )
  : TQObject( 0, "ImageLoader" ), mParent( parent )
{
}

TDEABC::Picture ImageLoader::loadPicture( const KURL &url, bool *ok )
{
  TDEABC::Picture picture;
  TQString tempFile;

  if ( url.isEmpty() )
    return picture;

  (*ok) = false;

  TQImage image;
  if ( url.isLocalFile() ) {
    image.load( url.path() );
    picture.setData( image );
    (*ok) = true;
  } else if ( TDEIO::NetAccess::download( url, tempFile, mParent ) ) {
    image.load( tempFile );
    picture.setData( image );
    (*ok) = true;
    TDEIO::NetAccess::removeTempFile( tempFile );
  }

  if ( !(*ok) ) {
    // image does not exist (any more)
    KMessageBox::sorry( mParent, i18n( "This contact's image cannot be found." ) );
    return picture;
  }

  TQPixmap pixmap = picture.data();

  TQPixmap selectedPixmap = KPIM::KPixmapRegionSelectorDialog::getSelectedImage( pixmap, 100, 140, mParent );
  if ( selectedPixmap.isNull() ) {
    (*ok) = false;
    return picture;
  }

  image = selectedPixmap;
  if ( image.height() != 140 || image.width() != 100 ) {
    if ( image.height() > image.width() )
      image = image.scaleHeight( 140 );
    else
      image = image.scaleWidth( 100 );
  }

  picture.setData( image );
  (*ok) = true;

  return picture;
}


ImageButton::ImageButton( const TQString &title, TQWidget *parent )
  : TQPushButton( title, parent ),
    mReadOnly( false ), mImageLoader( 0 )
{
  setAcceptDrops( true );

  connect( this, TQT_SIGNAL( clicked() ), TQT_SLOT( load() ) );
}

void ImageButton::setReadOnly( bool readOnly )
{
  mReadOnly = readOnly;
}

void ImageButton::setPicture( const TDEABC::Picture &picture )
{
  mPicture = picture;
  updateGUI();
}

TDEABC::Picture ImageButton::picture() const
{
  return mPicture;
}

void ImageButton::setImageLoader( ImageLoader *loader )
{
  mImageLoader = loader;
}

void ImageButton::startDrag()
{
  if ( !mPicture.data().isNull() ) {
    TQImageDrag *drag = new TQImageDrag( mPicture.data(), this );
    drag->dragCopy();
  }
}

void ImageButton::updateGUI()
{
  if ( mPicture.data().isNull() )
    setPixmap( TDEGlobal::iconLoader()->iconPath( "preferences-desktop-personal", TDEIcon::Desktop ) );
  else
    setPixmap( mPicture.data() );
}

void ImageButton::dragEnterEvent( TQDragEnterEvent *event )
{
  bool accepted = false;

  if ( TQImageDrag::canDecode( event ) )
    accepted = true;

  if ( TQUriDrag::canDecode( event ) )
    accepted = true;

  event->accept( accepted );
}

void ImageButton::dropEvent( TQDropEvent *event )
{
  if ( mReadOnly )
    return;

  if ( TQImageDrag::canDecode( event ) ) {
    TQPixmap pm;

    if ( TQImageDrag::decode( event, pm ) ) {
      mPicture.setData( pm.convertToImage() );
      updateGUI();
      emit changed();
    }
  }

  if ( TQUriDrag::canDecode( event ) ) {
    KURL::List urls;
    if ( KURLDrag::decode( event, urls ) ) {
      if ( urls.isEmpty() ) { // oops, no data
        event->accept( false );
        return;
      }
    }

    if ( mImageLoader ) {
      bool ok = false;
      TDEABC::Picture pic = mImageLoader->loadPicture( urls[ 0 ], &ok );
      if ( ok ) {
        mPicture = pic;
        updateGUI();
        emit changed();
      }
    }
  }
}

void ImageButton::mousePressEvent( TQMouseEvent *event )
{
  mDragStartPos = event->pos();
  TQPushButton::mousePressEvent( event );
}

void ImageButton::mouseMoveEvent( TQMouseEvent *event )
{
  if ( (event->state() & Qt::LeftButton) &&
       (event->pos() - mDragStartPos).manhattanLength() >
       TDEGlobalSettings::dndEventDelay() ) {
    startDrag();
  }
}

void ImageButton::contextMenuEvent( TQContextMenuEvent *event )
{
  TQPopupMenu menu( this );
  menu.insertItem( i18n( "Reset" ), this, TQT_SLOT( clear() ) );
  menu.exec( event->globalPos() );
}

void ImageButton::load()
{
  if ( mReadOnly )
    return;
  KURL url = KFileDialog::getOpenURL( TQString(), KImageIO::pattern(), this );
  if ( url.isValid() ) {
    if ( mImageLoader ) {
      bool ok = false;
      TDEABC::Picture pic = mImageLoader->loadPicture( url, &ok );
      if ( ok ) {
        mPicture = pic;
        updateGUI();
        emit changed();
      }
    }
  }
}

void ImageButton::clear()
{
  mPicture = TDEABC::Picture();
  updateGUI();

  emit changed();
}

ImageBaseWidget::ImageBaseWidget( const TQString &title,
                                  TQWidget *parent, const char *name )
  : TQWidget( parent, name ), mReadOnly( false )
{
  mImageLoader = new ImageLoader( this );

  TQVBoxLayout *topLayout = new TQVBoxLayout( this, KDialog::marginHint(),
                                            KDialog::spacingHint() );
  TQGroupBox *box = new TQGroupBox( 0, Qt::Vertical, title, this );
  TQVBoxLayout *layout = new TQVBoxLayout( box->layout(), KDialog::spacingHint() );

  mImageButton = new ImageButton( i18n( "Picture" ), box );
  mImageButton->setFixedSize( 100, 140 );
  mImageButton->setImageLoader( mImageLoader );
  layout->addWidget( mImageButton );

  topLayout->addWidget( box );

  connect( mImageButton, TQT_SIGNAL( changed() ), TQT_SIGNAL( changed() ) );
}

ImageBaseWidget::~ImageBaseWidget()
{
  delete mImageLoader;
  mImageLoader = 0;
}

void ImageBaseWidget::setReadOnly( bool readOnly )
{
  mReadOnly = readOnly;
  mImageButton->setReadOnly( mReadOnly );
}

void ImageBaseWidget::setImage( const TDEABC::Picture &photo )
{
  mImageButton->setPicture( photo );
}

TDEABC::Picture ImageBaseWidget::image() const
{
  return mImageButton->picture();
}


ImageWidget::ImageWidget( TDEABC::AddressBook *ab, TQWidget *parent, const char *name )
  : KAB::ContactEditorWidget( ab, parent, name )
{
  TQHBoxLayout *layout = new TQHBoxLayout( this, KDialog::marginHint(),
                                         KDialog::spacingHint() );

  mPhotoWidget = new ImageBaseWidget( TDEABC::Addressee::photoLabel(), this );
  layout->addWidget( mPhotoWidget );

  mLogoWidget = new ImageBaseWidget( TDEABC::Addressee::logoLabel(), this );
  layout->addWidget( mLogoWidget );

  connect( mPhotoWidget, TQT_SIGNAL( changed() ), TQT_SLOT( setModified() ) );
  connect( mLogoWidget, TQT_SIGNAL( changed() ), TQT_SLOT( setModified() ) );
}

void ImageWidget::loadContact( TDEABC::Addressee *addr )
{
  mPhotoWidget->setImage( addr->photo() );
  mLogoWidget->setImage( addr->logo() );
}

void ImageWidget::storeContact( TDEABC::Addressee *addr )
{
  addr->setPhoto( mPhotoWidget->image() );
  addr->setLogo( mLogoWidget->image() );
}

void ImageWidget::setReadOnly( bool readOnly )
{
  mPhotoWidget->setReadOnly( readOnly );
  mLogoWidget->setReadOnly( readOnly );
}

#include "imagewidget.moc"
