/*
 * This file is part of DesktopBSD, see the README file.
 *
 * Author: Peter Hofer <ph@desktopbsd.net>
 *			(C) 2004, 2005
 *
 * Copyright: BSD, see the COPYING file included in this distribution
 *
 */

#include <dbsdglobal.h>
#include <mntdevice.h>
#include <dialogs.h>

/* Qt */
#include <qptrlist.h>

static const Size::Unit  unit = Size::MB;


bool  modMount::needsRoot() {
	/* fdisk and bsdlabel need to be able
	 * to read from the device file, which
	 * is usually only possible as root.
	 */

	return  true;
}


void  modMount::mountUnmount() {
	QListViewItem  *curItem = lstDevices->selectedItem();
	MntDevice  *device = devices[curItem];
	if(device == NULL)
		return;

	bool  success;
	if(device->isMounted()) {
		success = device->unmount();

	 /** @todo  Just asking the user to click "Yes" or "No"
		*		  is probably bad. We really should make something
		*		  more secure, like disabling the "Yes" button
		*		  for about 5 seconds.
		*/
		if(!success && Dialogs::question(
							 tr("Error: Unable to unmount the file-system.\n"
								  "\n"
								  "Possible reasons:\n"
								  "- There are still files in use from this file system.\n"
								  "- The device was removed.\n"
								  "- The device was mounted by another user.\n"
								  "\n"
								  "You can unmount the file system forcibly, but\n"
								  "DO NOT do that if the device was already removed.\n"
								  "\n"
								  "Do you want to unmount forcibly?\n"
								  "ATTENTION:  You will LOSE DATA!")))
		{
		  device->unmount(true);
		}
	} else {
		success = device->mount();
		if(!success)
			Dialogs::warnDlg(tr("Mounting this device failed.\n\n" \

									  "Probably the file-system type is not\n" \
									  "supported or no media is inserted."));
	}

	if(success)
		refresh();
}


void modMount::initModule() {
	refresh();
}


void modMount::destroy() {
	if(wasInitialized()) {
		QListViewItem  *child = lstDevices->firstChild();

	  /* Remove only "top-level" devices, they delete their
		* subdevices (slices and partitions) on their own.
		*/
		while(child != NULL) {
			delete  devices.take(child);
			child = child->nextSibling();
		}
	}
}


void modMount::insertMntDev(MntDevice *mdev, const QString& desc, QPixmap pix) {
	QListViewItem  *item = new  QListViewItem(lstDevices,  desc);
	item->setPixmap(0, pix);
	devices.insert(item, mdev);

	for(int i = mdev->subdevCount() - 1; i >= 0; --i)
		insertMntDev((*mdev)[i], item);
}


void modMount::insertMntDev(MntDevice *mdev,  QListViewItem *item) {
	item->setOpen(true);
	item->setSelectable(false);

	QListViewItem  *subitem = new QListViewItem(item,
															  mdev->getDesc(),
															  mdev->getSize().toString(Size::MB));
	devices.insert(subitem, mdev);

	uint  subdevs = mdev->subdevCount();
	if(subdevs > 0)
		subitem->setPixmap(0, QPixmap::fromMimeSource("slice.png"));
	else
		subitem->setPixmap(0, mdev->isMounted()
									?	QPixmap::fromMimeSource("mounted.png")
									:  QPixmap::fromMimeSource("unmounted.png"));

	for(int i = (int) subdevs - 1; i >= 0; --i)
		insertMntDev((*mdev)[i], subitem);
}


void modMount::devSelected(QListViewItem  *item) {
	DBSDIconLoader  *iloader = DBSDGlobal::getIconLoader();

	MntDevice  *mdev = devices[item];
	if(mdev != NULL) {
		/* Devices with subdevices can't be mounted */
		if(item->childCount() == 0) {
			if(!mdev->isMounted()) {
				btnMountUnmount->setText(tr("Mount"));
				btnMountUnmount->setIconSet(iloader->loadIcon("attach",
																			 DBSDIconLoader::Button));
			} else {
				btnMountUnmount->setText(tr("Unmount"));
				btnMountUnmount->setIconSet(iloader->loadIcon("cancel",
																			 DBSDIconLoader::Button));
			}
			btnMountUnmount->show();
		} else
			btnMountUnmount->hide();
	}
}


void modMount::refresh() {
	DBSDIconLoader  *iloader = DBSDGlobal::getIconLoader();
	QPixmap  pixHDD[2]  = {	iloader->loadIcon("hdd_unmount", DBSDIconLoader::Size22x22),
									iloader->loadIcon("hdd_mount", DBSDIconLoader::Size22x22) };

	QPixmap  pixFloppy[2]  = {	iloader->loadIcon("3floppy_unmount", DBSDIconLoader::Size22x22),
										iloader->loadIcon("3floppy_mount", DBSDIconLoader::Size22x22) };

	QPixmap  pixDisc[2] = {	iloader->loadIcon("cdrom_unmount", DBSDIconLoader::Size22x22),
									iloader->loadIcon("cdrom_mount", DBSDIconLoader::Size22x22) };


	/* Empty lists */
	devices.clear();
	lstDevices->clear();

	MntDevice  *mdev;
	QPtrList<MntDevice>  list = MntDevice::getAllDevices();

	mdev = list.first();
	while(mdev != NULL) {
		if(mdev->isATAPICAMDevice()) {
			/* Ignore */
			if(list.current() == list.getLast())
				mdev = NULL;
				
			delete list.take();
			
			if(mdev != NULL)
				mdev = list.current();
				
			continue;
		}

		QPixmap  *pix;
		QString	desc = mdev->getDesc();

		uint  index = mdev->isMounted() ? 1 : 0;

		switch(mdev->getDeviceType()) {
		case  Device::ATAPI_CD:
		case  Device::SCSI_CD:
			pix = &pixDisc[index];
			break;

		case  Device::Floppy:
			pix = &pixFloppy[index];
			break;

		default:
			pix = &pixHDD[index];
			break;
		}

		insertMntDev(mdev, desc, *pix);

		mdev = list.next();
	}

	devSelected(lstDevices->firstChild());
}




void modMount::init() {
	DBSDIconLoader  *iloader = DBSDGlobal::getIconLoader();
	btnRefresh->setIconSet(iloader->loadIcon("reload", DBSDIconLoader::Button));
	pixPermissionHint->setPixmap(iloader->loadIcon("info", DBSDIconLoader::HintIcon));
	
	lstDevices->setSorting(-1);
}
