/***************************************************************************/
/**@file CamView.cpp
 * Description: Main initialisation for Camera Viewer app.      	   *  
 * Dependency:  WxWindows												   *
 ***************************************************************************/

/** Uses splash screen as the application is started if value is equal to 1 */
#define USE_SPLASH_SCREEN 1

#include "wx/wxprec.h"
#ifndef WX_PRECOMP
  #include "wx/wx.h" // For compilers that supports precompilation , includes "wx/wx.h"
#endif

#include "CamView.h"
#include "MainFrame.h"
#include "RT_EXEC.h"
#include "../library/hardware/OsSupp.h"
#include "../library/AboutDialog.h"

#include <userenv.h>


const char LOCALE_NAME[] = "CamView";


bool IniFileEmpty;


/** Count amount of cameras installed on your system. */
int CameraCount(void)
{
BazeCameraDriver *CamFactory;
int CamCount=0;
int idx;

  CamFactory = BazeCameraDriver::GetFirst();
  while(CamFactory)  
    {
    idx=0;
    while(CamFactory->GetDriver(idx++))
	CamCount++;

    CamFactory = CamFactory->GetNext();
    }
  return(CamCount);  
}


/** Emit error if next exgument exceeds argument list. */
int CheckArg(int & p, int argc, const char * const *arg)
{
  if(++p>=argc)
  {
    return 0;  
  }
  if(arg[p]==NULL) return 0;
return 1;  
}




/** Initalisation code. */
bool CAMVIEWApp::OnInit()
{   
bool splash=true;
bool ShowHelp=false;
const char *LocaleShort = NULL;

  InitOsDependent();

    // application and vendor name are used by wxConfig to construct the name
    // of the config file/registry key and must be set before the first call
    // to Get() if you want to override the default values (the application
    // name is the name of the executable and the vendor name is the same)
    
  SetVendorName(_T("F&TSOFT"));
  SetAppName(_T("CameView"));		// not needed, it's the default value

  for(int i=1; i<argc; i++)
  {
    if(!strcmp(argv[i],"/nosplash") || !strcmp(argv[i],"-nosplash"))
    {
      splash=false;
      continue;
    }
    if(!strcmp(argv[i],"/L") || !strcmp(argv[i],"-L"))
    {
      if(CheckArg(i,argc,argv))
      {
	LocaleShort = argv[i];
      }
      continue;
    }
    if(!strcmp(argv[i],"/help") || !strcmp(argv[i],"-help"))
    {
      ShowHelp = true;
      continue;
    }
  }

  if(ShowHelp)
  {
    wxMessageBox(_("Command line arguments:\n"
		   "    /help      Show this help\n"
                   "    /L lang    Set localisation language (e.g. CZ or EN)\n"                   
                   "    /nosplash  Do not display splash screen\n"
                   ), "CamView", wxOK|wxICON_INFORMATION);
  }

  wxString globalCongDir;
  {
    LPSTR pProfileDir = (LPSTR)calloc(2048,sizeof(CHAR));
    if(pProfileDir)
    {
      DWORD lpcchSize = 2048;
      HANDLE processToken = ::GetCurrentProcess();
      HANDLE user;
      if(::OpenProcessToken(processToken, TOKEN_ALL_ACCESS, &user))
      {
        GetUserProfileDirectoryA(user,pProfileDir,&lpcchSize);
        if(lpcchSize > 0)
        {
          globalCongDir = pProfileDir;
          if(pProfileDir[lpcchSize-1]!='\\' && pProfileDir[lpcchSize-1]!='/')
            globalCongDir += "\\";
          globalCongDir += "camera.ini";
        }
        CloseHandle(user);
      }
      CloseHandle(processToken);
      free(pProfileDir);
    }
  }

	// initialise a configuration file
  wxFileConfig *pConfig = new wxFileConfig(GetAppName(), GetVendorName(), _T("camera.ini"),  // _T("./config.cfg"), 
                                           globalCongDir,
                                          (globalCongDir.length()>0) ? wxCONFIG_USE_GLOBAL_FILE : wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_RELATIVE_PATH);
  wxConfigBase::Set(pConfig);
  IniFileEmpty = !pConfig->HasGroup("/HwSetting") && 
		   !pConfig->HasGroup("/MainFrame") 
		   /* && !pConfig->HasGroup(DEFAULT_PID_GROUP)*/ ;

  if(LocaleShort==NULL) LocaleShort=GetLang();
  if(LocaleShort!=NULL)
  {
    if(!stricmp(LocaleShort,"CS"))
        m_locale.Init("czech", "locale\\CS\\lc_messages", "czech");
    else
	LocaleShort = NULL;

   if(LocaleShort!=NULL)
       m_locale.AddCatalog(LOCALE_NAME);
  }

#ifdef POINTER_SIZE
  if(POINTER_SIZE/8 != sizeof(void*))
  {
    wxMessageBox(_("Program is wrongly compilled, predefined POINTER_SIZE mismatch!"), "CamView", wxOK|wxICON_ERROR, NULL);
    return false;
  }
#endif
    
  MRT.Hook2Drv((CameraCount()<=1) ? (CamRtExec::SEL_CAM|CamRtExec::SEL_INIT) : (CamRtExec::SEL_CAM|CamRtExec::SEL_CAM2|CamRtExec::SEL_INIT));

    // where you can also specify the file names explicitly if you wish.
    // Of course, calling Set() is optional and you only must do it if
    // you want to later retrieve this pointer with Get().
    
    // Create the main application window     
  CamViewMainFrame *frame = new CamViewMainFrame(wxString::Format(_("Camera viewer app %u"),(unsigned)(sizeof(void*)*8)), wxPoint(-1,-1), wxSize(600,500));

#if USE_SPLASH_SCREEN    // Shows Splash screen
    if(splash)
      {
      AboutFrame *frm = new AboutFrame(frame,"ballshow.bmp",_("About Camera Viewer"));

      frm->SetText(AboutText);
      frm->Show();
      frm->Refresh(); 

      Yield();
      }
#endif    
    
    // Show it and tell the application that it's our main window
  frame->Show(true);
  SetTopWindow(frame);
    
  return true;
}


/** Exit application. */
int CAMVIEWApp::OnExit()
{
BazeCameraDriver *CamFactory;
    // clean up: Set() returns the active config object as Get() does, but unlike
    // Get() it doesn't try to create one if there is none (definitely not what we want here!)    
    wxLog::EnableLogging(false);	//do not display warnings on RO filesytem on flush
    delete wxConfigBase::Set((wxConfigBase *) NULL);
    //wxConfigBase::DeleteAll();
    wxLog::EnableLogging(true);

    MRT.DismantleDrivers();
			   //prevent camera usage from this point        

	// Erase all camera related COM objects
    CamFactory=BazeCameraDriver::GetFirst();
    while(CamFactory!=NULL)
      {      
      CamFactory->GetDriver(BazeCameraDriver::ERASE_ALL);              
      CamFactory=CamFactory->GetNext();
      }    

    DoneOsDependent();
    return 0;
}


/**  Create a new application object: this macro will allow wxWidgets to create
*  the application object during program execution (it's better than using a
*  static object for many reasons) and also declares the accessor function
*  wxGetApp() which will return the reference of the right type (i.e. MyApp and
*  not wxApp) */
IMPLEMENT_APP(CAMVIEWApp)

