/*
 * Copyright 2001-2015 Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 */
#ifndef _APPLICATION_H
#define _APPLICATION_H


#include <AppDefs.h>
#include <InterfaceDefs.h>
#include <Looper.h>
#include <Messenger.h>
#include <Point.h>
#include <Rect.h>


#if defined( HoG_GENODE )

// libbe.so
#include <support/Locker.h>  // member

// genode/base.lib.a
#include <base/mutex.h>  // member

namespace Genode {
	class Env;
}
namespace hog {
//+	class FontStash;
//+	class MouseAndKeyboard;
}

/*
	_del_ (BScreen now has its own nitpicker connection)
class hog::VideoMode
{
public:
		VideoMode();
		
		void SetMode( BSize area );
		BSize area() const;

private:  // Data
	mutable Genode::Mutex rwMutex;
		BSize modeArea;

private:  // Disabled
		VideoMode( const VideoMode & peer );
		VideoMode & operator=( const VideoMode & );
};
*/

class FontStash
{
public: ///
		struct opaque_painter;  // hide the 'Text_painter::Font' implementation, from the (many) users of the Application.h header

public:
		FontStash();
		
//		const Text_painter::Font & Font( int font_id ) const;
		opaque_painter  Font( int font_id ) const;
			///ToDo-2: CanvasWindow ought to retrieve a copy once at creation, so that all further calls to canvas.DrawString() work without locking or speed or concurrency issues
		float FontHeight( int font_id ) const;

private:  // Disabled
		FontStash( const FontStash & peer );
		FontStash & operator=( const FontStash & );
};


class MouseAndKeyboard
{
	// Written by <inputBridger>, read by BView.GetMouse()
	
public:

		MouseAndKeyboard();
		
		// keyboard
		
		int32 KbdModifiers() const;
		void Set_KbdModifiers( int32 modifiers );
		
		// mouse
		
		BPoint PointDevice_ScreenCoords() const;
		uint32 PointDevice_Buttons() const;
		
		void Set_MouseScreenCoords( BPoint screen );
		void Set_MouseButtons( uint32 buttons );


private:  // Data

	mutable Genode::Mutex rwMutex;
		int32  kbdModifiers;
		BPoint mouseScreenCoords;
		uint32 mouseButtons;
		
private:  // Disabled
		MouseAndKeyboard( const MouseAndKeyboard & peer );
		MouseAndKeyboard & operator=( const MouseAndKeyboard & );
};

#endif  // ~HoG_GENODE


class BCursor;
class BList;
class BLocker;
class BMessageRunner;
class BResources;
class BServer;
class BWindow;

struct app_info;


namespace BPrivate {
	class PortLink;
	class ServerMemoryAllocator;
}


class BApplication : public BLooper {
public:
								BApplication(const char* signature);
								BApplication(const char* signature,
									status_t* error);

	virtual						~BApplication();

#if defined( HoG_GENODE )
					Genode::Env & Env();
					
					const FontStash & GenoFonts() const;
					MouseAndKeyboard & MouseKbd();
#endif


#ifndef HoG_GENODE
	// Archiving
								BApplication(BMessage* data);
	static	BArchivable*		Instantiate(BMessage* data);
	virtual	status_t			Archive(BMessage* data, bool deep = true) const;
#endif  // ~HoG_GENODE

			status_t			InitCheck() const;

	// App control and System Message handling
	virtual	thread_id			Run();
	virtual	void				Quit();
	virtual bool				QuitRequested();
	virtual	void				Pulse();
	virtual	void				ReadyToRun();
	virtual	void				MessageReceived(BMessage* message);
	virtual	void				ArgvReceived(int32 argc, char** argv);
	virtual	void				AppActivated(bool active);
	virtual	void				RefsReceived(BMessage* message);
	virtual	void				AboutRequested();

#ifndef HoG_GENODE
	// Scripting
	virtual BHandler*			ResolveSpecifier(BMessage* message, int32 index,
									BMessage* specifier, int32 form,
									const char* property);
#endif

