/***************************************************************************
                          sitemanagerdb.h  -  description
                             -------------------
    begin                : tis mar 12 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef SITEMANAGERDB_H
#define SITEMANAGERDB_H

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qtimer.h>
#include <qdom.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kapplication.h>
#include <dcopclient.h>
#include <ksystemtray.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "sitemanagerdbiface.h"

class SiteManagerDBSignaler;

/**
  *@author Björn Sahlström
  */

///////////////////////////////////////////////////////////////////////
// class SiteManagerDB
//////////////////////////////////////////////////////////////////////
class SiteManagerDB : public SiteManagerDBIface {
public:
	/** */
	SiteManagerDB();
	/** */
	~SiteManagerDB();
	/** */
	QDomNode findSite( const SiteInfo& );
	/** */
	QDomNode findGroup( const Group& );
	/**
	* The sitemanager plugin calls this every second..
	*/
	virtual bool ping();
	/**
	* Each instance using the database has to register.
	* The app exit when last referer has unregistered.
	* @see #unregReferer
	*/
	virtual void regReferer();
	/**
	* Each instance using the database must unregister when it has no more use of the database.
	* The app exit when last referer has unregistered.
	* @see #regReferer
	*/
	virtual void unregReferer();
	/** For internal use only */
	void unregReferer( const QCString& appID );
	/**
	* Call this to save a @ref Site .
	* Emits DCOP signal @ref #newSite
	* @param site @ref Site to add.
	* @see #newSite
	*/
	virtual void saveSite( SiteInfo site );
	/**
	* Call this to change an existing @ref Site.
	* Emits DCOP signal @ref #changeSite
	* @param site @ref Site to change.
	* @param oldLabel is the old label before change.
	* @see #changeSite
	*/
	virtual void changeSite( SiteInfo site, QString oldLabel );
	/**
	* Call this to remove a @ref Site .
	* Emits DCOP signal @ref #siteRemoved
	* @param site is the @ref Site to remove.
	* @see #siteRemoved
	*/
	virtual void removeSite( SiteInfo site );
	/**
	* Call this to move a @ref Site within the site tree.
	* Emits DCOP signal @ref #siteMoved
	* @param site is the @ref Site to move.
	* @param newParent is the new parent for the @ref Site to move.
	* @see #siteMoved
	*/
	virtual void moveSite( SiteInfo site, QString newParent );
	/**
	* @param site should containn the parent and the label for the site to retrieve.
	* @return a @ref Site matching the label and the parent
	*/
	virtual SiteInfo getSite( SiteInfo site );
	/**
	* Call this to save a new @ref Group.
	* Emits DCOP signal @ref #newGroup
	* @param site @ref Group to add.
	* @see #newGroup
	*/
	virtual void saveGroup( Group group );
	/**
	* Call this to change an existing @ref Group.
	* Emits DCOP signal @ref #changeGroup
	* @param group @ref Group to change.
	* @param oldLabel is the old label before change.
	* @see #changeGroup
	*/
	virtual void changeGroup( Group group, QString oldLabel );
	/**
	* Call this to remove a @ref Group.
	* Emits DCOP signal @ref #groupRemoved
	* @param group is @ref Group to remove.
	* @see #groupRemoved
	*/
	virtual void removeGroup( Group group );
	/**
	* Call this to move a @ref Group within the site tree.
	* Emits DCOP signal @ref #groupMoved
	* @param group is @ref Group to move.
	* @param newParent is the new parent for the @ref Group to move.
	* @see #groupMoved
	*/
	virtual void moveGroup( Group group, QString newParent );
	/**	
	* Call this to receive the entire database Dom Document as a @ref QString.
	*/
	virtual QString getSiteDataBase() { return domDocument().toString(); }
	/**	
	* Call this to retreive the encoding of the database.
	* @return a @ref QString containing the encoding like: 'iso 8859-1'
	* @see #setEncoding
	*/
	virtual QString encoding();
	/**	
	* Call this to set the encoding of the database.
	* emitts the signal @ref #newEncoding
	* @param encoding should contain the new encoding like: 'iso 8859-1'
	* @see #encoding
	* @see #newEncoding
	*/
	virtual void setEncoding( QString encoding );
	/**	
	* Call this to import a @ref QDomDocument.
	* The imported groups/sites will be placed in a @ref Group called "Imported Bookmarks".
	*/
	virtual void importDomDocument( QString domDocument );
	/** */
//	virtual void showSystemTrayIcon(bool);
	/** */
	virtual void setPlugInKonq(bool);

	/** */
	bool addSite( SiteInfo& site );
	/** */
	bool addGroup( Group& group );
	/** */
	QDomDocument& domDocument() { return m_siteDataBase;  }
	/** */
	void save();
	/** */
	QValueList<QCString>& referers() { return m_referers; }
private:
	QDomElement findParent( const QString& parentStr );
	void parseImportTree( QDomElement parentElement, QDomElement dbParentElement );
	void addSite( QDomElement parent, SiteInfo& site );
	void addGroup( QDomElement parent, Group& group );
	void save( QDomDocument doc, const QString& fileName );
	QString getFullPath( QDomElement );
	void makeValidDomTree();
private:
	QDomDocument m_siteDataBase;
	QString m_siteManagerFile, m_oldSiteManagerFile;
	QString m_encoding;
	QValueList<QCString> m_referers;
	SiteManagerDBSignaler* m_private;
//	KSystemTray* m_dockWindow;

};
///////////////////////////////////////////////////////////////////////
// class SiteManagerDBSignaler
//////////////////////////////////////////////////////////////////////
    /**
     * @internal
     * class to stop daemon when no more registered users
     **/
class SiteManagerDBSignaler : public QObject {
	Q_OBJECT
public:
	SiteManagerDBSignaler( SiteManagerDB* db )
		: m_timer( this ), m_DB( db ), m_gotPing( true )
	{
	}	
	QTimer* timer() { return &m_timer; }
	QTimer m_timer;
	SiteManagerDB* m_DB;
	bool m_gotPing;
public slots:
	void slotTimeout() {
/*
		QValueList<QCString>::Iterator it = m_DB->referers().begin();
		for( ; ! m_DB->referers().isEmpty() && it != m_DB->referers().end(); ++it ) {
			if( (*it).isEmpty() || (*it).isNull() || ! kapp->dcopClient()->isApplicationRegistered( *it ) ) {
				m_DB->unregReferer( *it );
			}
		}
		if( m_DB->referers().isEmpty() )
			kapp->quit();
*/
		if( ! m_gotPing )
			kapp->quit();
		m_gotPing = false;
	}
};

#endif
