program Core;

{{$APPTYPE CONSOLE}

uses
  ShareMem,
  Windows,
  Messages,
  SysUtils,
  uPlugins in 'uPlugins.pas',
  uCore in 'uCore.pas';

var
  x: integer;
  Finished: boolean;
  SleepTime: integer = 100;
  F: TextFile;

procedure Finish; stdcall;
begin
  Finished:=true;
end;

procedure SetSleep(Params: array of variant); stdcall;
begin
  SleepTime:=params[0];
end;

procedure WriteError(Msg: string);
begin
  Writeln(f, '['+DateToStr(Date)+' '+TimeToStr(Time)+']: Error! '+msg);
end;

function Execute(Params: array of variant): variant; stdcall;
var
  s: TextFile;
  ln, comm: string;
  P: array of variant;
begin
  AssignFile(S, Params[0]);
  Reset(s);
  while not EOF(s) do
  begin
    Readln(s, ln);
    SetLength(P, 0);
    Comm:='';
    while length(ln)>0 do
    begin
      if ord(ln[1])>32 then
      begin
        if length(P)=0 then comm:=comm+ln[1] else P[length(P)-1]:=P[length(P)-1]+ln[1]
      end
      else
        SetLength(P, length(P)+1);
      ln:=copy(ln, 2, length(ln)-1);
    end;
    call(comm, P);
  end;
  Closefile(s);
end;

function logwrite(Params: array of variant): variant; stdcall;
var
  x: integer;
begin
  for x := 0 to length(Params) - 1 do
    Writeln(f, '['+DateToStr(Date)+' '+TimeToStr(Time)+']: '+Params[x]);
end;

function getlasterrorfunc(Params: array of variant): variant; stdcall;
begin
  Result:=LastError;
  LastError:='';
end;

var Msg: TMsg;

begin
  SetCurrentDir(ExtractFileDir(ParamStr(0)));

  AssignFile(F, 'LOG.TXT');
//  if not FileExists('LOG.TXT') then
    Rewrite(f);
//  else
//    Append(f);
  writeln(f, #13#10'============================================');
  writeln(f, 'Engine launched '+DateToStr(Date)+' '+TimeToStr(Time));
  writeln(f, '--------------------------------------------');


  Finished:=false;
  OnError:=WriteError;
  AddFunction('shutdown',@Finish);
  AddFunction('log',@logwrite);
  AddFunction('getlasterror',@getlasterrorfunc);
  AddFunction('execute',@Execute);

  writeln(f, 'Core initialization...');
  if not InitCore then
  begin
    writeln(f, 'Core initialization failed!');
    Closefile(f);
    halt;
  end;
  writeln(f, #13#10'--------------------------------------------');
  writeln(f, 'Plugins loaded');
  writeln(f, '--------------------------------------------');
  for x := 0 to length(Funcs) - 1 do writeln(f, Libs[Funcs[x].Lib].Name+': '+Funcs[x].Name);
  for x := 0 to length(Libs) - 1 do if @Libs[x].MainProc<>nil then Libs[x].MainProc(onInit);

  writeln(f, #13#10'--------------------------------------------');
  writeln(f, 'Starting main loop');
  writeln(f, '--------------------------------------------');
  while not Finished do
    if (PeekMessage(msg, 0, 0, 0, PM_REMOVE)) then // Check if there is a message
    begin
      if (msg.message = WM_QUIT) then finished := True
      else
      begin                               // Else translate and dispatch the message
        TranslateMessage(msg);
        DispatchMessage(msg);
        for x := 0 to length(Libs) - 1 do if @Libs[x].MainProc<>nil then Libs[x].MainProc(onProgress);
      end;
    end else sleep(SleepTime);

  for x := length(Libs) - 1 downto 0 do if @Libs[x].MainProc<>nil then Libs[x].MainProc(onDeInit);
  for x := length(Libs) - 1 downto 0 do FreeLibrary(Libs[x].Lib);

  writeln(f, #13#10'--------------------------------------------');
  writeln(f, 'Engine stoped '+DateToStr(Date)+' '+TimeToStr(Time));
  writeln(f, '============================================');
  CloseFile(F);

  //NoErrMsg := True;
end.
