// Description   : Client application entry-point for the NANO OS Core $Revision: 29 $

// Copyright     : Proxima Centauri Romania SRL, ALL RIGHTS RESERVED. (http://www.ProximaCentauri.org)

// Author        : Alexander Ioan Mihail

 

#include "ring1.h"

#include <stdlib.h>

 

using namespace NANO_CORE;

using namespace NANO_RING1;

 

void CreateApplication(int argc, char**argv,void**app);

void RunApplication(void*application);

void CloseApplication(void*application);

void AppCreateWindow(void*app,ELEMENT*cat,ELEMENT*node);

bool AppCreatesWindow();

 

int _argc;

char**_argv;

 

#pragma optimize( "", off )

void do_main(int argc,char*argv[],void**arg_app)

{

  STACK_FRAME

  ENTER

  _argc=argc;

  _argv=argv;

  void**local_app=arg_app;

  CAT_RING1*cat=CAT_RING1::KernelInit();

  ELEMENT*e=cat->Find(eqCDPL,(1<<ELEMENT::PARTIAL));

  bool admin;

  if (_argc>1&&!strcmp(_argv[1],"admin"))

    admin=true;

  else

    admin=true// set to false for production systems to hide the details of the core.

  ELEMENT*home=admin?cat:nullptr;

  ELEMENT*th_main=ELEMENT::INIT(nullptr,nullptr,"TH.INIT",home,&cat->CAT_CORE::Types[CAT_CORE::em_THREAD],nullptr,0);

  ELEMENT*th_child;

  if (!(th_child=th_main->Fork("TH.APP")))

  {

    if (AppCreatesWindow())

    {

      CreateApplication(_argc,_argv,local_app);

      RunApplication(local_app);

      CloseApplication(*local_app);

      *local_app=nullptr;

    }

    delete ELEMENT::GetThread();

  }

  if (!(th_child=th_main->Fork("TH.BROWSER")))

  {

    if (!AppCreatesWindow())

      CreateApplication(_argc,_argv,local_app);

    while (!*local_app)

      OurSleep(1000);

    ELEMENT*node=cat; //admin?cat:cat->GetActor();

    AppCreateWindow(*local_app,cat,node);

    if (!AppCreatesWindow())

    {

      CloseApplication(*local_app);

      *local_app=nullptr;

    }

    delete ELEMENT::GetThread();

  }

  do

  {

    static int phase=0;

    TRACE((ETraceFlags::NORMAL,0,"."));

    cat->Evaluate(phase++,0);

    OurSleep(atoi(e->Name+sizeof(eqCDPL)-1));

  }

  while (*local_app);

  delete th_main;

  CAT_RING1::KernelDone(cat);

  EXIT

}

void main(int argc,char*argv[])

{

  void*local_app=nullptr;

  do_main(argc,argv,&local_app);

}

#pragma optimize( "", on )

#ifndef USE_QT

extern "C" int __stdcall GetModuleFileNameA(void*handle,char*buf,int sz);

int WinMain(void* instance, void* prev_instance, char* command_line, int show_command)

{

  char** argv;   

  int    index;

  int    result;

  int    argc = 1;

  char*  arg = command_line;

  while (arg[0])

  {

    while (arg[0] && arg[0] == ' ')

      arg++;

    if (arg[0])

    {

      argc++;

      while (arg[0] && arg[0] != ' ')

        arg++;

    }

  }   

  argv = (char**)alloca(argc * sizeof(char*));   

  arg = command_line;

  index = 1;   

  while (arg[0])

  {       

    while (arg[0] && arg[0] == ' ')

      arg++;

    if (arg[0])

    {

      argv[index] = arg;

      index++;

      while (arg[0] && arg[0] != ' ')

        arg++;

      if (arg[0])

        *arg++ = 0;   

    }

  }

  char filename[_MAX_PATH];

  GetModuleFileNameA(NULL, filename, _MAX_PATH);

  argv[0] = filename;

  result = main(argc, argv);

  return result;

}

#endif