//  ==================================================================== //
//                                                                       //
//    File      : MG_configs.cxx                                         //
//    Purpose   : Merge editor configurations                            //
//                                                                       //
//                                                                       //
//  Coded by Ralf Westram (coder@reallysoft.de) in July 2003             //
//  Copyright Department of Microbiology (Technical University Munich)   //
//                                                                       //
//  Visit our web site at: http://www.arb-home.de/                       //
//                                                                       //
//                                                                       //
//  ==================================================================== //

#include "merge.hxx"

#include <sel_boxes.hxx>
#include <selection_admin.h>
#include <prompt.hxx>

#include <aw_root.hxx>
#include <aw_awar.hxx>
#include <aw_awar_defs.hxx>
#include <aw_msg.hxx>

#include <ad_config.h>
#include <arbdb.h>

// @@@ change term "config" to "species selection" here (in interface + messages)

#define AWAR_CONFIG_NAME(db)          awar_name_tmp(db, "specsel_name")
#define AWAR_SPECSEL_COMMENT_NAME(db) awar_name_tmp(db, "specsel_comment")

inline void create_config_awars_for_db(AW_root *aw_root, AW_default aw_def, DbSel db) {
    aw_root->awar_string(AWAR_CONFIG_NAME(db),          "", aw_def);
    aw_root->awar_string(AWAR_SPECSEL_COMMENT_NAME(db), "", aw_def);
}
void MG_create_config_awar(AW_root *aw_root, AW_default aw_def) {
    create_config_awars_for_db(aw_root, aw_def, SRC_DB);
    create_config_awars_for_db(aw_root, aw_def, DST_DB);

    aw_root->awar_int(AWAR_TREE_REFRESH, 0, aw_def); // dummy used by extract_species_selection()
}

class MgSelectionAdmin: public SelectionAdmin {
    DbSel db;

public:
    MgSelectionAdmin(DbSel db_) : db(db_) {}

    const char *get_macro_suffix() const { return db == SRC_DB ? "src" : "tgt"; }
    GBDATA *get_gb_main() const { return ::get_gb_main(db); }

    const char *get_selection_awarname() const { return AWAR_CONFIG_NAME(db); }
    const char *get_selectionComment_awarname() const { return AWAR_SPECSEL_COMMENT_NAME(db); }

    const char *get_window_title() const { return GBS_global_string("Species selections (%s DB)", dbSide(db)); }

    const char *get_name_of_tree() const { arb_assert(0); return NULp; }
    class TreeNode *get_tree_root() const { return NULp; } // means: store species selection w/o groups

    const char *get_toparea_SAIs() const { return ""; } // do not add SAI info to species selection

    // rename/delete selections => no special action required in mergetool:
    void speciesSelection_renamed_cb(const char *, const char *) const {}
    void speciesSelection_deleted_cb(const char *) const {}
};


void MG_popup_selection_admin(AW_window *aw_parent, DbSel db) {
    static AW_window *existing_aws[2] = { NULp, NULp };

    int db_idx = int(db)-1;
    if (!existing_aws[db_idx]) {
        AW_root                  *root  = aw_parent->get_root();
        MgSelectionAdmin * const  admin = new MgSelectionAdmin(db);
        AW_window                *aws   = create_species_selection_window(root, admin);
        existing_aws[db_idx] = aws;
    }
    existing_aws[db_idx]->activate();
}

static void MG_transfer_selection(AW_window *aww, DbSel from_db) {
    AW_root *awr    = aww->get_root();
    char    *config = awr->awar(AWAR_CONFIG_NAME(from_db))->read_string();
    DbSel    to_db  = otherDb(from_db);

    GBDATA *gb_main_from = get_gb_main(from_db);
    GBDATA *gb_main_to   = get_gb_main(to_db);

    GB_ERROR error = GB_begin_transaction(gb_main_to);
    if (!error) {
        error = GB_begin_transaction(gb_main_from);
        if (!error) {
            GBDATA *gb_config_data_from = GB_search(gb_main_from, CONFIG_DATA_PATH, GB_CREATE_CONTAINER);
            GBDATA *gb_config_data_to   = GB_search(gb_main_to, CONFIG_DATA_PATH, GB_CREATE_CONTAINER);

            GBDATA *gb_exist_name_from = GB_find_string(gb_config_data_from, "name", config, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
            GBDATA *gb_exist_name_to   = GB_find_string(gb_config_data_to,   "name", config, GB_IGNORE_CASE, SEARCH_GRANDCHILD);

            if (!gb_exist_name_from) {
                error = GBS_global_string("First select a species selection in the %s list.", dbSide(from_db));
            }
            else if (gb_exist_name_to) {
                error = GBS_global_string("The %s database already has a selection '%s'.\n"
                                          "Use 'Edit selection' to delete or rename.",
                                          dbSide(to_db), config);
            }
            else {
                GBDATA *gb_cfg_from = GB_get_father(gb_exist_name_from);
                GBDATA *gb_cfg_to   = GB_create_container(gb_config_data_to, "configuration");
                error               = GB_copy_dropProtectMarksAndTempstate(gb_cfg_to, gb_cfg_from);
            }
        }
        error = GB_end_transaction(gb_main_from, error);
    }
    error = GB_end_transaction(gb_main_to, error);

    if (error) aw_message(error);
    else       awr->awar(AWAR_CONFIG_NAME(to_db))->write_string(config);

    free(config);
}

AW_window *MG_create_merge_selections_window(AW_root *awr) {
    GB_ERROR error = MG_expect_renamed();
    if (error) {
        aw_message(error);
        return NULp; // deny to open window before user has renamed species
    }

    AW_window_simple *aws = new AW_window_simple;

    aws->init(awr, "MERGE_CONFIGS", "Transfer species selections (=editor configs)");
    aws->load_xfig("merge/configs.fig");

    aws->button_length(10);

    aws->at("close");
    aws->callback(AW_POPDOWN);
    aws->create_button("CLOSE", "CLOSE", "C");

    aws->at("help");
    aws->callback(makeHelpCallback("mg_species_configs.hlp"));
    aws->create_button("HELP", "HELP", "H");

    aws->at("configs1");
    awt_create_CONFIG_selection_list(GLOBAL_gb_src, aws, AWAR_CONFIG_NAME(SRC_DB));

    aws->at("configs2");
    awt_create_CONFIG_selection_list(GLOBAL_gb_dst, aws, AWAR_CONFIG_NAME(DST_DB));

    aws->button_length(20);

    aws->at("edit1");
    aws->callback(makeWindowCallback(MG_popup_selection_admin, SRC_DB));
    aws->create_button("EDIT_SELECTION_DB1", "Edit selection");

    aws->at("edit2");
    aws->callback(makeWindowCallback(MG_popup_selection_admin, DST_DB));
    aws->create_button("EDIT_SELECTION_DB2", "Edit selection");

    aws->at("xfer1");
    aws->callback(makeWindowCallback(MG_transfer_selection, SRC_DB));
    aws->create_button("TRANSFER_SELECTION_DB1", "Transfer selection");
    aws->alias_remote_command("TRANSFER_CONFIG", "TRANSFER_SELECTION_DB1"); // macro backward compatibility

    aws->at("xfer2");
    aws->callback(makeWindowCallback(MG_transfer_selection, DST_DB));
    aws->create_button("TRANSFER_SELECTION_DB2", "Transfer selection");

    aws->button_length(0);
    aws->shadow_width(1);
    aws->at("icon");
    aws->callback(makeHelpCallback("mg_species_configs.hlp"));
    aws->create_button("HELP_MERGE", "#merge/icon.xpm");

    return aws;
}

