/***************************************************************************
                          devicesapplet.cpp  -  description
                             -------------------
    begin                : jeu jui 24 18:57:47 CEST 2003
    copyright            : (C) 2003 by ervin
    email                : ervin at tuxfamily dot 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <kglobal.h>
#include <klocale.h>
#include <kconfig.h>
#include <kapp.h>
#include <kaboutdata.h>
#include <kaboutapplication.h>
#include <kdebug.h>
#include <kpopupmenu.h>
#include <kiconloader.h>

#include "devicesapplet.h"

#include "preferencesdialog.h"

extern "C"
{
	KPanelApplet* init( QWidget *parent, const QString configFile)
	{
		KGlobal::locale()->insertCatalogue("devicesapplet");
		return new DevicesApplet(configFile, KPanelApplet::Normal,
			KPanelApplet::About | KPanelApplet::Preferences,
			parent, "devicesapplet");
  }
}

DevicesApplet::DevicesApplet(const QString& configFile, Type type, int actions, QWidget *parent, const char *name)
	: KPanelApplet(configFile, type, actions, parent, name)
{
	if (!parent)
		setBackgroundMode(X11ParentRelative);

	loadConfig();
	mButtonList.setAutoDelete(true);

	mpDirLister = new KDirLister();

	connect( mpDirLister, SIGNAL( clear() ),
	         this, SLOT( slotClear() ) );
	connect( mpDirLister, SIGNAL( started(const KURL&) ),
	         this, SLOT( slotStarted(const KURL&) ) );
	connect( mpDirLister, SIGNAL( completed() ),
	         this, SLOT( slotCompleted() ) );
	connect( mpDirLister, SIGNAL( newItems( const KFileItemList & ) ),
	         this, SLOT( slotNewItems( const KFileItemList & ) ) );
	connect( mpDirLister, SIGNAL( deleteItem( KFileItem * ) ),
	         this, SLOT( slotDeleteItem( KFileItem * ) ) );
	connect( mpDirLister, SIGNAL( refreshItems( const KFileItemList & ) ),
	         this, SLOT( slotRefreshItems( const KFileItemList & ) ) );

	reloadList();
}

DevicesApplet::~DevicesApplet()
{
	delete mpDirLister;
	mButtonList.clear();
        KGlobal::locale()->removeCatalogue("devicesapplet");
}

void DevicesApplet::about()
{
	KAboutData data("devicesapplet",
	                I18N_NOOP("Devices Applet"),
	                "1.0",
	                I18N_NOOP("\"devices:/\" ioslave frontend applet"),
	                KAboutData::License_GPL_V2,
	                "(c) 2003, Kevin Ottens");

	data.addAuthor("Kevin \"ervin\" Ottens",
	               I18N_NOOP("Maintainer"),
	               "ervin@tuxfamily.org",
	               "http://ervin.tuxfamily.org");

	data.addCredit("Joseph Wenninger",
	               I18N_NOOP("Good mentor, patient and helpful. Thanks for all!"),
	               "jowenn@kde.org");

	KAboutApplication dialog(&data);
	dialog.exec();
}

void DevicesApplet::preferences()
{
	PreferencesDialog dialog(mDevices);

	dialog.setExcludedDeviceTypes(mExcludedTypesList);
	dialog.setExcludedDevices(mExcludedList);

	if(dialog.exec())
	{
		mExcludedTypesList = dialog.excludedDeviceTypes();
		mExcludedList = dialog.excludedDevices();
		saveConfig();
		reloadList();
	}
}

int DevicesApplet::widthForHeight( int height ) const
{
	return mButtonList.count()*height;
}

int DevicesApplet::heightForWidth( int width ) const
{
	return mButtonList.count()*width;
}

void DevicesApplet::resizeEvent( QResizeEvent *)
{
	arrangeButtons();
}

void DevicesApplet::arrangeButtons()
{
	int icon_size = 0;
	int x_offset = 0;
	int y_offset = 0;

	if(orientation() == Vertical)
	{
		icon_size = width();
		x_offset = 0;
		y_offset = icon_size;
	}
	else
	{
		icon_size = height();
		x_offset = icon_size;
		y_offset = 0;
	}

	int i = 0;
	for(DeviceButton *button = mButtonList.first(); button; button = mButtonList.next())
	{
		button->resize(icon_size, icon_size);
		button->move(i*x_offset, i*y_offset);
		button->setPanelPosition(position());
		i++;
	}

	updateGeometry();
	emit updateLayout();
}

void DevicesApplet::slotClear()
{
	kdDebug()<<"DevicesApplet::slotClear"<<endl;

	mButtonList.clear();
	arrangeButtons();
}

void DevicesApplet::slotStarted(const KURL &/*url*/)
{

}

