/* GMM (C) 2018 Stephane Charette <stephanecharette@gmail.com>
 * $Id: GMMApp.hpp 2643 2018-10-20 16:54:16Z stephane $
 */

#pragma once

#include "GMM.hpp"


class GMMApplication : public JUCEApplication
{
	public:

		enum class EJob
		{
			kInvalid					,
			kInitializeAndLoad			,
			kShowFirstWindow			,
			kShowAboutWindow			,
			kShowMainWindow				,
			kShutdown					,
			kNoOp
		};

		GMMApplication						(void);
		virtual ~GMMApplication				(void);

		const String getApplicationName		(void) override	{ return "Gorman Moisture Meter";	}
		const String getApplicationVersion	(void) override	{ return GMM_VERSION;				}
		bool moreThanOneInstanceAllowed		(void) override	{ return false;						}
		void systemRequestedQuit			(void) override { quit();							}

		void initialise(const String& commandLine) override;

		void shutdown() override;

		void anotherInstanceStarted (const String& commandLine) override;

		void unhandledException(const std::exception *e, const String &sourceFilename, int lineNumber) override;

		void run( const EJob job );

		void job_initialize_and_load(void);
		void job_show_about_window(void);

		TooltipWindow						tool_tip;

		std::unique_ptr<LookAndFeel_V4>		laf;
		std::unique_ptr<Cfg>				cfg;
		std::unique_ptr<GMMWnd>				wnd;

		VStr errors;

		/// Prefixes to all the known devices stored in configuration.
		VStr prefixes;
};


/** Return a reference to the single running application.  Will throw if the
 * app somehow does not exist, such as early in the startup process, or late
 * in the shutdown sequence.
 */
inline GMMApplication &gmm(void)
{
	GMMApplication *app = dynamic_cast<GMMApplication*>(JUCEApplication::getInstance());
	if (app == nullptr)
	{
		throw Lox::Exception( LOX_WHERE, "failed to find an active application pointer" );
	}

	return *app;
}


inline GMMApplication &run(const GMMApplication::EJob job)
{
	GMMApplication &app( gmm() );

	app.run(job);

	return app;
}


/// Quick and easy access to configuration.  Will throw if the GMM application does not exist.
inline Cfg &cfg(void)
{
	return *gmm().cfg;
}


inline std::string to_string(const GMMApplication::EJob job)
{
	switch(job)
	{
		case GMMApplication::EJob::kInvalid:					return "invalid";
		case GMMApplication::EJob::kInitializeAndLoad:			return "initialize and load";
		case GMMApplication::EJob::kShowFirstWindow:			return "show first window";
		case GMMApplication::EJob::kShowAboutWindow:			return "about window";
		case GMMApplication::EJob::kShowMainWindow:				return "main window";
		case GMMApplication::EJob::kShutdown:					return "shutdown";
		case GMMApplication::EJob::kNoOp:						return "no-op";
	}

	return "?";
}
