//! \~\file pisingleapplication.h
//! \~\ingroup Application
//! \~\brief
//! \~english Single-instance application control
//! \~russian Контроль одного экземпляра приложения
/*
    PIP - Platform Independent Primitives
    Single application
    Ivan Pelipenko peri4ko@yandex.ru

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

    This program 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PISINGLEAPPLICATION_H
#define PISINGLEAPPLICATION_H

#include "pithread.h"

class PISharedMemory;

//! \~\ingroup Application
//! \~\brief
//! \~english Single-instance application control.
//! \~russian Контроль одного экземпляра приложения.
//! \~\details
//! \~english The PISingleApplication class provides single-instance application control. It allows detecting if the current application
//! instance is the first one launched and enables inter-process communication between multiple instances. Multiple instances with the same
//! "app_name" can detect each other and communicate. The first instance becomes the server, receiving messages from subsequent instances.
//! \~russian Класс PISingleApplication предоставляет контроль одного экземпляра приложения. Он позволяет определить, является ли текущий
//! экземпляр первым запущенным, и обеспечивает межпроцессное взаимодействие между несколькими экземплярами. Несколько экземпляров с
//! одинаковым "app_name" могут обнаруживать друг друга и обмениваться сообщениями. Первый экземпляр становится сервером, принимающим
//! сообщения от последующих экземпляров.

class PIP_EXPORT PISingleApplication: public PIThread {
	PIOBJECT_SUBCLASS(PISingleApplication, PIThread);

public:
	//! \~english Constructs %PISingleApplication for application name "app_name".
	//! \~russian Создает %PISingleApplication для имени приложения "app_name".
	PISingleApplication(const PIString & app_name = PIString());

	//! \~english Stops instance monitoring and releases shared resources.
	//! \~russian Останавливает мониторинг экземпляра и освобождает общие ресурсы.
	~PISingleApplication();


	//! \~english Returns whether this process is the first launched instance.
	//! \~russian Возвращает, является ли этот процесс первым запущенным экземпляром.
	bool isFirst() const;

	//! \handlers
	//! \{

	//! \fn void sendMessage(const PIByteArray & m)
	//! \brief
	//! \~english Sends message "m" to the first launched application instance
	//! \~russian Посылает сообщение "m" первому запущенному экземпляру приложения
	EVENT_HANDLER1(void, sendMessage, const PIByteArray &, m);

	//! \}
	//! \events
	//! \{

	//! \fn void messageReceived(PIByteArray m)
	//! \brief
	//! \~english Emitted by the first launched application when receiving a message from another instance
	//! \~russian Вызывается первым запущенным приложением при получении сообщения от другого экземпляра
	EVENT1(messageReceived, PIByteArray, m);

	//! \}

private:
	void begin() override;
	void run() override;
	void waitFirst() const;

	PISharedMemory * shm;
	PITimeMeasurer ftm;
	PIByteArray readed;
	bool first, started;
	int sacnt;
};

#endif // PISINGLEAPPLICATION_H
