#include "pch.h"

#include "legacy_document_export_services.h"

#include "app.h"

#include <string>
#include <thread>

namespace pp::panopainter {
namespace {

class LegacyDocumentExportServices final : public pp::app::DocumentExportServices {
public:
    explicit LegacyDocumentExportServices(App& app) noexcept
        : app_(app)
    {
    }

    bool create_directory(std::string_view directory) override
    {
        return Asset::create_dir(std::string(directory));
    }

    void export_equirectangular(const pp::app::DocumentExportFileTarget& target) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_equirectangular(target.path, [app, target] {
#if defined(__IOS__)
            app->message_box("Export Equirectangular", "Image exported to Photos");
#elif defined(__OSX__)
            app->message_box("Export Equirectangular", "Image exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
            app->message_box("Export Equirectangular", "Image exported to " + app->work_path);
#elif defined(__QUEST__)
            (void)target;
#elif __WEB__
            app->ui_task([app, target] {
                app->save_prepared_file(target.path, target.suggested_name, [](const std::string&, bool) { });
            });
#else
            (void)target;
#endif
        });
    }

    void export_layers_to_stem(const pp::app::DocumentExportStemTarget& target) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_layers(target.stem_path, [app, target] {
            app->message_box("Export Layers", "Layers exported to: " + target.stem_path);
        });
    }

    void export_layers_to_collection(const pp::app::DocumentExportCollectionTarget& target) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_layers(target.stem_path, [app] {
            app->message_box("Export Layers", "Image layers exported to Files/PanoPainter");
        });
    }

    void export_animation_frames_to_stem(const pp::app::DocumentExportStemTarget& target) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_anim_frames(target.stem_path, [app, target] {
            app->message_box("Export Layers", "Layers exported to: " + target.stem_path);
        });
    }

    void export_animation_frames_to_collection(const pp::app::DocumentExportCollectionTarget& target) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_anim_frames(target.stem_path, [app] {
            app->message_box("Export Layers", "Image layers exported to Files/PanoPainter");
        });
    }

    void export_depth(std::string_view document_name) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_depth(std::string(document_name), [app] {
#if defined(__IOS__)
            app->message_box("Export 3D View + Depth", "Image and depth exported to Files/PanoPainter");
#elif defined(__OSX__)
            app->message_box("Export 3D View + Depth", "Image and depth exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
            app->message_box("Export 3D View + Depth", "Image and depth exported to " + app->work_path);
#endif
        });
    }

    void export_cube_faces(std::string_view document_name) override
    {
        auto* app = &app_;
        app_.canvas->m_canvas->export_cube_faces(std::string(document_name), [app] {
#if defined(__IOS__)
            app->message_box("Export Cube Faces", "Image and depth exported to Files/PanoPainter");
#elif defined(__OSX__)
            app->message_box("Export Cube Faces", "Image and depth exported to Pictures/PanoPainter folder");
#elif defined(_WIN32)
            app->message_box("Export Cube Faces", "Image and depth exported to " + app->work_path);
#endif
        });
    }

private:
    App& app_;
};

class LegacyDocumentVideoExportServices final : public pp::app::DocumentVideoExportServices {
public:
    LegacyDocumentVideoExportServices(App& app, bool asynchronous) noexcept
        : app_(app)
        , asynchronous_(asynchronous)
    {
    }

    void export_animation_mp4(std::string_view path) override
    {
        auto* app = &app_;
        auto path_string = std::string(path);
        if (asynchronous_) {
            Canvas::I->export_anim_mp4(path_string, [app, path_string] {
                app->message_box("Export Animation", "Animation exported to: " + path_string);
            });
            return;
        }

        Canvas::I->export_anim_mp4(path_string, [app] {
            app->message_box("Export Animation", "Animation exported successfully.");
        });
    }

    void export_timelapse_mp4(std::string_view path) override
    {
        auto* app = &app_;
        auto path_string = std::string(path);
        if (asynchronous_) {
            std::thread([app, path_string] {
                BT_SetTerminate();
                app->rec_export(path_string);
                app->message_box("Export Timelapse", "Timelapse exported to: " + path_string);
            }).detach();
            return;
        }

        app->rec_export(path_string);
    }

    void show_animation_export_success(std::string_view path) override
    {
        (void)path;
    }

    void show_timelapse_export_success(std::string_view path) override
    {
        if (asynchronous_) {
            (void)path;
        } else {
            app_.message_box("Export Timelapse", "Timelapse exported successfully.");
        }
    }

private:
    App& app_;
    bool asynchronous_ = false;
};

} // namespace

pp::foundation::Status execute_legacy_document_export_file(
    App& app,
    const pp::app::DocumentExportFileTarget& target)
{
    LegacyDocumentExportServices services(app);
    return pp::app::execute_document_export_file(target, services);
}

pp::foundation::Status execute_legacy_document_export_stem(
    App& app,
    pp::app::DocumentExportCollectionKind kind,
    const pp::app::DocumentExportStemTarget& target)
{
    LegacyDocumentExportServices services(app);
    return pp::app::execute_document_export_stem(kind, target, services);
}

pp::foundation::Status execute_legacy_document_export_collection(
    App& app,
    pp::app::DocumentExportCollectionKind kind,
    const pp::app::DocumentExportCollectionTarget& target)
{
    LegacyDocumentExportServices services(app);
    return pp::app::execute_document_export_collection(kind, target, services);
}

pp::foundation::Status execute_legacy_document_export_depth(
    App& app,
    std::string_view document_name)
{
    LegacyDocumentExportServices services(app);
    return pp::app::execute_document_export_depth(document_name, services);
}

pp::foundation::Status execute_legacy_document_export_cube_faces(
    App& app,
    std::string_view document_name)
{
    LegacyDocumentExportServices services(app);
    return pp::app::execute_document_export_cube_faces(document_name, services);
}

pp::foundation::Status execute_legacy_document_video_export(
    App& app,
    pp::app::DocumentVideoExportKind kind,
    std::string_view path,
    bool asynchronous)
{
    LegacyDocumentVideoExportServices services(app, asynchronous);
    return pp::app::execute_document_video_export(kind, path, services);
}

} // namespace pp::panopainter