void DevicesApplet::slotCompleted()
{
	mDevices = mpDirLister->items(KDirLister::AllItems);
}

void DevicesApplet::slotNewItems(const KFileItemList &entries)
{
	kdDebug()<<"DevicesApplet::slotNewItems"<<endl;

	for(KFileItemListIterator it(entries); it.current(); ++it)
	{
		if( !mExcludedList.contains(it.current()->url().url()) )
		{
			DeviceButton *button = new DeviceButton(this, *it.current());
			button->show();
			mButtonList.append(button);
		}
	}

	arrangeButtons();
}

void DevicesApplet::slotDeleteItem(KFileItem *fileItem)
{
	kdDebug()<<"DevicesApplet::slotDeleteItems"<<endl;

	for(DeviceButton *button = mButtonList.first(); button; button = mButtonList.next())
	{
		if(button->fileItem().url()==fileItem->url())
		{
			mButtonList.remove(button);
			break;
		}
	}

	arrangeButtons();
}

void DevicesApplet::slotRefreshItems(const KFileItemList &entries)
{
	for(KFileItemListIterator it(entries); it.current(); ++it)
	{
		kdDebug()<<"DevicesApplet::slotRefreshItems:"<<(*it.current()).url().url()<<endl;

		it.current()->refresh();

		QString mimetype = (*it.current()).mimetype();
		bool found = false;

		kdDebug()<<"mimetype="<<mimetype<<endl;

		for(DeviceButton *button = mButtonList.first(); button; button = mButtonList.next())
		{
			if(button->fileItem().url()==(*it.current()).url())
			{
				if(mExcludedTypesList.contains(mimetype))
				{
					mButtonList.remove(button);
				}
				else
				{
					button->setFileItem(*it.current());
				}
				found = true;
				break;
			}
		}

		if(!found && !mExcludedTypesList.contains(mimetype) && !mExcludedList.contains(it.current()->url().url()) )
		{
			DeviceButton *button = new DeviceButton(this, *it.current());
			button->show();
			mButtonList.append(button);
		}
	}

	arrangeButtons();
}

void DevicesApplet::positionChange(Position)
{
	arrangeButtons();
}

void DevicesApplet::loadConfig()
{
	KConfig *c = config();
	c->setGroup("General");

	if(c->hasKey("ExcludedTypes"))
	{
		mExcludedTypesList = c->readListEntry("ExcludedTypes",';');
	}
	else
	{
		mExcludedTypesList.clear();
		mExcludedTypesList << "kdedevice/hdd_mounted";
		mExcludedTypesList << "kdedevice/hdd_unmounted";
		mExcludedTypesList << "kdedevice/cdrom_unmounted";
		mExcludedTypesList << "kdedevice/cdwriter_unmounted";
		mExcludedTypesList << "kdedevice/dvd_unmounted";
	}

	if(c->hasKey("ExcludedDevices"))
	{
		mExcludedList = c->readListEntry("ExcludedDevices",';');
	}
	else
	{
		mExcludedList.clear();
	}

}

void DevicesApplet::saveConfig()
{
	KConfig *c = config();
	c->setGroup("General");

	c->writeEntry("ExcludedTypes", mExcludedTypesList, ';');
	c->writeEntry("ExcludedDevices", mExcludedList, ';');

	c->sync();
}

void DevicesApplet::reloadList()
{
	mpDirLister->stop();
	mButtonList.clear();
	mpDirLister->clearMimeFilter();
	mpDirLister->setMimeExcludeFilter(mExcludedTypesList);
	mpDirLister->openURL(KURL("devices:/"));
}

void DevicesApplet::mousePressEvent(QMouseEvent *e)
{
	if(e->button()==RightButton)
	{
		KPopupMenu menu(this);

		menu.insertTitle(i18n("Devices"));
		menu.insertItem(SmallIcon("configure"), i18n("&Configure..."), 1);

		int choice = menu.exec(this->mapToGlobal(e->pos()));

		if(choice==1)
		{
			preferences();
		}
	}
}

#include "devicesapplet.moc"
