/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   glue module configuration.
 *//*
 * LEGAL:   COPYRIGHT (C) 2008 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define GLUE_CONF_CC 1
#include "base/module.hh"
#include "base/misc.hh"
#include "base/file.hh"
#include "base/stream.hh"
using namespace base;
#include "glue/module.hh"
#include "glue/conf.hh"

namespace glue {

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////  functions  /////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/*****************************************************************************
 * @return Name of user's home directory.
 * THROWS EXCEPTION
 * ~/.PROGRAM
 *****************************************************************************/
const string& GetHomeDirectoryName( void )
{
    PERSISTENT string sDirname;
    if ( sDirname.empty() )
    {
#if DOSFS || OS_WINDOWS
        // Windows:
        // Catenate HOMEDRIVE (C:) + HOMEPATH (\Documents and Settings).
        const char* homeDrive = getenv( "HOMEDRIVE" );
        const char* homePath  = getenv( "HOMEPATH" );
        if ( (homeDrive == NULL) or (homePath == NULL) )
            throw Exception( "ERROR: can't get HOMEDRIVE,HOMEPATH env var" );
        sDirname = string(homeDrive) + string(homePath);
#else
        // UNIX:
        const char* homeEnv = getenv( "HOME" );
        if ( homeEnv == NULL )
            throw Exception( "ERROR: can't get HOME env var" );
        sDirname = homeEnv;
#endif
    }
    ASSERT( not sDirname.empty() );
    return sDirname;
}

/*****************************************************************************
 * Open (or create) the directory that holds configuration files.
 * THROWS EXCEPTION
 * ~/.palomino
 *****************************************************************************/
const string& GetConfDirectoryName( void )
{
    PERSISTENT string sConfDir;
    if ( sConfDir.empty() )
    {
        // Base name of conf dir is similar to program name.
        // Find or create configuration directory.
        sConfDir = glue::GetHomeDirectoryName();
        sConfDir += DIRECTORY_SEPARATOR_CHAR;
        sConfDir += ".";  // leading dot to hide directory on UNIX
        ASSERT( not GLUE_CONF.mProgramName.empty() );
        sConfDir += GLUE_CONF.mProgramName;
        if ( not IfDirExists( sConfDir ) )
        {
            // Directory doesn't exist yet.  Make directory.
            if ( MakeDir( sConfDir ) )
                CLOG << "Made configuration directory " << sConfDir << std::endl;
            else
                throw Exception( string("Warning: cannot open/make directory ") + sConfDir );
        }
    }
    ASSERT( not sConfDir.empty() );
    return sConfDir;
}

////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////  Conf  ///////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

namespace global { Conf gConf; }

/*****************************************************************************
 * ctor/dtor.
 *****************************************************************************/
Conf::Conf( void )
:   mValid(false),
    mProgramName(""),  // set by Conf::Init()
    // cmd-line args
    mFastMode(false)
#if COMPILE_SDL
   ,mEnableSDL(true)
#endif
{
    // NOP
}

/*****************************************************************************
 * Initialize/read configuration.
 *****************************************************************************/
void
Conf::Init( const base::InitArgs& initArgs )
{
// glue's Conf class is special.

BEGIN_ONCE {

    mValid = true;  // now conf is valid

    mProgramName = initArgs.mProgramName;  // first of all, set the program's name

    ParseCmdlineArgs( initArgs.mArgc, initArgs.mArgv );

} END_ONCE

}

/*****************************************************************************
 * Parse cmdline args.
 *****************************************************************************/
void
Conf::ParseCmdlineArgs( int argc, char** argv )
{
    // Parse args.
    for ( int i = 1; i < argc; ++i )
    {
        if ( STRSTR( argv[i], "-fast" ) )
        {
            GLUE_CONF.mFastMode = true;
            CmdargDone( i );
            CLOG << "Fast mode." << std::endl;
        }
#if COMPILE_SDL
        else if ( STREQ( argv[i], "-no-sdl" ) )
        {
            COUT << "Disabled SDL." << std::endl;
            mEnableSDL = false;
            CmdargDone( i );
        }
#endif // COMPILE_SDL
    }
}

} // namespace glue
