/* This file is part of the KDE libraries
    Copyright (C) 1999 Paul Campbell (paul@taniwha.com)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

// $Id: kapp.h,v 1.60 1998/12/06 08:56:10 garbanzo Exp $

#ifndef _KUAPP_H
#define _KUAPP_H

#include <kapp.h>
#include <qsocketnotifier.h>

//
//
//	KUniqueApplication
//	------------------
//
//	This is a derived class of KApplication - the only difference is that
//	no more than one KApplication of this type per user
//	may be running (type is defined by kapp->appName()).
//
//	It can be used two ways:
//
//	1) Simply replace the instantiation of your KApplication object
//	   with a definition of KUniqueApplication instead - in this case
//	   your program will quietly exit if an existing application
//	   is running - if one isn't running the creation of the
//	   object will return cleanly
//
//	2) the same as above but also pass in a 'unique code' - a string
//	   that is passed to the primary instance of the app (case 1 above
//	   acts as if you pass in a code value of "") - in this case a message is passed to
//	   the primary application instance telling it that another application
//	   tried to start up - the string value is passed as part
//	   of this message
//
//	Hooking the messages
//	--------------------
//
//	The KUniqueApplication class has a single public signal, if you
//	connect to it your slot will get called with the signal code
//	every time another application attempts to be created and 
//	your application is the primary instance
//	
//	 	void uniqueCalled(char *message);
//
//	codes
//	-----
//
//	The code values are up to you to define - however the following
//	are reccomended:
//
//	"" - null code - probably switches the application to the current
//	    screen and brings it to the fore
//
//	"--new" - 'new' create a new empty document and open it on the current screen
//	    
//	
//
//	Example
//	-------
//
//	Imagine a mail program - two usefull instances might be checking for
//	mail (triggered by clocking on KBiff in the dock which in turn executes
//	a 'mail --check' and 'mail --new' which opens the mail application and
//	pops up a new empty mail message ready to write - 'mail --new' might
//	be contained in a style-sheet .kdelnk one which when clocked on results
//	in a new message window being opened (now you can drag the new mail style-sheet
//	to the dock and have a 'create mail' button)
//
//	normally you might process the program args something like:
//
//	
//		for (i = 1; i <= argc; i++)
//		if (strcmp(argv[i], "--new") == 0) newflg = 1; else
//		if (strcmp(argv[i], "--check") == 0) chkflg = 1;
//			etc
//
//		app = new KApplication(argv, argv, "mail");
//
//		mail = new Mail();
//
//		if (newflg) mail->new();
//		if (chkflg) mail->chk();
//
//		mail->showbrowser();
//
//	'Uniquifying' the app and implementing passing 'new' and 'check' as messages would result in:
// 	
//
//		char *message = "";
//
//		for (i = 1; i <= argc; i++)
//		if (strcmp(argv[i], "--new") == 0) {
//			newflg = 1
//			message = argv[i];
//		} else
//		if (strcmp(argv[i], "--check") == 0)
//			chkflg = 1;
//			message = argv[i];
//		} else
//			etc
//
//		app = new KUniqueApplication(message, argv, argv, "mail");
//
//
//		mail = new Mail();
//
//		if (newflg) mail->new();
//		if (chkflg) mail->chk();
//
//		mail->showbrowser();
//
//		QObject::connect(app, SIGNAL(uniqueCalled(char *)), mail, SLOT(uniqueMessage(char *)));    
//
//	The only difference here being using the KUniqueApplication class, passing a code
//	indicating the flag to it, and connecting a slot to receive the message from other
//	applications
//
//	In the mail class you need to register a slot:
//
//		void mail::uniqueMessage(char *message)
//		{
//			if (strcmp(message, "") == 0) {
//				showbrowser();		// bring it to the front
//			} else
//			if (strcmp(message, "--new") == 0) {
//				new();			// create a new mail window
//			} else 
//			if (strcmp(message, "--check") == 0) {
//				chk();			// check for mail
//			}
//		} 
//

//

class KUniqueApplication : public KApplication
{
  Q_OBJECT
public:
  /** 
	* Constructor. Pass command-line arguments. 
	*
	* A KConfig object is
	* created that contains an application-specific config file whose
	* name is "~/." + argv[0] + "rc". This constructor should be considered
	* obsolete. The state of the application-specific config file may be
	* queried afterwards with getConfigState(). 
	*/
  KUniqueApplication( char *message, int& argc, char** argv );
  KUniqueApplication( int& argc, char** argv );

  /** 
	* Constructor. Pass command-line arguments. 
	*
	* A KConfig object is
	* created that contains an application-specific config file whose
	* name is "~/." + rAppName + "rc". The state of the application-specific 
	* config file may be queried afterwards with getConfigState(). 
	*/
  KUniqueApplication( char *message, int& argc, char** argv, const QString& rAppName );
  KUniqueApplication( int& argc, char** argv, const QString& rAppName );

  /** 
	* Destructor 
	*/
  virtual ~KUniqueApplication();

signals:
  	void uniqueCalled(char *message);
private:
	void uniqueCheck(char *message);
	QSocketNotifier *mynotifier;
	int	fd;	// socket fd
	QString lock;
private slots:
	void slotRead( int );        
};

#endif
