%module{Slic3r::XS};

%{
#include <xsinit.h>
#include "slic3r/GUI/Preset.hpp"
#include "slic3r/GUI/PresetBundle.hpp"
#include "slic3r/GUI/PresetHints.hpp"
%}

%name{Slic3r::GUI::Preset} class Preset {
    // owned by PresetCollection, no constructor/destructor

    bool                        default()       %code%{ RETVAL = THIS->is_default;  %};
    bool                        external()      %code%{ RETVAL = THIS->is_external; %};
    bool                        system()        %code%{ RETVAL = THIS->is_system;   %};
    bool                        visible()       %code%{ RETVAL = THIS->is_visible;  %};
    bool                        dirty()         %code%{ RETVAL = THIS->is_dirty;    %};
    bool                        compatible()    %code%{ RETVAL = THIS->is_compatible; %};
    bool                        is_compatible_with_printer(Preset *active_printer)
        %code%{ RETVAL = THIS->is_compatible_with_printer(*active_printer); %};

    std::string                 name()          %code%{ RETVAL = THIS->name; %};
    std::string                 file()          %code%{ RETVAL = THIS->file; %};

    bool                        loaded()        %code%{ RETVAL = THIS->loaded;      %};

    Ref<DynamicPrintConfig>     config()        %code%{ RETVAL = &THIS->config;     %};

    void                        set_num_extruders(int num_extruders);
};

%name{Slic3r::GUI::PresetCollection} class PresetCollection {

    Ref<Preset>             preset(size_t idx) %code%{ RETVAL = &THIS->preset(idx); %};
    size_t                  size() const;
    size_t                  num_visible() const;
    std::string             name() const;

    Ref<Preset>             get_selected_preset() %code%{ RETVAL = &THIS->get_selected_preset(); %};
    Ref<Preset>             get_current_preset() %code%{ RETVAL = &THIS->get_edited_preset(); %};
    std::string             get_current_preset_name() %code%{ RETVAL = THIS->get_selected_preset().name; %};
    Ref<Preset>             get_edited_preset() %code%{ RETVAL = &THIS->get_edited_preset(); %};

    Ref<Preset>             find_preset(char *name, bool first_visible_if_not_found = false) %code%{ RETVAL = THIS->find_preset(name, first_visible_if_not_found); %};

    void                    update_tab_ui(SV *ui, bool show_incompatible)
        %code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" ); 
                THIS->update_tab_ui(cb, show_incompatible); %};

    void                    update_platter_ui(SV *ui)
        %code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object( aTHX_ ui, "Wx::BitmapComboBox" ); 
                THIS->update_platter_ui(cb); %};

%{

SV*
PresetCollection::arrayref()
    CODE:
        AV* av = newAV();
        av_fill(av, THIS->size()-1);
        for (int i = 0; i < int(THIS->size()); ++ i) {
            Preset &preset = THIS->preset(i);
            av_store(av, i, perl_to_SV_ref(preset));
        }
        RETVAL = newRV_noinc((SV*)av);
    OUTPUT:
        RETVAL

%}
};

%name{Slic3r::GUI::PresetBundle} class PresetBundle {
    PresetBundle();
    ~PresetBundle();

    void                        reset(bool delete_files);

    void                        setup_directories()
        %code%{
            try {
                THIS->setup_directories();
            } catch (std::exception& e) {
                croak("Cannot create configuration directories:\n%s\n", e.what());
            }
        %};
    void                        load_presets(AppConfig *config)
        %code%{
            try {
                THIS->load_presets(*config);
            } catch (std::exception& e) {
                croak("Loading of Slic3r presets from %s failed.\n\n%s\n", 
                    Slic3r::data_dir().c_str(), e.what());
            }
        %};
    void                        load_config(const char *name, DynamicPrintConfig *config)
        %code%{
            try {
                THIS->load_config(name, *config);
            } catch (std::exception& e) {
                croak("Loading a configuration %s failed:\n%s\n", name, e.what());
            }
        %};
    void                        load_config_file(const char *path)
        %code%{
            try {
                THIS->load_config_file(path);
            } catch (std::exception& e) {
                croak("Loading a configuration file %s failed:\n%s\n", path, e.what());
            }
        %};
    size_t                      load_configbundle(const char *path)
        %code%{
            try {
                RETVAL = THIS->load_configbundle(path, PresetBundle::LOAD_CFGBNDLE_SAVE);
            } catch (std::exception& e) {
                croak("Loading of a config bundle %s failed:\n%s\n", path, e.what());
            }
        %};
    void                        export_configbundle(char *path)
        %code%{
            try {
                THIS->export_configbundle(path);
            } catch (std::exception& e) {
                croak("Export of a config bundle %s failed:\n%s\n", path, e.what());
            }
        %};

    void                        set_default_suppressed(bool default_suppressed);

    void                        export_selections(AppConfig *config) %code%{ THIS->export_selections(*config); %};
    void                        export_selections_pp(PlaceholderParser *pp) %code%{ THIS->export_selections(*pp); %};

    Ref<PresetCollection>       print()    %code%{ RETVAL = &THIS->prints;   %};
    Ref<PresetCollection>       filament() %code%{ RETVAL = &THIS->filaments; %};
    Ref<PresetCollection>       sla_material() %code%{ RETVAL = &THIS->sla_materials; %};
    Ref<PresetCollection>       printer()  %code%{ RETVAL = &THIS->printers;  %};
    Ref<DynamicPrintConfig>     project_config() %code%{ RETVAL = &THIS->project_config; %};

    bool                        has_defauls_only();

    std::vector<std::string>    filament_presets() %code%{ RETVAL = THIS->filament_presets; %};
    void                        set_filament_preset(int idx, const char *name);

    Clone<DynamicPrintConfig>   full_config() %code%{ RETVAL = THIS->full_config();  %};

    void                        update_platter_filament_ui(int extruder_idx, SV *ui)
        %code%{ auto cb = (wxBitmapComboBox*)wxPli_sv_2_object(aTHX_ ui, "Wx::BitmapComboBox");
                THIS->update_platter_filament_ui(extruder_idx, cb); %};
};