/***********************************************************************
**
**   main.cpp
**
**   This file is part of Cumulus.
**
************************************************************************
**
**   Copyright (c):  2001 by Heiner Lamprecht
**
**   This file is distributed under the terms of the General Public
**   Licence. See the file COPYING for more information.
**
**   $Id: main.cpp,v 1.21 2005/02/26 23:17:32 andre Exp $
**
***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <qobject.h>
#include <qpe/qpeapplication.h>
#include <qmessagebox.h>
#include <libgen.h>
#include "generalconfig.h"
#include "messagehandler.h"
#include "cumulusapp.h"
#include "cumulusqpeapplication.h"

const char *callPath = 0;

/////////////////////
int main(int argc, char *argv[])
{
  CumulusQPEApplication a(argc, argv);

  // @AP: Note, that Opie will install a default message handler in
  // QPEApplication constructor. This handler will suppress all debug
  // and warning messages in release mode. Therefore we will install
  // our own handler now.

  qInstallMsgHandler(messageHandler);

  // @AP: make call path available for other modules of cumulus
  callPath = dirname(argv[0]);

  // @AP: to make trace output available, if process is started via
  // QPE, we can redirect all output into a file, if config option
  // Log2File is set to true.

  GeneralConfig *conf = GeneralConfig::instance();

  bool isLog2File = conf->getLog2FileMode();
  
  if( isLog2File )
    {
      int i = open( "/tmp/cumulus.log", O_RDWR|O_CREAT|O_TRUNC,
		    S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH );

      // Duplicate file descriptors 1, 2 that the output goes into a logfile

      // dup2( i, fileno(stdin) );
      dup2( i, fileno(stdout) );
      dup2( i, fileno(stderr) );

      close(i);
    }

/*
@AP: check, if environment variable LD_BIND_NOW is set. In this case reset
it to avoid a gps client crash during fork under Opie.

If the process environment [see exec(base operating system)] contains a
variable named LD_BIND_NOW with a non-null value, the dynamic linker processes
all relocations before transferring control to the program. For example, all
the following environment entries would specify this behavior.

    * LD_BIND_NOW=1
    * LD_BIND_NOW=on
    * LD_BIND_NOW=off 

Otherwise, LD_BIND_NOW either does not occur in the environment or has a null
value. The dynamic linker is permitted to evaluate procedure linkage table
entries lazily, thus avoiding symbol resolution and relocation overhead for
functions that are not called. See the Procedure Linkage Table in this chapter
of the processor supplement for more information.
*/

  char *env = getenv("LD_BIND_NOW");

  if( env != 0 )
    {
      unsetenv("LD_BIND_NOW");
    }

  #define DISCLAIMERVERSION 1

  if( conf->getDisclaimerVersion() < DISCLAIMERVERSION )
  {
    CumulusApp::playSound();
    if (QMessageBox::warning (NULL, QObject::tr("Cumulus Disclaimer"),
        QObject::tr(  //upon changing the text, you should also increase the value of DISCLAIMERVERSION with 1
           "Do not rely on this software\n"
           "program as your primary source\n"
           "of navigation. The operator is\n"
           "responsible for using official\n"
           "government charts and prudent\n"
           "methods for safe navigation.\n"
           "The information presented in this\n"
           "software program may be outdated\n"
           "or incorrect.\n\n"
           "Do you accept these terms?"
          ),
        QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
      {
	conf->setDisclaimerVersion( DISCLAIMERVERSION );
	conf->save();
      }
    else
      {
	qWarning("Closing application, user does not accept conditions.");
	return 0;
      }
  }

  // cumulus as local variable important to get the destructor called !
  CumulusApp cumulus (0, "cumulusapp");
 
  a.showMainWidget(&cumulus);
  int result = a.exec();

  delete GeneralConfig::instance();
  return result;
}
