/***************************************************************************
                          photo_iconview.cpp  -  description
                             -------------------
    begin                : Sun Jan 13 2002
    copyright            : (C) 2002 by Renchi Raju
    email                : renchi@green.tam.uiuc.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 <qstring.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qdatetime.h>
#include <qpopupmenu.h>

#include <klocale.h>
#include <kiconloader.h>
#include <kmimetype.h>
#include <kurl.h>
#include <kurldrag.h>
#include <kapp.h>
#include <kfileviewitem.h>
#include <kmessagebox.h>
#include <ktrader.h>
#include <kservice.h>
#include <krun.h>
#include <kio/jobclasses.h>
#include <kpropsdlg.h>

#include "photo_iconview.h"
#include "thumbnailloadjob.h"
#include "image_viewer.h"

Photo_IconView::Photo_IconView(QWidget* parent, const char* name):
  QIconView(parent, name), KFileView()
{
  setAutoArrange(true);
  setItemsMovable(false);
  setResizeMode(Adjust);
  setShowToolTips(true);
  setWordWrapIconText(true);
  setSpacing(5);

  setGridX(95);
  setGridY(95);
  QIconView::setSelectionMode(QIconView::Extended);
  KFileView::setSelectionMode ( KFile::Extended );
 
  connect( this, SIGNAL( doubleClicked(QIconViewItem*) ), 
	   this, SLOT( slot_displayImage(QIconViewItem*) ) );
  connect( this, SIGNAL( rightButtonPressed(QIconViewItem*, const QPoint&) ),
	   this, SLOT( slot_popupMenu(QIconViewItem*, const QPoint&) ) );
  connect( this, SIGNAL(itemRenamed(QIconViewItem *, const QString &)), 
	   SLOT(slot_itemRenamed(QIconViewItem *, const QString &)) );
}

Photo_IconView::~Photo_IconView(){
  stopGenThumbnail();
}

void Photo_IconView::insertItem(KFileViewItem* item) {

  if (!item) return;

  QIconViewItem* iconItem=new QIconViewItem(this,item->text());
  iconItem->setRenameEnabled(true);
  iconItem->setPixmap(BarIcon("image", KIcon::SizeLarge));
  item->setViewItem(this,iconItem);

}


void Photo_IconView::removeItem(const KFileViewItem* fileItem) {

  if (!fileItem) return;
  
  if (!thumbnailGenerator.isNull())
    thumbnailGenerator->itemRemoved(fileItem);
  
  const QIconViewItem* iconItem=static_cast<const QIconViewItem*>( fileItem->viewItem(this) );
  delete iconItem;
  KFileView::removeItem(fileItem);
  arrangeItemsInGrid();
}




void Photo_IconView::ensureItemVisible(const KFileViewItem* fileItem) {
  if (!fileItem) return;
  
  QIconViewItem* iconItem=(QIconViewItem*)( fileItem->viewItem(this) );
  QIconView::ensureItemVisible(iconItem);
}


void Photo_IconView::setSelected(const KFileViewItem* fileItem,bool enable) {
  if (!fileItem) return;
  
  QIconViewItem* iconItem=(QIconViewItem*)( fileItem->viewItem(this) );
  QIconView::setSelected(iconItem, enable);
}


bool Photo_IconView::isSelected(const KFileViewItem* fileItem) const {

  if (!fileItem) return false;

  QIconViewItem* iconItem=(QIconViewItem*)( fileItem->viewItem(this) );
  if (!iconItem) return false;
  
  if (iconItem->isSelected()) 
    return true;
  else
    return false;

}



void Photo_IconView::clearView() {
  for (KFileViewItem* item = KFileView::firstItem();item; item=item->next()) {
    item->setViewItem(this,0L);
  }
  QIconView::clear();
}


void Photo_IconView::startGenThumbnail() {

  thumbnailGenerator = new ThumbnailLoadJob(this->items(), thumbnailSize);
  connect(thumbnailGenerator, SIGNAL(thumbnailLoaded(const KFileViewItem*,const QPixmap&)),
	  this, SLOT(slot_setThumbnail(const KFileViewItem*,const QPixmap&)) );
  connect(thumbnailGenerator, SIGNAL(result(KIO::Job*)),
	  this, SIGNAL(stoppedGenThumbnail()) );
  emit startedGenThumbnail(QIconView::count());
  thumbnailGenerator->start();

}

void Photo_IconView::stopGenThumbnail() {

  if (!thumbnailGenerator.isNull()) {
    emit stoppedGenThumbnail();
    thumbnailGenerator->kill();
  }

}

void Photo_IconView::slot_setThumbnail(const KFileViewItem* fileViewItem, const QPixmap& thumbnail) 
{
  
  QIconViewItem* item=static_cast<QIconViewItem*>( const_cast<void*>(fileViewItem->viewItem(this)) );
  int pixelSize=thumbnailSize.pixelSize();

  item->setPixmap(thumbnail);
  emit generatedOneThumbnail();

}

void Photo_IconView::setThumbSize(ThumbnailSize size) {

  if (size == thumbnailSize) return;
  thumbnailSize = size;
  setGridX(size.pixelSize() + 10);
  setGridY(size.pixelSize() + 10);
  arrangeItemsInGrid();
}

void Photo_IconView::slot_displayImage(QIconViewItem* item) {

  if (!item) return;

  KFileViewItem* fileItem = ((KFileView*)this)->firstItem();
  while (fileItem) {
    if ( (QIconViewItem*) fileItem->viewItem(this)
	 == item ) break;
    fileItem = fileItem->next();
  }
  
  if (!(fileItem)) return;

  QString fullPath = (fileItem->url()).path();

  Image_Viewer* imgView = new Image_Viewer();
  imgView->loadImage(fullPath);
  imgView->show();

}


void Photo_IconView::slot_popupMenu(QIconViewItem* item, const QPoint& pos) {

  if (!item) return;

  KFileViewItem* fileItem = ((KFileView*)this)->firstItem();
  while (fileItem) {
    if ( (QIconViewItem*) fileItem->viewItem(this)
	 == item ) break;
    fileItem = fileItem->next();
  }
  
  if (!(fileItem)) return;
  QString fullPath = (fileItem->url()).path();

  QPopupMenu *mainMenu = new QPopupMenu();
  mainMenu->insertItem( BarIcon("image", KIcon::SizeSmall), i18n("View"), 10);
  mainMenu->insertItem( BarIcon("pencil", KIcon::SizeSmall), i18n("Rename"), 11);
  mainMenu->insertItem( BarIcon("trashcan_empty", KIcon::SizeSmall), i18n("Delete"), 12);
  mainMenu->insertItem( i18n("Properties"), 13);
  int index = 13;

  QPopupMenu *openMenu = new QPopupMenu();
  KTrader::OfferList offers = KTrader::self()->query(fileItem->mimeTypePtr()->name(), "Type == 'Application'");
  KTrader::OfferList::Iterator it;
  KService::Ptr ptr;
  for( it = offers.begin(); it != offers.end(); ++it ) {
    ptr = *it;
    openMenu->insertItem( ptr->pixmap(1), ptr->name(), ++index);
  }

  mainMenu->insertItem(i18n("Open With ..."), openMenu, 1);

  int id = mainMenu->exec(pos);
  
  if (id == 10) 
    // Display Image
    slot_displayImage(item);
  else if (id == 11) {
    // Rename Image
    item->rename();
  }
  else if (id == 12) {
    // Delete Image(s)
    KURL::List lst;
    QStringList imageList;

    const KFileViewItemList* fileItems  = items();
    KFileViewItemListIterator it(*fileItems);
    for ( ; it.current(); ++it ) {
      QIconViewItem* iconItem=(QIconViewItem*)( it.current()->viewItem(this) );
      if ( iconItem->isSelected() ) {
	lst.append( (it.current()->url()).path() );
	imageList.append(it.current()->url().path());
      }
    }

    if (lst.count() > 0) {
      if (KMessageBox::warningContinueCancelList(this, "About to delete these Image(s)\n"
					     "Are you sure?",imageList, "Warning",
					     "Delete") ==  KMessageBox::Continue) {
	KIO::DeleteJob *job = KIO::del(lst, false, true);
      }
    }
  }
  else if (id == 13) {
    
    (void)new KPropertiesDialog(fileItem->url());

  }
  else if (id > 13) {
    KTrader::OfferList::Iterator it2;
    int j = 14;
    for( it2 = offers.begin(); it2 != offers.end(); ++it2 ) {
      ptr = *it2;
      if (j == id) break;
      ++j;
    }
    KURL::List lst;
    lst.append(fullPath);
    KRun::run(*ptr, lst);
  }
  delete mainMenu;
}


void Photo_IconView::slot_itemRenamed(QIconViewItem* item,const QString& newName) {

  if (!item) return;
  KFileViewItem* fileItem = ((KFileView*)this)->firstItem();
  while (fileItem) {
    if ( (QIconViewItem*) fileItem->viewItem(this)
	 == item ) break;
    fileItem = fileItem->next();
  }
  if (!(fileItem)) return;
  
  KURL oldurl = fileItem->url();
  QString newPath = oldurl.directory(false,true) + newName;
  KURL newurl(oldurl);
  newurl.setPath(newPath);

  if ( oldurl != newurl ) {
    KURL::List lst;
    lst.append(oldurl);
    KIO::Job * job = KIO::moveAs( oldurl, newurl );
  }
}

// -------Drag n Drop -------------------------------

void Photo_IconView::startDrag() {
  
  const KFileViewItemList* fileItemList = selectedItems();
  if (fileItemList->isEmpty()) return;

  KFileViewItemListIterator it(*fileItemList);
  KURL::List urls;
  for ( ; it.current(); ++it ) 
    urls.append((*it)->url());


  QUriDrag* drag = KURLDrag::newDrag( urls, this );
  drag->setPixmap( fileItemList->getFirst()->pixmap() );
  drag->dragCopy();

}
