#include "kflistbase.h"
#include <iostream.h>
#include <stdlib.h>
#include <qdragobject.h>

KFileListBase::KFileListBase(QWidget *parent, const char *name, WFlags f)
	: QTableView(parent,name,f)
{
	setBackgroundColor(colorGroup().base());
	setNumRows(0);
	setNumCols(0);
	FileList = 0;
	LinkArrow = 0;
	Selected = new FileInfoList;
	Selected->setAutoDelete(FALSE);
	Edit = new KFileEdit("",this);
	Editing = FALSE;
	Edit->hide();
	CellEdited = 0;
	connect(Edit,SIGNAL(cancelEdit()),SLOT(cancelEdit()));
	connect(Edit,SIGNAL(terminateEdit()),SLOT(terminateEdit()));
	canDrag = FALSE;
	press_x = press_y = 0;
}

KFileListBase::~KFileListBase()
{
	delete Edit;
	delete Selected;
}

void KFileListBase::setFileList(FileInfoList *list, bool keepSel)
{
	cancelEdit();
	FileList = list;
	if (!keepSel) Selected->clear();
	updateListSize();
	update();
}

void KFileListBase::mousePressEvent(QMouseEvent *e)
{
	cancelEdit();
	int	row = findRow(e->y()), col = findCol(e->x());
	press_x = e->x();
	press_y = e->y();
	FileInfo	*current = 0;
	bool		itemSelected;
	if (row < 0 || col < 0) itemSelected = FALSE;
	else itemSelected = getItemCell(row,col,&current,QPoint(e->x(),e->y()));
	if (e->button() == LeftButton) {
		if (itemSelected) {
			if ((e->state() & ShiftButton) && Selected->count() > 0) {
				FileInfo	*begin = Selected->last();
				int	minrow = QMIN(begin->index(),current->index());
				int	maxrow = QMAX(begin->index(),current->index());
				for (int i=minrow;i<=maxrow;i++)
					addToSelection(FileList->at(i));
			}
			else if (e->state() & ControlButton) {
				if (Selected->findRef(current) != -1) removeFromSelection(current);
				else addToSelection(current);
			}
			else {
				if (Selected->findRef(current) != -1) {
					if (Selected->count() > 1 || !getItemTextRect(current).contains(QPoint(e->x(),e->y()))) canDrag = TRUE, ItemClicked = current;
					else {
						Editing = TRUE;
						CellEdited = current;
						Edit->setGeometry(getItemTextRect(current));
						Edit->setText(current->fileName().data());
						Edit->selectAll();
						Edit->show();
						Edit->setFocus();
						addToSelection(current);
					}
				}
				else {
					removeSelection();
					addToSelection(current);
					canDrag = TRUE;
					ItemClicked = current;
				}
			}
		}
		else if (!(e->state() & ControlButton) && !(e->state() & ShiftButton) && !(e->state() & AltButton))
			removeSelection();
	}
	else if (e->button() == RightButton) {
		if (!itemSelected) removeSelection();
		else if (Selected->findRef(current) == -1) {
			removeSelection();
			addToSelection(current);
		}
		emit popup();
	}
}

void KFileListBase::mouseMoveEvent(QMouseEvent *e)
{
	if (canDrag && Selected->count() > 0) {
		if (abs(e->x() - press_x) + abs(e->y() - press_y) > 10) {
			FileInfoListIterator	it(*Selected);
			QStrList		list;
			for (;it.current();++it) list.append(it.current()->absFilePath());
			QUrlDrag	*object = new QUrlDrag(list,this);
			if (DNDIcon) object->setPixmap(*DNDIcon);
			object->drag();
		}
	}
}

void KFileListBase::mouseReleaseEvent(QMouseEvent *)
{ canDrag = FALSE;}

void KFileListBase::mouseDoubleClickEvent(QMouseEvent *e)
{
	int	col = findCol(e->x()), row = findRow(e->y());
	FileInfo	*current = 0;
	bool		itemSelected;
	if (row < 0 || col < 0) itemSelected = FALSE;
	else itemSelected = getItemCell(row,col,&current,QPoint(e->x(),e->y()));
	if (current && itemSelected && e->button() == LeftButton) {
		emit openItem(current);
	}
}

void KFileListBase::removeSelection()
{
	if (Selected->count() == 0) return;
	FileInfo	*item = Selected->first();
	int	row = 0,col = 0;
	while (item) {
		Selected->remove();
		getTablePosition(item->index(),row,col);
		updateCell(row,col);
		item = Selected->first();
	}
	emit selectionChanged();
}

void KFileListBase::setLinkArrow(QPixmap *larrow)
{
	LinkArrow = larrow;
}

void KFileListBase::setDNDIcon(QPixmap *dndicon)
{
	DNDIcon = dndicon;
}

void KFileListBase::addToSelection(FileInfo *item)
{
	if (Selected->findRef(item) == -1) {
		Selected->append(item);
		int	row,col;
		getTablePosition(item->index(),row,col);
		updateCell(row,col);
		emit selectionChanged();
	}
}

void KFileListBase::removeFromSelection(FileInfo *item)
{
	Selected->removeRef(item);
	int	row,col;
	getTablePosition(item->index(),row,col);
	updateCell(row,col);
	emit selectionChanged();
}

void KFileListBase::selectAll()
{
	if (FileList != 0) {
		Selected->clear();
		FileInfoListIterator	it(*FileList);
		for ( ;it.current();++it) Selected->append(it.current());
		update();
		emit selectionChanged();
	}
}

void KFileListBase::cancelEdit()
{
	if (Editing) {
		int	row = 0, col = 0;
		getTablePosition(CellEdited->index(),row,col);
		Edit->hide();
		updateCell(row,col);
		Editing = FALSE;
	}
}

void KFileListBase::terminateEdit()
{
	if (Editing) {
		emit renameItem(CellEdited,QString(Edit->text()));
		Edit->hide();
		Editing = FALSE;
	}
}

void KFileListBase::setSelection(FileInfoList& list)
{
	removeSelection();
	FileInfoListIterator	it(list);
	for (;it.current();++it) Selected->append(it.current());
	update();
}
