unit Frost.Engine;

interface

uses
  _Geometry,
  Frost.GL,
  Frost.Forms,  
  Frost.Font,
  Frost.Scenes,
  Frost.RenderEngine,  
  Frost.Renderers,   
  Frost.Resources,
  Frost.GameObjects;

type

TTime = class
  private
    FDelta: Single;
  public
    property Delta: Single read FDelta;
  end;

TResources    = Frost.Resources.TResources; 
TControl      = Frost.Forms.TControl;
TScreen       = Frost.Forms.TScreen;
TScene        = Frost.Scenes.TScene;
TGameObject   = Frost.GameObjects.TGameObject;
TComponent    = Frost.GameObjects.TComponent;
TCamera       = Frost.RenderEngine.TCamera;
TMeshRenderer = Frost.Renderers.TMeshRenderer;
TMesh         = Frost.Renderers.TMesh; 
TTextAlign    = Frost.Font.TTextAlign;

TCameraClearMode = Frost.RenderEngine.TCameraClearMode;
const None       = Frost.RenderEngine.TCameraClearMode(0);
const ClearAll   = Frost.RenderEngine.TCameraClearMode(1);
const ClearDepth = Frost.RenderEngine.TCameraClearMode(2);
const ClearColor = Frost.RenderEngine.TCameraClearMode(3);

type
TApplication = class
  private
    class var FInstance: TApplication;
  private
    FCurrentScene: TScene;
    FWindow: TWindow;                 
    constructor Create();
  public
    property CurrentScene: TScene read FCurrentScene;
    class procedure Init(ApplicationTitle: PAnsiChar; Width: Integer = 0; Height: Integer = 0);
    class procedure Start(CurrentScene: TScene);
    procedure Close;
  end;

var              
  Application: TApplication;
  Resources: TResources;
  Control: TControl;
  Screen:  TScreen;    
  Window:  TWindow;  

implementation

{$REGION '  Application  '}
procedure CreateApplication;
begin
  GL := TOpenGL.Create(Application.FWindow.Handle, Application.FWindow.Width, Application.FWindow.Height);        
  Control := Application.FWindow.Control;
  Screen  := Application.FWindow.Screen;
  Application.CurrentScene.Awake;
end;

procedure CloseApplication;
begin
  if (Application.CurrentScene <> nil) then
    Application.CurrentScene.OnDestroy;
end;

procedure ChangeState;
begin
  GL.Resize(Window.Width, Window.Height);
end;

procedure OnTimer(Delta: double);
begin
  Application.FCurrentScene.OnSceneUpdate(Delta / 10);
end;
 
constructor TApplication.Create();
begin
  TApplication.FInstance := self;
end;

class procedure TApplication.Init(ApplicationTitle: PAnsiChar; Width: Integer = 0; Height: Integer = 0);
begin
  if (TApplication.FInstance = nil) then
    begin
      Application := TApplication.Create();
      if (Width <> 0) and (Height <> 0) then
      begin
        Window:= TWindow.Create(PAnsiChar(ApplicationTitle),
          @CreateApplication, @CloseApplication, @ChangeState, @OnTimer,
          Width, Height, True);
      end else
      begin
        Window:= TWindow.Create(PAnsiChar(ApplicationTitle),
          @CreateApplication, @CloseApplication, @ChangeState, @OnTimer, True);
      end;
      Application.FWindow := Window;
    end;
end;

class procedure TApplication.Start(CurrentScene: TScene);
begin               
  Application.FCurrentScene:= CurrentScene;
  Application.FWindow.Initialize;
end;

procedure TApplication.Close;
begin
  FWindow.Close;
end;
{$ENDREGION}

end.
