//#####################################################################
// Copyright 2019, Craig Schroeder.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class VIEWER_DIR
//#####################################################################
#ifndef __VIEWER_DIR__
#define __VIEWER_DIR__

#include <Core/Arrays/ARRAY.h>
#include <string>
namespace PhysBAM{
struct VIEWER_DIR
{
    static const int max_substep_level = 10;
    bool no_log=false;
    std::string output_directory;
    ARRAY<int> frame_stack;

private:
    std::string current_directory;
    bool made_common=false;
public:

    struct SAVE_STATE
    {
        std::string current_directory;
        ARRAY<int> frame_stack;
        bool made_common=false;
    };

    explicit VIEWER_DIR(const std::string& output_directory);
    VIEWER_DIR(const VIEWER_DIR&)=delete;
    VIEWER_DIR&operator=(const VIEWER_DIR&)=delete;
    ~VIEWER_DIR();

    // Write
    void Make_Common_Directory(bool append_log=false);
    void Start_Directory(int substep_level,const char* title);
    void Start_Directory(int substep_level,const std::string& title);
    void Finish_Directory();
    bool First_Frame() const;

    // Read
    bool Find_Next_Directory(int substep_level,bool check_last_frame);
    bool Find_Prev_Directory(int substep_level,bool check_last_frame);
    void Read_Last_Frame(ARRAY<int>& stack) const;
    void Read_Last_Frame(int substep_level=max_substep_level);
    void Set(int frame);
    void Set(const std::string& frame_string);
    void Set(const char* frame_string);
    bool Valid_Frame(bool check_last_frame) const;
    bool Valid_Frame(const ARRAY<int>& stack, bool check_last_frame) const;
    
    // Helper utilities
    void Advance_Directory(int substep_level);
    void Update_Current_Directory();
    std::string Current_Directory(const ARRAY<int>& stack) const;
    std::string Frame_As_String(const ARRAY<int>& stack) const;
    std::string Frame_As_String() const;
    void Parse_Frame(ARRAY<int>& stack,const std::string& frame_string) const;
    void Parse_Frame(ARRAY<int>& stack,const char* frame_string) const;
    std::string Common_File(const char* filename) const;
    std::string Common_File(const std::string& filename) const;
    std::string Frame_File(const char* filename) const;
    std::string Frame_File(const std::string& filename) const;

    void Save_State(SAVE_STATE& s) const;
    void Restore_State(const SAVE_STATE& s);
};
}
#endif
