#pragma once
#include <filesystem>
#include <string>
#include <vector>

#include "ecs/entity.h"
#include "ecs/ComponentFactory.h"

class d_3d_class;
class object;
class application_class;

static inline std::string trim(const std::string& s) {
    size_t start = s.find_first_not_of(" \t\r\n");
    size_t end = s.find_last_not_of(" \t\r\n");
    return (start == std::string::npos) ? "" : s.substr(start, end - start + 1);
}

class scene_manager
{
public:

    scene_manager();
    ~scene_manager();

    /**
     * Initialize the scene manager with the application instance.
     * @param app Pointer to the application class instance.
     * @return True if initialization is successful, otherwise false.
     */
    bool initialize(application_class* app);
    /**
     * Shutdown the scene manager and release resources.
     * @return True if shutdown is successful, otherwise false.
     */
    bool shutdown();

    /**
     * Function to save the current scene as a new file.
     * The scene is saved in a .ker file format.
     * This function will prompt the user to choose a file location and name.
     * Then it will call the save_scene function to perform the actual saving.
     * @return 
     */
    bool save_scene_as();
    /**
     * Function to save the current scene.
     * This function will save the current scene to the path specified in scene_path_.
     * If the scene_path_ is empty, it will call save_scene_as() to prompt the user for a file location.
     * @return True if the scene was saved successfully, otherwise false.
     */
    bool save_scene();
    /**
     * Function to load a scene from a file.
     * This function will prompt the user to choose a file to load.
     * @return True if the scene was loaded successfully, otherwise false.
     */
    bool load_scene();

    /**
     * Get the current scene path.
     * @return The path to the current scene as a string.
     */
    std::wstring get_scene_path();
    /**
     * Convert a wide string to a standard string.
     * @param w_str 
     * @return The converted string.
     */
    std::string convert_w_string_to_string(const std::wstring& w_str);

private:

    std::vector<std::shared_ptr<ecs::Entity>> entity_;
    
    application_class* app_;
    std::string scene_path_;
    std::vector<object*> object_vec_;
    int object_id_;
    std::filesystem::path w_folder_;
    d_3d_class* direct_3d_;
};
