//#####################################################################
// Copyright 2009, Nipun Kwatra.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
#ifndef __EXAMPLE__
#define __EXAMPLE__
#include <Core/Utilities/VIEWER_DIR.h>
#include <Core/Vectors/VECTOR.h>
#include <Core/Viewer/VIEWER_OUTPUT.h>
#include <functional>
#include <string>
namespace PhysBAM{

class PARSE_ARGS;
template<class TV>
class EXAMPLE
{
    typedef typename TV::SCALAR T;
    enum workaround1{d=TV::m};
    
public:
    const STREAM_TYPE stream_type;
    int last_frame=120;
    T frame_dt=(T)1/24;
    std::string frame_title;
    int write_substeps_level=-1;
    VIEWER_DIR viewer_dir{"output"};
    VIEWER_OUTPUT viewer_output{stream_type,viewer_dir};
    std::string data_directory;

    bool auto_restart=false;
    int restart=0;
    bool write_output_files=true;

    T fixed_dt=0;
    T min_dt=0;
    T max_dt=0;
    int substeps_delay_frame=-1;
    int substeps_delay_level=-1;
    bool use_test_output=false;
    std::string test_output_prefix;
    bool user_last_frame=false;
    bool user_output_directory=false;
    bool user_frame_dt=false;
    bool opt_nolog=false;
    int opt_verbosity=1<<30;
    T m=1,s=1,kg=1;
    std::string stored_args;

    EXAMPLE(STREAM_TYPE stream_type_input,PARSE_ARGS& parse_args);
    virtual ~EXAMPLE();

    std::function<void(T& dt,T time)> limit_dt;

//#####################################################################
    T Time_At_Frame(int frame) const;
    bool Clamp_Time_Step_With_Target_Time(T time,T target_time,T& dt);
    void Set_Write_Substeps_Level(int level);
    virtual void Register_Output_Files()=0;
    virtual void Log_Parameters() const;
//#####################################################################
};
}
#endif
