//**************************************************************************************************
//
// LIBRARY RUNTIME PARAMETERS AND INITIALIZATION:
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// RuntimeForStatic base library | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#pragma once
#include "include_restrictions.h"
namespace RuntimeForStatic {

//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// SATELLITE STRUCTURES FOR RUNTIME PARAMETERS (GLOBAL VALUES):
//
//==================================================================================================
struct $ModuleParametersRT {
   PCWSTR Name $required;
   PCWSTR MainModuleName $optional;
}; // $ModuleParametersRT
typedef $ModuleParametersRT*        $PModuleParametersRT;
typedef const $ModuleParametersRT*  $PCModuleParametersRT;
//==================================================================================================
struct $ExitCodesRT {
   static const int
      SuccessfulDefault =  0, // $SUCCESSFUL_EXIT_CODE
      FailureDefault    =  1, // $FAILURE_EXIT_CODE
      BreakdownDefault  = -1; // $BREAKDOWN_EXIT_CODE
   int Successful $optional;
   int Failure    $optional_through( 0 )
                  $default_value( FailureDefault );
   int Breakdown  $optional_through( 0 )
                  $default_value( BreakdownDefault );
}; // $ExitCodesRT
typedef $ExitCodesRT*         $PExitCodesRT;
typedef const $ExitCodesRT*   $PCExitCodesRT;
//==================================================================================================
struct $FatalErrorSettingsRT
{
   $ActionRoutine
      RaiseTrigger            $optional;
   $EmergencyCallback
      EmergencyHandler        $optional,
      EmergencyFinalHandler   $optional;
}; // $FatalErrorSettingsRT
typedef $FatalErrorSettingsRT*         $PFatalErrorSettingsRT;
typedef const $FatalErrorSettingsRT*   $PCFatalErrorSettingsRT;
//==================================================================================================


//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// "$RuntimeParameters" AGGREGATIVE STRUCTURE (GLOBAL VALUES):
//
//==================================================================================================
struct $RuntimeParameters
{
   DWORD                   MainThreadId               $auto $optional_through(0);
   DWORD                   InitializerThreadId        $auto;
   bool                    AllowDesktopInteraction;
   bool                    IsNativeThreadStartForbiddenVCRT;
   $ModuleParametersRT     ModuleParameters;
   $ExitCodesRT            ExitCodes;
   $ThreadSettings         ThreadSettingsPattern;
   $FatalErrorSettingsRT   FatalErrorSettings;
   void Reset();
   void Reset(PCSTR crtLocaleString_ALL $optional);
   void Prepare($A,PCWSTR moduleName);
   void Prepare($A,PCWSTR moduleName, PCSTR crtLocaleString_ALL $optional );
   void Prepare($A,PCWSTR moduleName, bool allowDesktopInteraction );
   void Prepare($A,PCWSTR moduleName, PCSTR crtLocaleString_ALL $optional,
                                      bool allowDesktopInteraction );
}; // $RuntimeParameters
typedef $RuntimeParameters*         $PRuntimeParameters;
typedef const $RuntimeParameters*   $PCRuntimeParameters;
//==================================================================================================


//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// "$RT" STATIC CLASS — RUNTIME INITIALIZATION AND PARAMETERS:
//
//==================================================================================================
class $RT
{
$STATIC_CLASS( $RT )
public:
   static bool IsInitialized();
   static bool WasInitialized();
   static bool WasInitializationAttempt();
   static void VerifyInitialized($O) $requires_rt_init;
   static bool Initialize($OA, const $RuntimeParameters& runtimeParameters,
                               $DynText& errorMessage $out );
   static void Finalize() $not_requires_rt_init;
public:
   static PCWSTR ModuleName($O) $strict_result $requires_rt_init;
   static PCWSTR GetModuleName() $or_null;
   static PCWSTR GetMainModuleName() $or_null;
   static DWORD MainThreadId($O) $strict_result $requires_rt_init;
   static DWORD GetMainThreadId() $or_zero;
   static DWORD InitializerThreadId($O) $strict_result $requires_rt_init;
   static DWORD GetInitializerThreadId() $or_zero;
   static bool AllowDesktopInteractionValue($O) $strict_result $requires_rt_init;
   static bool GetAllowDesktopInteraction() $or_false;
   static bool GetAllowDesktopInteraction(bool defaultValue);
   static bool IsNativeThreadStartForbiddenVCRT($O) $strict_result $requires_rt_init;
   static bool GetNativeThreadStartForbiddenVCRT() $or_false;
public:
   static int SuccessfulExitCode($O)   $strict_result $requires_rt_init;
   static int GetSuccessfulExitCode()  $default_value( 0 );
   static int FailureExitCode($O)      $strict_result $requires_rt_init;
   static int GetFailureExitCode()     $default_value( 1 );
   static int BreakdownExitCode($O)    $strict_result $requires_rt_init;
   static int GetBreakdownExitCode()   $default_value( -1 );
public:
   static const $ModuleParametersRT&   ModuleParameters($O)       $requires_rt_init;
   static $PCModuleParametersRT        GetModuleParameters()      $or_null;
   static const $ExitCodesRT&          ExitCodes($O)              $requires_rt_init;
   static $PCExitCodesRT               GetExitCodes()             $or_null;
   static const $ThreadSettings&       ThreadSettingsPattern($O)  $requires_rt_init;
   static $PCThreadSettings            GetThreadSettingsPattern() $or_null;
   static const $FatalErrorSettingsRT& FatalErrorSettings($O)     $requires_rt_init;
   static $PCFatalErrorSettingsRT      GetFatalErrorSettings()    $or_null;
public:
   static bool IsInInitializerThread();
   static void SpecifyMainThreadId($O,DWORD value) $requires_rt_init;
public:
   static PCWSTR GetDefaultModuleName() $or_null;
   static void SpecifyDefaultModuleName(PCWSTR name $optional);
private:
#include "..\private\RT.private.h"
}; // $RT
//==================================================================================================

} // RuntimeForStatic
