/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Module configuration.
 * @remarks Most of the joystick configuration (axis3,calibration,autofire)
 *          is done by the higher-level "control" module.
 *//*
 * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define INPUT_CONF_CC 1
#include <fstream>
#include "base/module.hh"
#include "base/conf.hh"
#include "base/conf_template_macros.hh"
#include "base/misc.hh"
#include "base/stream.hh"
using namespace base;
#include "input/module.hh"
#include "input/defs.hh"
#include "input/conf.hh"

namespace input {

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

namespace global { Conf gConf; }

/*****************************************************************************
 * ctor/dtor.
 *****************************************************************************/
Conf::Conf( void )
:   mValid(false),
    // cmd-line args 
    // .conf file
    mInputQueueTickFreq(defs::DEFAULT_INPUT_QUEUE_TICK_FREQ),
    mKeyboardInputQueueOverflow(0),
    mJoystickInputQueueOverflow(0),
    mMouseInputQueueOverflow(0),
    mJoystickNum(0),
    mEnableLinuxJoystick(false),    // false to prefer SDL (applies to FreeBSD too)
    mEnableWindowsJoystick(false)   // false to prefer SDL
{
}

/*****************************************************************************
 * Initialize/read configuration.
 *****************************************************************************/
void
Conf::Init( const base::InitArgs& initArgs, const string& confTxtFilename )
{
    CONF_TEMPLATE_Init_ParseCmdline_ReadConfTxt;
}

/*****************************************************************************
 * Parse cmdline args.
 *****************************************************************************/
void
Conf::ParseCmdlineArgs( int argc, char** argv )
{
    // Parse args.
    for ( int i = 1; i < argc; ++i )
    {
        // -- Other joystick args are parsed at control module. --

        if ( STREQ( argv[i], "-jn" ) )
        {
            mJoystickNum = Argi( i+1, argc, argv );
          //COUT << "Selecting joystick " << mJoystickNum << std::endl;  // let driver confirm
            CmdargDone( i+1, 1 );  // let -jn stay for control module to see it
        }
        else if ( STREQ( argv[i], "-jlinux" ) )
        {
            mEnableLinuxJoystick = true;
            //CmdargDone( i, 1 );  // let -jn stay for control module to see it
        }
        else if ( STREQ( argv[i], "-jwindows" ) )
        {
            mEnableWindowsJoystick = true;
            //CmdargDone( i, 1 );  // let -jn stay for control module to see it
        }
    }
}

void
Conf::ParseCmdlineArgs2( int argc, char** argv )
{
    // NOP
}

/*****************************************************************************
 * Read from .conf file.
 *****************************************************************************/
void
Conf::ReadConfTxt( const string& confTxtFilename )
{
    CONF_TEMPLATE_ReadConfTxt;
}

void
Conf::ModuleConfTxt::ProcessField( string& field, std::ifstream& conf )
{
    bool error = false;

    // -----------------------  Timer  -----------------------------------------
    if ( field == "InputQueueTickFreq" )
    {
        conf >> INPUT_CONF.mInputQueueTickFreq;
        if ( (INPUT_CONF.mInputQueueTickFreq <= Milliseconds(0))
          or (INPUT_CONF.mInputQueueTickFreq >= Milliseconds(1000)) )
            error = true;
    }
    else if ( field == "KeyboardInputQueueOverflow" )
    {
        conf >> INPUT_CONF.mKeyboardInputQueueOverflow;
    }
    else if ( field == "JoystickInputQueueOverflow" )
    {
        conf >> INPUT_CONF.mJoystickInputQueueOverflow;
    }
    else if ( field == "MouseInputQueueOverflow" )
    {
        conf >> INPUT_CONF.mMouseInputQueueOverflow;
    }

    // Errors?
    if ( error )
    {
        CERROR << "ERROR[conf]: parameter for " << field << " is invalid." << std::endl;
        EXIT( 1 );
    }
}

/*****************************************************************************
 * Print Conf configuration.
 *****************************************************************************/
std::ostream& operator<<( std::ostream& strm, const Conf& conf )
{
    std::ios::fmtflags savedFlags = strm.flags();
    strm << "conf [input]:" << std::endl
         << "Key/joy/mouse overflow   =" <<        INPUT_CONF.mKeyboardInputQueueOverflow
                                         << ',' << INPUT_CONF.mJoystickInputQueueOverflow
                                         << ',' << INPUT_CONF.mMouseInputQueueOverflow; //std::endl
    strm.flags(savedFlags);
    return strm;
}

} // namespace input
