#include "ChatCommand.h"

#include "Game.h"
#include "Player.h"

ChatCommand::ChatCommand(
    Framework::Text name, Framework::Text description, int securityLevel)
    : Framework::ReferenceCounter(),
      name(name),
      description(description),
      securityLevel(securityLevel)
{}

void ChatCommand::addParam(ChatCommandParameter* param)
{
    params.add(param);
}

const Framework::RCArray<ChatCommandParameter>& ChatCommand::getParams() const
{
    return params;
}

Framework::Text ChatCommand::getName() const
{
    return name;
}

Framework::Text ChatCommand::getHelp() const
{
    Framework::Text result = "/";
    result += name;

    for (ChatCommandParameter* param : params)
    {
        result += " ";
        if (param->isOptional()) result += "[";
        result += param->getName();
        if (param->isOptional()) result += "]";
    }
    if (description.getLength() > 0)
    {
        result.append() << "\n    " << description;
    }
    for (ChatCommandParameter* param : params)
    {
        if (param->getDescription().getLength() > 0)
        {
            result += "\n    ";
            if (param->isOptional()) result += "[";
            result += param->getName();
            if (param->isOptional()) result += "]";
            result.append() << " - " << param->getDescription();
        }
    }
    return result;
}

int ChatCommand::getSecurityLevel(
    Framework::RCArray<Framework::Text> params) const
{
    return securityLevel;
}

ChatCommandParameter::ChatCommandParameter(
    Framework::Text name, Framework::Text description, bool optional)
    : ReferenceCounter(),
      name(name),
      description(description),
      optional(optional)
{}

bool ChatCommandParameter::isLegalValue(Framework::Text value) const
{
    return 1;
}

Framework::Text ChatCommandParameter::getDefaultValue(Entity* zActor) const
{
    return "";
}

Framework::Text ChatCommandParameter::getName() const
{
    return name;
}

Framework::Text ChatCommandParameter::getDescription() const
{
    return description;
}

bool ChatCommandParameter::isOptional() const
{
    return optional;
}

PlayerNameParameter::PlayerNameParameter()
    : ChatCommandParameter(
        "player", "The name of the player (has to be online)", 0)
{}

bool PlayerNameParameter::isLegalValue(Framework::Text value) const
{
    return Game::INSTANCE->zPlayerByName(value) != 0;
}

Framework::Text PlayerNameParameter::getDefaultValue(Entity* zActor) const
{
    Player* p = dynamic_cast<Player*>(zActor);
    if (p) return p->getName();
    return "";
}

IntegerParameter::IntegerParameter(Framework::Text name,
    Framework::Text description,
    bool optional,
    std::function<int(Entity* zEntity)> calculateDefault)
    : ChatCommandParameter(name, description, optional),
      calculateDefault(calculateDefault)
{}

bool IntegerParameter::isLegalValue(Framework::Text value) const
{
    return Text((int)value).istGleich(value);
}

Framework::Text IntegerParameter::getDefaultValue(Entity* zActor) const
{
    return Text(calculateDefault(zActor));
}