/****************************************************************************
** listviewmedia - class
**
** This file re-implements the QListView class
** and handles the drag event by re-implementing
** the dragObject function.
**
*****************************************************************************/
#include <qimage.h>
#include <qpoint.h>
#include <qlistview.h>
#include <qfileinfo.h>
#include <qdragobject.h>

#include "sourcefileentry.h"
#include "listviewmedia.h"
#include "listviewitemmedia.h"

ListViewMedia::ListViewMedia (QWidget *pParent, const char *pName, WFlags f)
	: QListView (pParent, pName, f)
{
	setAcceptDrops(true);
	setSorting (-1);
	setAllColumnsShowFocus(true);
	m_pDraggingSourceFileInfo  = NULL;
	m_pDraggingSourceFileEntry = NULL;
	connect (this, SIGNAL (clicked (QListViewItem *, const QPoint &, int)), this , SLOT (slotItemClicked (QListViewItem *, const QPoint &, int)));
}

ListViewMedia::~ListViewMedia ()
{

}

void ListViewMedia::resetDragging ()
{
	// Okay here we should re-set the sourceFileInfo for the next drag...
	m_pDraggingSourceFileEntry = NULL;
	m_pDraggingSourceFileInfo  = NULL;
}

SourceFileEntry *ListViewMedia::draggingSourceFileEntry()
{
	return m_pDraggingSourceFileEntry;
}

SourceFileInfo *ListViewMedia::draggingSourceFileInfo()
{
	return m_pDraggingSourceFileInfo;
}

void ListViewMedia::dropEvent (QDropEvent *pDropEvent)
{
	// This function handles the re-sorting of the SourceFileEntries.
	// Meaning if the user can drag'n drop a SourceFileInfo and drop it where he want's to.
	// Thius also means that we need to handle different SourceFileEntries for the SourceFileInfo.
	// First we check if the source came from this listView, otherwise we don't really care.
	if ( pDropEvent->source() != this )
		return;

	SourceFileEntry *pSourceFileEntry = draggingSourceFileEntry();
	SourceFileInfo  *pSourceFileInfo  = draggingSourceFileInfo ();	// Could be NULL if Header
	// Okay we have the source SourceFileEntry and SourceFileInfo
	// now we need to find the target insertion point
	ListViewItemMedia *pSourceItem = (ListViewItemMedia *)currentItem ();
	ListViewItemMedia *pSourceHeader = pSourceItem;	// We assume the source is a header
	if (!pSourceHeader->sourceFileEntry())
		pSourceHeader = (ListViewItemMedia *)pSourceItem->parent();

	QPoint p = pDropEvent->pos();
	// and since we actually are only looking for a hight comparison,
	// we set x to always hit a entry (if there is one).
	p.setX(50);
	ListViewItemMedia *pTargetItem = (ListViewItemMedia *)itemAt (p);
	ListViewItemMedia *pTargetHeader = pTargetItem;	// We assume for now that the Item is a header.
	if (!pTargetItem)
		return;
	// If we drag'n Drop the same item we don't do nothin'
	if (pTargetItem == pSourceItem)
		return;
	SourceFileEntry *pTargetFileEntry = pTargetItem->sourceFileEntry();
	SourceFileInfo  *pTargetFileInfo  = pTargetItem->sourceFileInfo ();
	if (!pTargetFileEntry)	{
		// If we dragged onto a child (normal case) then we ought to obtain the entry from its parent.
		pTargetHeader = ((ListViewItemMedia *)pTargetItem->parent());
		pTargetFileEntry = pTargetHeader->sourceFileEntry();
	}
	if (!pTargetFileInfo)
		pTargetFileInfo = pTargetFileEntry->listFileInfos[0];
	// Okay at this point we have all we need.
	if (pSourceFileInfo)	{
		// REMOVE and
		pSourceFileEntry->listFileInfos.remove (pSourceFileInfo);
		// Next we check if we removed the last SourceFileInfo from the SourceFileEntry.
		if (pSourceFileEntry->listFileInfos.count() < 1)	{
			emit (signalRemoveEntry (pSourceFileEntry));	// Go back to SourceToolBar::slotRemoveEntry()
			delete pSourceFileEntry;
			pSourceFileEntry = NULL;
		}
		// INSERT
		QValueList<SourceFileInfo *>::iterator it;
		for (it = pTargetFileEntry->listFileInfos.begin(); it != pTargetFileEntry->listFileInfos.end(); ++it)	{
			if ((*it) == pTargetFileInfo)	{
				pTargetFileEntry->listFileInfos.insert (it, pSourceFileInfo);
				break;(ListViewItemMedia *)itemAt (p);
			}
		}

		// In case we jump from one entry to another, we need to build two new entries
		if (pTargetFileEntry != pSourceFileEntry)	{
			// Create only if there is something to create ...
			if (pSourceFileEntry)
				new ListViewItemMedia (this, pSourceItem, pSourceFileEntry, pSourceItem->backgroundColor());
			delete pSourceHeader;
		}
		new ListViewItemMedia (this, pTargetItem, pTargetFileEntry, pTargetItem->backgroundColor());
		delete pTargetHeader;
	}
	else 	{	// If pSourceFileInfo = NULL then the user only wants
			//to reposition the SourceFileEntry in the list.
		new ListViewItemMedia (this, pSourceItem, pTargetFileEntry, pSourceItem->backgroundColor());
		delete pTargetHeader;
	}
	resetDragging ();
//	triggerUpdate ();
	return;
}

