#include "ProcArgs.h"
#include <boost/tokenizer.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
ProcArgs::ProcArgs( const char * paramStr )
  : frame(0.0)
  , fps(24.0)
  , shutterOpen(0)
  , shutterClose(0)
  , excludeXform(false)
  , makeInstance(false)
  , subdIterations(0)
  , proceduralNode(0)
{
    
    
    typedef boost::char_separator<char> Separator;
    typedef boost::tokenizer<Separator> Tokenizer;
    
    std::vector<std::string> tokens;
    std::string params( paramStr );
    Tokenizer tokenizer( params, Separator(" ") );
    for ( Tokenizer::iterator iter = tokenizer.begin(); iter != tokenizer.end() ;
          ++iter )
    {
        if ( (*iter).empty() ) { continue; }
        tokens.push_back( *iter );
    }
    for ( size_t i = 0; i < tokens.size(); ++i )
    {
        std::string token = tokens[i];
        std::transform( token.begin(), token.end(), token.begin(), ::tolower );
        if ( token == "-frame" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                frame = atof( tokens[i].c_str() );
            }
        }
        else if ( token == "-fps" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                fps = atof( tokens[i].c_str() );
            }
        }
        else if ( token == "-shutteropen" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                shutterOpen = atof( tokens[i].c_str() );
            }
        }
        else if ( token == "-shutterclose" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                shutterClose = atof( tokens[i].c_str() );
            }
        }
        else if ( token == "-filename" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                filename = tokens[i];
            }
        }
        else if ( token == "-nameprefix" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                nameprefix = tokens[i];
            }
        }
        else if ( token == "-objectpath" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                objectpath = tokens[i];
            }
        }
        else if ( token == "-excludexform" )
        {
            excludeXform = true;
            
        }
        else if ( token == "-subditerations" )
        {
            ++i;
            if ( i < tokens.size() )
            {
                subdIterations = atoi( tokens[i].c_str() );
            }
        }
        else if ( token == "-makeinstance" )
        {
            makeInstance = true;
        }
        
    }
}
void ProcArgs::usage()
{
    std::cerr << "AlembicArnoldProcedural usage:" << std::endl;
    std::cerr << std::endl;
    
    
    std::cerr << "-filename /path/to/some/archive.abc" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "This is the only required argument. "
                 "It has no default value." << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-frame 42" << std::endl;
    std::cerr << std::endl;
    std::cerr << "The frame number to load from within the archive. "
                 "The default value is 0. This is combined with -fps to map "
                 "to Alembic time units (double-precision seconds).";
    
    std::cerr << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-fps 24" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "Combined with -frame above. The default value is 24.0.";
    std::cerr << std::endl;
    std::cerr << std::endl;
    
    
    std::cerr << "-shutteropen 0.0" << std::endl;
    std::cerr << "-shutterclose 0.5" << std::endl;
    std::cerr << std::endl;
    std::cerr << "These are frame-relative values which specify the shutter "
                 "window. The procedural will include all samples present in "
                 "the archive which are relevant to the shutter window. "
                 "The default value of both is 0.0 (no motion blur).";
    std::cerr << std::endl;
    std::cerr << std::endl;
    std::cerr << "-objectpath /assetroot/characters" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "If specified, only objects at or below the provided path "
                 "(within the archive) will be emitted. When combined with "
                 "-excludexform, this can also be used to load individual "
                 "leaf locations within an externally defined hierarchy. Be "
                 "aware that in that case, you'd need to set the \"matrix\" "
                 "and \"inherit_xform\" parameters on the procedural node "
                 "itself. If the path points to a single \"faceset\" object "
                 "directly beneath a polymesh or subdivision mesh, it'll add "
                 "a \"face_visibility\" user data array.";
    std::cerr << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-excludexform" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "If specified, the \"matrix\" parameter will not be set on "
                 "the resulting primitive nodes." << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-subditerations 2" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "For AbcGeom::ISubD objects, this option specifies the "
                 "\"subdiv_iterations\" value. It currently has no effect for "
                 "other primitive types. The default value is 0.";
    std::cerr << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-nameprefix some_prefix__" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "Because node names are unique scene-wide in arnold, this "
                 "allows you control potential name clashes when loading or "
                 "instancing an archive (or multiple equivalently named "
                 "archives) multiple times. The default name of each node is "
                 "its full path within the alembic archive.";
    std::cerr << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "-makeinstance" << std::endl;
    std::cerr << std::endl;
    
    std::cerr << "This behavior is disabled by default. If enabled, the "
                 "procedural will attempt to identify identical primitives "
                 "(using Alembic's per-array-property hash keys) and create "
                 "corresponding \"ginstance\" nodes. Two primitives are "
                 "considered equivalent if the keys of their relevant point "
                 "position samples match along with any specified "
                 "subdivision values. This works across multiple archives or "
                 "invokations of the procedural. It currently does not write "
                 "unique user data per instance but will likely do so "
                 "automatically (when necessary) in a future release. "
                 "The ray visibility of the source primitive will be set to "
                 "AI_RAY_NONE and the \"ginstance\" node's will be set to "
                 "that of the calling \"procedural\" node.";
    
    std::cerr << std::endl;
    
}