	// Cursor control, window/looper list, and app info
			void				ShowCursor();
			void				HideCursor();
			void				ObscureCursor();
#ifndef HoG_GENODE
			bool				IsCursorHidden() const;
			void				SetCursor(const void* cursor);
			void				SetCursor(const BCursor* cursor,
									bool sync = true);
#endif

			int32				CountWindows() const;
			BWindow*			WindowAt(int32 index) const;

#ifndef HoG_GENODE
			int32				CountLoopers() const;
			BLooper*			LooperAt(int32 index) const;
#endif
			bool				IsLaunching() const;
			const char*			Signature() const;
			status_t			GetAppInfo(app_info* info) const;
	static	BResources*			AppResources();

	virtual	void				DispatchMessage(BMessage* message,
									BHandler* handler);
			void				SetPulseRate(bigtime_t rate);

	// Register a BLooper to be quit before the BApplication
	// object is destroyed.
			status_t			RegisterLooper(BLooper* looper);
			status_t			UnregisterLooper(BLooper* looper);

	// More scripting
#ifndef HoG_GENODE
	virtual status_t			GetSupportedSuites(BMessage* data);
#endif


	// Private or reserved
	virtual status_t			Perform(perform_code d, void* arg);

	class Private;

private:
	typedef BLooper _inherited;

	friend class Private;
	friend class BServer;

								BApplication(const char* signature,
									const char* looperName, port_id port,
									bool initGUI, status_t* error);
								BApplication(uint32 signature);
								BApplication(const BApplication&);
			BApplication&		operator=(const BApplication&);

	virtual	void				_ReservedApplication1();
	virtual	void				_ReservedApplication2();
	virtual	void				_ReservedApplication3();
	virtual	void				_ReservedApplication4();
	virtual	void				_ReservedApplication5();
	virtual	void				_ReservedApplication6();
	virtual	void				_ReservedApplication7();
	virtual	void				_ReservedApplication8();

#ifndef HoG_GENODE
	virtual	bool				ScriptReceived(BMessage* msg, int32 index,
									BMessage* specifier, int32 form,
									const char* property);
#endif
			void				_InitData(const char* signature, bool initGUI,
									status_t* error);
			port_id				_GetPort(const char* signature);
#ifndef HoG_GENODE
			void				BeginRectTracking(BRect r, bool trackWhole);
			void				EndRectTracking();
			status_t			_SetupServerAllocator();
#endif
			status_t			_InitGUIContext();
#ifndef HoG_GENODE
			status_t			_ConnectToServer();
			void				_ReconnectToServer();
#endif
			bool				_QuitAllWindows(bool force);
			bool				_WindowQuitLoop(bool quitFilePanels,
									bool force);
			void				_ArgvReceived(BMessage* message);

			uint32				InitialWorkspace();
			int32				_CountWindows(bool includeMenus) const;
			BWindow*			_WindowAt(uint32 index,
									bool includeMenus) const;

	static	void				_InitAppResources();

private:
	static	BResources*			sAppResources;

			const char*			fAppName;  //++ "fAppSignature"..
#ifndef HoG_GENODE
			::BPrivate::PortLink*	fServerLink;
			::BPrivate::ServerMemoryAllocator* fServerAllocator;

#else  // HoG_GENODE

			FontStash fontStash;
			MouseAndKeyboard inputDevicesState;
#endif  // ~HoG_GENODE

#ifndef HoG_GENODE
			void*				fCursorData;
#endif  // ~HoG_GENODE
			bigtime_t			fPulseRate;
			uint32				fInitialWorkspace;
			BMessageRunner*		fPulseRunner;
			status_t			fInitError;
#ifndef HoG_GENODE
			void*				fServerReadOnlyMemory;
			uint32				_reserved[12];
#endif

			bool				fReadyToRunCalled;
};


// Global Objects

extern BApplication* be_app;
extern BMessenger be_app_messenger;


#endif	// _APPLICATION_H