void ListViewMedia::dragEnterEvent(QDragEnterEvent *pEvent)
{
	// Tell the Widget that we accept ImageDrops ...
	// This is necessary otherwise the dropEvent does not occur.
	pEvent->accept(QImageDrag::canDecode(pEvent));
}

QDragObject *ListViewMedia::dragObject()
{
	ListViewItemMedia *pCurrentItem     = (ListViewItemMedia *)currentItem ();
	SourceFileEntry   *pSourceFileEntry = NULL;
	SourceFileInfo    *pSourceFileInfo  = NULL;
	if (!pCurrentItem)
		return NULL;

	QImage  theImage;
	QPixmap thePixmap;
	QSize sizeThumbnail;
	bool bResetSourceFileInfo=false;

	// Check if we drag the header (SourceFileEntry)
	pSourceFileEntry = pCurrentItem->sourceFileEntry();
	if (pSourceFileEntry)	{
		pSourceFileInfo = pSourceFileEntry->listFileInfos[0];
		sizeThumbnail   = pSourceFileEntry->sizeThumbnail;
		bResetSourceFileInfo=true;
	}
	else	{	// Or if we drag the child (SourceFileInfo)
		pSourceFileInfo = pCurrentItem->sourceFileInfo ();
		// Quick sanity check.
		if (pSourceFileInfo)	{
			if (pCurrentItem->pixmap(0))
				sizeThumbnail   = pCurrentItem->pixmap(0)->size();
			// Okay we also need the SourceFileEntry to this ...
			pCurrentItem = (ListViewItemMedia *)pCurrentItem->parent();
			pSourceFileEntry = pCurrentItem->sourceFileEntry();
		}
	}
	// error. We should never get here
	if (!pSourceFileInfo)
		return NULL;

	m_pDraggingSourceFileEntry = pSourceFileEntry;
	m_pDraggingSourceFileInfo  = pSourceFileInfo;
	if (bResetSourceFileInfo)	// NULL is a sign for the receiver (MenuPreview) that we dragged the whole thing ...
		m_pDraggingSourceFileInfo = NULL;

	theImage  = QImage  (*pSourceFileInfo->pPreview);
	thePixmap = QPixmap ( theImage.smoothScale (sizeThumbnail, QImage::ScaleMin) );

	QDragObject *pDragObject = new QImageDrag (theImage, this);
	pDragObject->setPixmap (thePixmap);
//	pDragObject->drag();
//	pDragObject->dragMove();
//	pDragObject->dragCopy();
	return pDragObject;
}


void ListViewMedia::slotItemClicked (QListViewItem *pItem, const QPoint &thePoint, int)
{
	if (!pItem)
		return;
	ListViewItemMedia *pMediaItem = (ListViewItemMedia *)pItem;
	pMediaItem->itemClicked((QPoint &)thePoint);
}

