#include "ControlActionText.h"

#include <QCoreApplication>
#include <QKeySequence>

namespace
{

// tr() for a file of free functions. Q_DECLARE_TR_FUNCTIONS expands with access
// specifiers, so it needs a class rather than a namespace; this struct exists only to
// carry it and give the strings a single lupdate context.
struct Strings
{
    Q_DECLARE_TR_FUNCTIONS(ControlActionText)
};

QString getMouseBadge(MouseBinding binding)
{
    switch (binding)
    {
    case MouseBinding::LeftClick:     return Strings::tr("LMB");
    case MouseBinding::LeftDrag:      return Strings::tr("LMB drag");
    case MouseBinding::CtrlLeftClick: return Strings::tr("Ctrl+LMB");
    case MouseBinding::CtrlLeftDrag:  return Strings::tr("Ctrl+LMB drag");
    case MouseBinding::RightClick:    return Strings::tr("RMB");
    }
    return QString();
}

}  // namespace

QString getControlBindingBadge(const ControlBinding& binding)
{
    if (binding.isMouse) { return getMouseBadge(binding.mouse); }

    // QKeySequence spells the modifiers and the key together and localizes them, which
    // is what makes this stay correct once keys are rebindable: the chip is generated
    // from the binding rather than typed next to it.
    return QKeySequence(binding.key | static_cast<int>(binding.modifiers))
        .toString(QKeySequence::NativeText);
}

QString getControlActionLabel(ControlAction action, const ControlContext& context)
{
    switch (action)
    {
    case ControlAction::None:               return QString();
    case ControlAction::Move:               return Strings::tr("Move");
    case ControlAction::GameSpeed:          return Strings::tr("Game speed");
    case ControlAction::TogglePause:        return Strings::tr("Toggle pause");
    case ControlAction::PasteTemporary:     return Strings::tr("Paste last");
    case ControlAction::OpenBlueprints:     return Strings::tr("Blueprints");
    case ControlAction::OpenMenu:           return Strings::tr("Menu");
    // A click on empty space clears and a click on an object replaces; naming only the
    // first would be a half-truth once something is selected.
    case ControlAction::Select:
        return context.selection == ControlSelection::None
                   ? Strings::tr("Select")
                   : Strings::tr("Select / clear selection");
    case ControlAction::SelectArea:         return Strings::tr("Select area");
    case ControlAction::AddToSelection:     return Strings::tr("Add / remove from selection");
    case ControlAction::AddAreaToSelection: return Strings::tr("Add area to selection");
    case ControlAction::EnterDeconstruct:   return Strings::tr("Deconstruct mode");
    case ControlAction::CopyTemporary:      return Strings::tr("Copy to temporary blueprint");
    case ControlAction::CreateBlueprint:    return Strings::tr("Create blueprint");
    case ControlAction::ClearSelection:     return Strings::tr("Clear selection");
    case ControlAction::Place:              return Strings::tr("Place");
    case ControlAction::ApplySettings:      return Strings::tr("Apply settings");
    case ControlAction::PlaceBeltLine:      return Strings::tr("Place belt line");
    case ControlAction::Rotate:             return Strings::tr("Rotate");
    case ControlAction::CancelBeltLine:     return Strings::tr("Cancel belt line");
    case ControlAction::ExitMode:
        return context.mode == BuildMode::Deconstruct
                   ? Strings::tr("Exit deconstruct mode")
                   : Strings::tr("Exit placement");
    case ControlAction::ToggleDeconstruct:  return Strings::tr("Toggle deconstruct");
    case ControlAction::DeconstructArea:    return Strings::tr("Deconstruct area");
    }
    return QString();
}

QString getControlContextName(ControlContextKind kind)
{
    switch (kind)
    {
    case ControlContextKind::General:     return Strings::tr("GENERAL");
    case ControlContextKind::Selection:   return Strings::tr("SELECTION");
    case ControlContextKind::Build:       return Strings::tr("BUILD MODE");
    case ControlContextKind::Blueprint:   return Strings::tr("BLUEPRINT MODE");
    case ControlContextKind::Deconstruct: return Strings::tr("DECONSTRUCT MODE");
    }
    return QString();
}
