// ============================================================ //
//                                                              //
//   File      : itemtools.cxx                                  //
//   Purpose   : item-specific toolkit                          //
//                                                              //
//   Coded by Ralf Westram (coder@reallysoft.de) in July 2015   //
//   http://www.arb-home.de/                                    //
//                                                              //
// ============================================================ //

#include "items.h"

#include <arb_msg.h>
#include <arb_str.h>

#include <aw_window.hxx>

#include <arbdb.h>


const char *ITEMS_get_key(ItemSelector& selector) {
    // this method generates unique keys, if you have multiple ItemSelectors,
    // which have the same QUERY_ITEM_TYPE, but should be handled differently.
    // In these cases the 'items_name' field of these selectors has to differ!
    //
    // Example:
    // - species queries in mergetool (both QUERY_ITEM_SPECIES, bound to different database)

    const char *items_name = selector.items_name;

    static SmartCharPtr item_key;
    item_key = GBS_string_2_key(items_name);

    return &*item_key;
}

static const char *type_key[QUERY_ITEM_TYPES] = {
    "species",
    "organism",
    "gene",
    "experiment",
    "sai"
};

const char *ITEMS_get_type_key(QUERY_ITEM_TYPE itemtype) {
    return type_key[itemtype];
}

const char *ITEMS_get_possible_former_itemname(ItemSelector& selector) {
    const char *item_name = selector.item_name;
    if (GB_check_key(item_name) != NULp) {
        // currently this transforms "target species" + "source species" into "species"
        return type_key[selector.type];
    }
    return item_name;
}

inline char *itemTypeSpecificWindowID(QUERY_ITEM_TYPE itemtype, const char *window_id) {
    char *specific_win_id;
    if (speciesOrOrganism(itemtype)) {
        specific_win_id = ARB_strdup(window_id); // for species return given window id
    }
    else {
        char *item_type_id = ARB_strdup(ITEMS_get_type_key(itemtype));
        specific_win_id    = GBS_global_string_copy("%s_%s", window_id, ARB_strupper(item_type_id));
        free(item_type_id);
    }
    return specific_win_id;
}
inline char *itemSpecificWindowID(const ItemSelector& selector, const char *window_id, bool force_suffix) {
    char *specific_win_id;
    if (selector.type == QUERY_ITEM_SPECIES && !force_suffix && strcmp(selector.item_name, "species") == 0) {
        specific_win_id = ARB_strdup(window_id); // for species return given window id
    }
    else {
        specific_win_id = GBS_global_string_copy("%s_%s", window_id, ITEMS_get_key(selector));
    }
    return specific_win_id;
}

void init_itemType_specific_window(AW_root *aw_root, AW_window_simple *aws, const ItemSelector& itemType, const char *id, const char *title_format, bool plural) {
    char *s_id    = itemTypeSpecificWindowID(itemType.type, id);
    char *s_title = GBS_global_string_copy(title_format, plural ? itemType.items_name : itemType.item_name);

    aws->init(aw_root, s_id, s_title);

    free(s_title);
    free(s_id);
}
void init_item_specific_window(AW_root *aw_root, AW_window_simple *aws, const ItemSelector& itemType, const char *id, bool force_suffix, const char *title_format, bool plural) {
    /*! Init new window in an item specific manner.
     *
     * @param aw_root       window root.
     * @param aws           window to initialize.
     * @param itemType      specifies type of item.
     * @param id            the base macro id for this window. will be suffixed specific for itemtype.
     * @param force_suffix  force suffixing for normal 'species'? (false = similar to behavior of init_itemType_specific_window). recommended value is 'true'.
     * @param title_format  format string for title.
     * @param plural        use plural in title?
     */

    char *s_id    = itemSpecificWindowID(itemType, id, force_suffix);
    char *s_title = GBS_global_string_copy(title_format, plural ? itemType.items_name : itemType.item_name);

    aws->init(aw_root, s_id, s_title);

    free(s_title);
    free(s_id);
}

// --------------------------------------------------------------------------------

#ifdef UNIT_TESTS
#ifndef TEST_UNIT_H
#include <test_unit.h>
#endif

void TEST_itemTypeSpecificWindowID() {
    const char *WINID = "WINID";
    for (int i = 0; i<QUERY_ITEM_TYPES; ++i) {
        QUERY_ITEM_TYPE  itemtype       = (QUERY_ITEM_TYPE)i;
        char            *specific_winid = itemTypeSpecificWindowID(itemtype, WINID);
        const char      *expected_winid = NULp;
        switch (itemtype) {
            case QUERY_ITEM_SPECIES:    expected_winid = WINID; break;
            case QUERY_ITEM_ORGANISM:   expected_winid = WINID; break;
            case QUERY_ITEM_GENE:       expected_winid = "WINID_GENE"; break;
            case QUERY_ITEM_EXPERIMENT: expected_winid = "WINID_EXPERIMENT"; break;
            case QUERY_ITEM_SAI:        expected_winid = "WINID_SAI"; break;
        }
        TEST_EXPECT_EQUAL(specific_winid, expected_winid);
        free(specific_winid);
    }
}

#endif // UNIT_TESTS

// --------------------------------------------------------------------------------
