#include "Character.h"

std::string Character::Archetype() const {
    const auto res = this->lsObject->GetMember("Archetype");
    return res.has_value()
               ? res->CharPtr
               : string();
}

std::string Character::SubClass() const {
    const auto res = this->lsObject->GetMember("SubClass");
    return res.has_value()
               ? res->CharPtr
               : string();
}

std::string Character::TradeskillArchtype() const {
    const auto res = this->lsObject->GetMember("TSArchetype");
    return res.has_value()
               ? res->CharPtr
               : string();
}

std::string Character::TradeskillClass() const {
    const auto res = this->lsObject->GetMember("TSClass");
    return res.has_value()
               ? res->CharPtr
               : string();
}

std::string Character::TradeskillSubClass() const {
    const auto res = this->lsObject->GetMember("TSSubClass");
    return res.has_value()
               ? res->CharPtr
               : string();
}

Actor Character::CursorActor() const {
    return Actor(make_shared<LSObject>(LSObject(this->lsObject->GetMember("CursorActor"))));
}

bool Character::IsMoving() const {
    const auto res = this->lsObject->GetMember("IsMoving");
    return res.has_value()
               ? res->Int
               : false;
}

bool Character::InGameWorld() const {
    const auto res = this->lsObject->GetMember("InGameWorld");
    return res.has_value()
               ? res->Int
               : false;
}

bool Character::AtCharSelect() const {
    const auto res = this->lsObject->GetMember("AtCharSelect");
    return res.has_value()
               ? res->Int
               : false;
}

float Character::WaterDepth() const {
    const auto res = this->lsObject->GetMember("WaterDepth");
    return res.has_value()
               ? res->Float
               : false;
}

float Character::HeadingTo(const float toX, const float toY, const float toZ) const {
    const auto res = this->lsObject->GetMember("HeadingTo", toX, toY, toZ);
    return res.has_value() ? res->Float : 0.0f;
}

string Character::HeadingToAsString(const float toX, const float toY, const float toZ) const {
    const auto res = this->lsObject->GetMember("HeadingTo", toX, toY, toZ, "AsString");
    return res.has_value() ? res->CharPtr : string();
}

int Character::VeteranBonus() const {
    const auto res = this->lsObject->GetMember("VeteranBonus");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::Level() const {
    const auto res = this->lsObject->GetMember("Level");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::EffectiveLevel() const {
    const auto res = this->lsObject->GetMember("EffectiveLevel");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::TradeskillLevel() const {
    const auto res = this->lsObject->GetMember("TSLevel");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::APExperience() const {
    const auto res = this->lsObject->GetMember("APExp");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::TotalEarnedAPs() const {
    const auto res = this->lsObject->GetMember("TotalEarnedAPs");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::MaxAPs() const {
    const auto res = this->lsObject->GetMember("MaxAPs");
    return res.has_value()
               ? res->Int
               : 0;
}

u_long Character::Copper() const {
    const auto res = this->lsObject->GetMember("Copper");
    return res.has_value()
               ? res->Int64
               : 0;
}

u_long Character::Silver() const {
    const auto res = this->lsObject->GetMember("Silver");
    return res.has_value()
               ? res->Int64
               : 0;
}

u_long Character::Gold() const {
    const auto res = this->lsObject->GetMember("Gold");
    return res.has_value()
               ? res->Int64
               : 0;
}

u_long Character::Platinum() const {
    const auto res = this->lsObject->GetMember("Platinum");
    return res.has_value()
               ? res->Int64
               : 0;
}

bool Character::IsGroupLeader() const {
    const auto res = this->lsObject->GetMember("IsGroupLeader");
    return res.has_value()
               ? res->Int
               : 0;
}

bool Character::Grouped() const {
    const auto res = this->lsObject->GetMember("Grouped");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::GroupCount() const {
    const auto res = this->lsObject->GetMember("GroupCount");
    return res.has_value()
               ? res->Int
               : 0;
}

GroupMember Character::GroupMemberByIndex(const int index) const {
    if (index <= 0 || index >= 7) {
        throw std::invalid_argument("index must be between 1 and 6");
    }
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", index))));
}

GroupMember Character::GroupMemberByName(const string &name) const {
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", name))));
}

GroupMember Character::GroupMemberById(const u_long id) const {
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("GroupMember", "id", id))));
}

int Character::RaidCount() const {
    const auto res = this->lsObject->GetMember("RaidCount");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::RaidGroupNumber() const {
    const auto res = this->lsObject->GetMember("RaidGroupNumber");
    return res.has_value()
               ? res->Int
               : 0;
}

int Character::Raid() const {
    const auto res = this->lsObject->GetMember("Raid");
    return res.has_value()
               ? res->Int
               : 0;
}

GroupMember Character::RaidMemberByIndex(const int index) const {
    if (index <= 0 || index >= 25) {
        throw std::invalid_argument("index must be between 1 and 24");
    }

    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", index))));
}

GroupMember Character::RaidMemberByName(const string &name) const {
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", name))));
}

GroupMember Character::RaidMemberById(const u_long id) const {
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", "id", id))));
}

GroupMember Character::RaidMemberByGroupAndIndex(const int group, const int index) const {
    if (group <= 0 || group >= 5) {
        throw std::invalid_argument("group must be between 1 and 4");
    }

    if (index <= 0 || index >= 7) {
        throw std::invalid_argument("index must be between 1 and 6");
    }
    return GroupMember(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Raid", group, index))));
}

int Character::NumAbilities() const {
    const auto res = this->lsObject->GetMember("NumAbilities");
    return res.has_value()
               ? res->Int
               : 0;
}

Ability Character::Ability(const int index) const {
    return Ability::Ability(make_shared<LSObject>(LSObject(this->lsObject->GetMember("Ability", index))));
}




