//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//
// copyright            : (C) 2008 by Eran Ifrah
// file name            : macros.h
//
// -------------------------------------------------------------------------
// A
//              _____           _      _     _ _
//             /  __ \         | |    | |   (_) |
//             | /  \/ ___   __| | ___| |    _| |_ ___
//             | |    / _ \ / _  |/ _ \ |   | | __/ _ )
//             | \__/\ (_) | (_| |  __/ |___| | ||  __/
//              \____/\___/ \__,_|\___\_____/_|\__\___|
//
//                                                  F i l e
//
//    This program is free software; you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation; either version 2 of the License, or
//    (at your option) any later version.
//
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifndef MACROS_H
#define MACROS_H

#include "cl_standard_paths.h"
#include "wxStringHash.h"

#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <wx/intl.h>
#include <wx/stdpaths.h>

//-------------------------------------------------------
// wxWidgets Connect macros
//-------------------------------------------------------

#define ConnectChoice(ctrl, fn)                                                                         \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(fn), NULL, this);

#define ConnectButton(ctrl, fn)                                                                        \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(fn), NULL, this);

#define ConnectListBoxDClick(ctrl, fn)                                                                        \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(fn), NULL, this);

#define ConnectCheckBox(ctrl, fn)                                                                        \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(fn), NULL, this);

#define ConnectListCtrlItemSelected(ctrl, fn)                                                           \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(fn), NULL, this);

#define ConnectListCtrlItemActivated(ctrl, fn)                                                           \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(fn), NULL, this);

#define ConnectKeyDown(ctrl, fn) ctrl->Connect(ctrl->GetId(), wxEVT_KEY_DOWN, wxKeyEventHandler(fn), NULL, this);

#define ConnectCharEvent(ctrl, fn) ctrl->Connect(ctrl->GetId(), wxEVT_CHAR, wxKeyEventHandler(fn), NULL, this);

#define ConnectCmdTextEntered(ctrl, fn)                                                            \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(fn), NULL, this);

#define ConnectCmdTextUpdated(ctrl, fn)                                                              \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(fn), NULL, this);

#define ConnectCombo(ctrl, fn)                                                                            \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(fn), NULL, this);

#define ConnectCheckList(ctrl, fn)                                                                           \
    ctrl->Connect(ctrl->GetId(), wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEventHandler(fn), NULL, this);

#define TrimString(str)        \
    {                          \
        str = str.Trim();      \
        str = str.Trim(false); \
    }

#define IsSourceFile(ext)                                                                                \
    (ext == wxT("cpp") || ext == wxT("cxx") || ext == wxT("c") || ext == wxT("c++") || ext == wxT("cc"))

#define BoolToString(b) b ? wxT("yes") : wxT("no")

//-----------------------------------------------------
// Constants
//-----------------------------------------------------

#define clCMD_NEW _("<New...>")
#define clCMD_EDIT _("<Edit...>")

// constant message
#define BUILD_START_MSG _("==========Build Started==========\n")
#define BUILD_END_MSG _("==========Build Ended==========\n")
#define BUILD_PROJECT_PREFIX _("==========Building project:[ ")
#define BUILD_PROJECT_SUFFIX _(" ]==========")
#define CLEAN_PROJECT_PREFIX _("==========Cleaning project:[ ")

// Find in files options
#define SEARCH_IN_WORKSPACE wxTRANSLATE("<Entire Workspace>")
#define SEARCH_IN_PROJECT wxTRANSLATE("<Active Project>")
#define SEARCH_IN_CURR_FILE_PROJECT wxTRANSLATE("<Current File's Project>")
#define SEARCH_IN_CURRENT_FILE wxTRANSLATE("<Current File>")
#define SEARCH_IN_OPEN_FILES wxTRANSLATE("<Open Files>")
#define SEARCH_IN_WORKSPACE_FOLDER wxTRANSLATE("<Workspace Folder>")
#define USE_WORKSPACE_ENV_VAR_SET wxTRANSLATE("<Use Defaults>")
#define USE_GLOBAL_SETTINGS wxTRANSLATE("<Use Defaults>")

// terminal macro
#ifdef __WXGTK__
#define TERMINAL_CMD                                                                           \
    wxString::Format(wxT("%s/codelite_xterm '$(TITLE)' '$(CMD)'"),                             \
                     wxFileName(clStandardPaths::Get().GetExecutablePath()).GetPath().c_str())
#elif defined(__WXMAC__)
#define TERMINAL_CMD wxString::Format(wxT("%s/OpenTerm '$(CMD)'"), clStandardPaths::Get().GetDataDir().c_str())
#else
#define TERMINAL_CMD ""
#endif

#if defined(__WXMSW__)
#define PATH_SEP wxT("\\")
#else
#define PATH_SEP wxT("/")
#endif

#define ID_MENU_CUSTOM_TARGET_FIRST 15000
#define ID_MENU_CUSTOM_TARGET_MAX 15100

#define viewAsMenuItemID 23500
#define viewAsMenuItemMaxID 23500 + 100

#define viewAsSubMenuID 23499
#define RecentFilesSubMenuID 23600
#define RecentWorkspaceSubMenuID 23650

// Useful macros
#define CHECK_PTR_RET(p) \
    if (!p)              \
    return
#define CHECK_PTR_RET_FALSE(p) \
    if (!p)                    \
    return false
#define CHECK_PTR_RET_NULL(p) \
    if (!p)                   \
    return NULL

#define CHECK_PTR_RET_EMPTY_STRING(p) \
    if (!p)                           \
    return wxEmptyString

// If expression != expected -> return
#define CHECK_EXPECTED_RETURN(expression, expected) \
    if ((expression) != (expected))                 \
    return

#define CHECK_COND_RET(p) \
    if (!(p))             \
    return
#define CHECK_COND_RET_FALSE(p) \
    if (!(p))                   \
    return false
#define CHECK_COND_RET_NULL(p) \
    if (!(p))                  \
    return NULL
#define CHECK_COND_RET_EMPTY_STRING(p) \
    if (!(p))                          \
    return wxEmptyString

#define CHECK_ITEM_RET(item) \
    if (!item.IsOk())        \
    return
#define CHECK_ITEM_RET_FALSE(item) \
    if (!item.IsOk())              \
    return false
#define CHECK_ITEM_RET_NULL(item) \
    if (!item.IsOk())             \
    return NULL
#define CHECK_ITEM_RET_EMPTY_STRING(item) \
    if (!item.IsOk())                     \
    return wxEmptyString

// PATH environment variable separator
#ifdef __WXMSW__
#define clPATH_SEPARATOR ";"
#else
#define clPATH_SEPARATOR ":"
#endif

// ----------------------------- useful typedefs -------------------------------
typedef std::unordered_map<wxString, bool> wxStringBoolMap_t;
typedef std::unordered_map<wxString, wxString> wxStringTable_t;
typedef std::unordered_set<wxString> wxStringSet_t;
typedef wxStringTable_t wxStringMap_t; // aliases

#endif // MACROS_H
