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

#define GRAPH_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 "gfx/rgba.hh"
using namespace gfx;
#include "graph/module.hh"
#include "graph/defs.hh"
#include "graph/conf.hh"
#include "graph/shadow_scene_graph.hh"

namespace graph {

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

namespace global { Conf gConf; }

/*****************************************************************************
 * ctor/dtor.
 *****************************************************************************/
Conf::Conf( void )
:   mValid(false),
    // cmd-line args
    mEnableOsgOptimizer(true),
    mEnableWireframe(false),
    mEnableDumpFull(false),
    mEnableFog(true),
    mShadowMode(graph::defs::SHADOW_MODE_DEFAULT),
    // .conf file
    mShadowLightNum(1),
    mShadowLightPos(500.0f, 500.0f, 3000.0f, 0.0f),
    mShadowLightDir(0.70710678f, 0.0f, -0.70710678f),
    mShadowLightColor(1.0f, 1.0f, 1.0f, 1.0f),
    mBackgroundColor(graph::defs::DEFAULT_BACKGROUND_COLOR)
{
    // NOP
}

/*****************************************************************************
 * 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 )
{
    // NOP
}

void
Conf::ParseCmdlineArgs2( int argc, char** argv )
{
    for ( int i = 1; i < argc; ++i )
    {
        if ( STREQ( argv[i], "-no-osg-opt" ) )
        {
            mEnableOsgOptimizer = false;
            CmdargDone( i );
            CLOG << "Disabled OSG optimizer." << std::endl;
        }
        else if ( STREQ( argv[i], "-wire" )
               or STREQ( argv[i], "-wireframe" ) )
        {
            mEnableWireframe = true;
            CLOG << "Enabled wireframe mode." << std::endl;
        }
        else if ( STREQ( argv[i], "-dump-full" )   // BTW, dumping core is -debug/-debugger/-gdb
               or STREQ( argv[i], "-full-dump" )   // alt
               or STREQ( argv[i], "-dump-all" ) )  // alt
        {
            mEnableDumpFull = true;
            CmdargDone( i );
            CLOG << "Enabled fully dumping scene-graph." << std::endl;
        }
        else if ( STRSTR( argv[i], "-no-shadow" )  // or -no-shadows
               or STREQ( argv[i], "-fast" ) )
        {
            mShadowMode = graph::defs::SHADOW_MODE_DISABLED;
            CmdargDone( i );
            CLOG << "Disabled shadows." << std::endl;
        }
        else if ( STRSTR( argv[i], "-fast-shadow" ) )  // or -fast-shadows
        {
            mShadowMode = graph::defs::SHADOW_MODE_SAMPLE1;
            CmdargDone( i );
            CLOG << "Enabled fast shadows." << std::endl;
        }
        else if ( STRSTR( argv[i], "-soft-shadow" ) )  // or -soft-shadows
        {
            mShadowMode = graph::defs::SHADOW_MODE_SAMPLE4;
            CmdargDone( i );
            CLOG << "Enabled soft shadows." << std::endl;
        }
    }
}

/*****************************************************************************
 * 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;

    if ( field == "ShadowLightNum" )
    {
        conf >> GRAPH_CONF.mShadowLightNum;
    }
    else if ( field == "ShadowLightPosition" )  // 4D
    {
        conf >> GRAPH_CONF.mShadowLightPos[XX];
        conf >> GRAPH_CONF.mShadowLightPos[YY];
        conf >> GRAPH_CONF.mShadowLightPos[ZZ];
        conf >> GRAPH_CONF.mShadowLightPos[WW];
    }
    else if ( field == "ShadowLightDirection" )  // 3D
    {
        conf >> GRAPH_CONF.mShadowLightDir[XX];
        conf >> GRAPH_CONF.mShadowLightDir[YY];
        conf >> GRAPH_CONF.mShadowLightDir[ZZ];
    }
    else if ( field == "ShadowLightColor" )
    {
        fp r, g, b, a;
        conf >> r;
        conf >> g;
        conf >> b;
        conf >> a;
        GRAPH_CONF.mShadowLightColor.Set( r, g, b, a );
    }
    else if ( field == "BackgroundColor" )
    {
        fp r, g, b, a;
        conf >> r;
        conf >> g;
        conf >> b;
        conf >> a;
        GRAPH_CONF.mBackgroundColor.Set( r, g, b, a );
    }

    // 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 [graph]:"                                                      << std::endl
         << "enable OSG optimizer        = " << conf.mEnableOsgOptimizer         << std::endl
         << "shadow mode                 = " << conf.mShadowMode              ;//<< std::endl
    strm.flags(savedFlags);

    return strm;
}

} // namespace graph
