#include "Actor.h"

u_long Actor::Id() const
{
    if (const auto id = this->lsObject->GetMember("ID"); id.has_value())
    {
        return id->Int64;
    }
    return {};
}

std::string Actor::Name() const
{
    if (!this->lsObject->IsValid())
    {
        return "Invalid Actor";
    }

    if (const auto name = this->lsObject->GetMember("Name"); name.has_value())
    {
        return name->CharPtr;
    }
    return {};
}

std::string Actor::LastName() const
{
    if (const auto lastName = this->lsObject->GetMember("LastName"); lastName.has_value())
    {
        return lastName->CharPtr;
    }
    return {};
}

int Actor::HealthPercentage() const
{
    if (const auto healthPercentage = this->lsObject->GetMember("Health"); healthPercentage.has_value())
    {
        return healthPercentage->Int;
    }
    return {};
}

int Actor::PowerPercentage() const
{
    if (const auto powerPercentage = this->lsObject->GetMember("Power"); powerPercentage.has_value())
    {
        return powerPercentage->Int;
    }
    return {};
}

int Actor::Level() const
{
    if (const auto level = this->lsObject->GetMember("Level"); level.has_value())
    {
        return level->Int;
    }
    return {};
}

int Actor::EffectiveLevel() const
{
    if (const auto effectiveLevel = this->lsObject->GetMember("EffectiveLevel"); effectiveLevel.has_value())
    {
        return effectiveLevel->Int;
    }
    return {};
}

u_int Actor::TintFlags() const
{
    if (const auto tintFlags = this->lsObject->GetMember("TintFlags"); tintFlags.has_value())
    {
        return tintFlags->Int;
    }
    return {};
}

std::string Actor::VisualVariant() const
{
    if (const auto visualVariant = this->lsObject->GetMember("VisualVariant"); visualVariant.has_value())
    {
        return visualVariant->CharPtr;
    }
    return {};
}

std::string Actor::Mood() const
{
    if (const auto mood = this->lsObject->GetMember("Mood"); mood.has_value())
    {
        return mood->CharPtr;
    }
    return {};
}

std::string Actor::CurrentAnimation() const
{
    if (const auto currentAnimation = this->lsObject->GetMember("CurrentAnimation"); currentAnimation.has_value())
    {
        return currentAnimation->CharPtr;
    }
    return {};
}

std::string Actor::Overlay() const
{
    if (const auto overlay = this->lsObject->GetMember("Overlay"); overlay.has_value())
    {
        return overlay->CharPtr;
    }
    return {};
}

std::string Actor::Aura() const
{
    if (const auto aura = this->lsObject->GetMember("Aura"); aura.has_value())
    {
        return aura->CharPtr;
    }
    return {};
}

std::string Actor::Guild() const
{
    if (const auto guild = this->lsObject->GetMember("Guild"); guild.has_value())
    {
        return guild->CharPtr;
    }
    return {};
}

std::string Actor::Type() const
{
    if (const auto type = this->lsObject->GetMember("Type"); type.has_value())
    {
        return type->CharPtr;
    }
    return {};
}

std::string Actor::SuffixTitle() const
{
    if (const auto suffixTitle = this->lsObject->GetMember("SuffixTitle"); suffixTitle.has_value())
    {
        return suffixTitle->CharPtr;
    }
    return {};
}

std::string Actor::ConColor() const
{
    if (const auto conColor = this->lsObject->GetMember("ConColor"); conColor.has_value())
    {
        return conColor->CharPtr;
    }
    return {};
}

std::string Actor::RawConColor() const
{
    // TODO: Modify to accept a parameter & pass in the string 'raw'
    if (const auto rawConColor = this->lsObject->GetMember("RawConColor"); rawConColor.has_value())
    {
        return rawConColor->CharPtr;
    }
    return {};
}

std::string Actor::FactionStanding() const
{
    if (const auto factionStanding = this->lsObject->GetMember("FactionStanding"); factionStanding.has_value())
    {
        return factionStanding->CharPtr;
    }
    return {};
}

int Actor::Faction() const
{
    if (const auto faction = this->lsObject->GetMember("Faction"); faction.has_value())
    {
        return faction->Int;
    }
    return {};
}

Actor Actor::Target() const
{
    if (const auto target = this->lsObject->GetMember("Target"); target.has_value())
    {
        return Actor(make_shared<LSObject>(LSObject(target.value())));
    }
    return Actor(make_shared<LSObject>(nullopt));
}

Actor Actor::Pet() const
{
    if (const auto pet = this->lsObject->GetMember("Pet"); pet.has_value())
    {
        return Actor(make_shared<LSObject>(LSObject(pet.value())));
    }
    return Actor(make_shared<LSObject>(nullopt));
}

int Actor::ThreatToPet() const
{
    if (const auto threatToPet = this->lsObject->GetMember("ThreatToPet"); threatToPet.has_value())
    {
        return threatToPet->Int;
    }
    return {};
}

int Actor::ThreatToMe() const
{
    if (const auto threatToMe = this->lsObject->GetMember("ThreatToMe"); threatToMe.has_value())
    {
        return threatToMe->Int;
    }
    return {};
}

int Actor::ThreatToNext() const
{
    if (const auto threatToNext = this->lsObject->GetMember("ThreatToNext"); threatToNext.has_value())
    {
        return threatToNext->Int;
    }
    return {};
}

float Actor::Distance() const
{
    if (const auto distance = this->lsObject->GetMember("Distance"); distance.has_value())
    {
        return distance->Float;
    }
    return {};
}

float Actor::Distance2d() const
{
    if (const auto distance2d = this->lsObject->GetMember("Distance2D"); distance2d.has_value())
    {
        return distance2d->Float;
    }
    return {};
}

float Actor::X() const
{
    if (const auto x = this->lsObject->GetMember("X"); x.has_value())
    {
        return x->Float;
    }
    return {};
}

float Actor::Y() const
{
    if (const auto y = this->lsObject->GetMember("Y"); y.has_value())
    {
        return y->Float;
    }
    return {};
}

float Actor::Z() const
{
    if (const auto z = this->lsObject->GetMember("Z"); z.has_value())
    {
        return z->Float;
    }
    return {};
}

std::string Actor::Race() const
{
    if (const auto race = this->lsObject->GetMember("Race"); race.has_value())
    {
        return race->CharPtr;
    }
    return {};
}

std::string Actor::Class() const
{
    if (const auto cls = this->lsObject->GetMember("Class"); cls.has_value())
    {
        return cls->CharPtr;
    }
    return {};
}

std::string Actor::Gender() const
{
    if (const auto gender = this->lsObject->GetMember("Gender"); gender.has_value())
    {
        return gender->CharPtr;
    }
    return {};
}

Point3f Actor::Location() const
{
    if (const auto location = this->lsObject->GetMember("Location"); location.has_value())
    {
        return Point3f(make_shared<LSObject>(LSObject(location.value())));
    }
    return Point3f(make_shared<LSObject>(nullopt));
}

float Actor::Heading() const
{
    if (const auto heading = this->lsObject->GetMember("Heading"); heading.has_value())
    {
        return heading->Float;
    }
    return {};
}

string Actor::HeadingToAsString() const
{
    if (const auto headingTo = this->lsObject->GetMember("HeadingTo"); headingTo.has_value())
    {
        return headingTo->CharPtr;
    }
    return {};
}

Point3f Actor::Velocity() const
{
    if (const auto velocity = this->lsObject->GetMember("Velocity"); velocity.has_value())
    {
        return Point3f(make_shared<LSObject>(LSObject(velocity.value())));
    }
    return Point3f(make_shared<LSObject>(LSObject(nullopt)));
}

bool Actor::CheckCollision() const
{
    if (const auto checkCollision = this->lsObject->GetMember("CheckCollision"); checkCollision.has_value())
    {
        return checkCollision->Int;
    }
    return false;
}

bool Actor::CheckCollision(const float toX, const float toY, const float toZ) const
{
    if (const auto checkCollision = this->lsObject->GetMember("CheckCollision", toX, toY, toZ); checkCollision.has_value())
    {
        return checkCollision->Int;
    }
    return {};
}

float Actor::TargetRingRadius() const
{
    if (const auto targetRingRadius = this->lsObject->GetMember("TargetRingRadius"); targetRingRadius.has_value())
    {
        return targetRingRadius->Float;
    }
    return {};
}

float Actor::CollisionRadius() const
{
    if (const auto collisionRadius = this->lsObject->GetMember("CollisionRadius"); collisionRadius.has_value())
    {
        return collisionRadius->Float;
    }
    return {};
}

float Actor::CollisionScale() const
{
    if (const auto collisionScale = this->lsObject->GetMember("CollisionScale"); collisionScale.has_value())
    {
        return collisionScale->Float;
    }
    return {};
}

u_long Actor::WhoFollowingId() const
{
    if (const auto whoFollowingId = this->lsObject->GetMember("WhoFollowing"); whoFollowingId.has_value())
    {
        return whoFollowingId->Int64;
    }
    return {};
}

string Actor::WhoFollowingName() const
{
    if (const auto whoFollowingName = this->lsObject->GetMember("WhoFollowing"); whoFollowingName.has_value())
    {
        return whoFollowingName->CharPtr;
    }
    return {};
}

float Actor::Speed() const
{
    if (const auto speed = this->lsObject->GetMember("Speed"); speed.has_value())
    {
        return speed->Float;
    }
    return {};
}

float Actor::SwimmingSpeedModifier() const
{
    if (const auto swimmingSpeedModifier = this->lsObject->GetMember("SwimmingSpeedMod"); swimmingSpeedModifier.has_value())
    {
        return swimmingSpeedModifier->Float;
    }
    return {};
}

bool Actor::InMyGroup() const
{
    if (const auto inMyGroup = this->lsObject->GetMember("InMyGroup"); inMyGroup.has_value())
    {
        return inMyGroup->Int;
    }
    return false;
}

bool Actor::Interactable() const
{
    if (const auto interactable = this->lsObject->GetMember("Interactable"); interactable.has_value())
    {
        return interactable->Int;
    }
    return false;
}

bool Actor::OnFlyingMount() const
{
    if (const auto onFlyingMount = this->lsObject->GetMember("OnFlyingMount"); onFlyingMount.has_value())
    {
        return onFlyingMount->Int;
    }
    return false;
}

bool Actor::FlyingUsingMount() const
{
    if (const auto flyingUsingMount = this->lsObject->GetMember("FlyingUsingMount"); flyingUsingMount.has_value())
    {
        return flyingUsingMount->Int;
    }
    return false;
}

bool Actor::IsChest() const
{
    if (const auto isChest = this->lsObject->GetMember("IsChest"); isChest.has_value())
    {
        return isChest->Int;
    }
    return false;
}

bool Actor::IsBanker() const
{
    if (const auto isBanker = this->lsObject->GetMember("IsBanker"); isBanker.has_value())
    {
        return isBanker->Int;
    }
    return false;
}

bool Actor::IsMerchant() const
{
    if (const auto isMerchant = this->lsObject->GetMember("IsMerchant"); isMerchant.has_value())
    {
        return isMerchant->Int;
    }
    return false;
}

bool Actor::IsAPet() const
{
    if (const auto isAPet = this->lsObject->GetMember("IsAPet"); isAPet.has_value())
    {
        return isAPet->Int;
    }
    return false;
}

bool Actor::IsMyPet() const
{
    if (const auto isMyPet = this->lsObject->GetMember("IsMyPet"); isMyPet.has_value())
    {
        return isMyPet->Int;
    }
    return false;
}

bool Actor::IsAfk() const
{
    if (const auto isAfk = this->lsObject->GetMember("IsAFK"); isAfk.has_value())
    {
        return isAfk->Int;
    }
    return false;
}

bool Actor::IsLfw() const
{
    if (const auto isLfw = this->lsObject->GetMember("IsLFW"); isLfw.has_value())
    {
        return isLfw->Int;
    }
    return false;
}

bool Actor::IsLfg() const
{
    if (const auto isLfg = this->lsObject->GetMember("IsLFG"); isLfg.has_value())
    {
        return isLfg->Int;
    }
    return false;
}

bool Actor::IsLinkdead() const
{
    if (const auto isLinkdead = this->lsObject->GetMember("IsLinkdead"); isLinkdead.has_value())
    {
        return isLinkdead->Int;
    }
    return false;
}

bool Actor::IsCamping() const
{
    if (const auto isCamping = this->lsObject->GetMember("IsCamping"); isCamping.has_value())
    {
        return isCamping->Int;
    }

    return false;
}

bool Actor::IsLocked() const
{
    if (const auto isLocked = this->lsObject->GetMember("IsLocked"); isLocked.has_value())
    {
        return isLocked->Int;
    }
    return false;
}

bool Actor::IsAggro() const
{
    if (const auto isAggro = this->lsObject->GetMember("IsAggro"); isAggro.has_value())
    {
        return isAggro->Int;
    }
    return false;
}

bool Actor::IsSolo() const
{
    if (const auto isSolo = this->lsObject->GetMember("IsSolo"); isSolo.has_value())
    {
        return isSolo->Int;
    }
    return false;
}

bool Actor::IsHeroic() const
{
    if (const auto isHeroic = this->lsObject->GetMember("IsHeroic"); isHeroic.has_value())
    {
        return isHeroic->Int;
    }
    return false;
}

bool Actor::IsEpic() const
{
    if (const auto isEpic = this->lsObject->GetMember("IsEpic"); isEpic.has_value())
    {
        return isEpic->Int;
    }
    return false;
}

bool Actor::IsNamed() const
{
    if (const auto isNamed = this->lsObject->GetMember("IsNamed"); isNamed.has_value())
    {
        return isNamed->Int;
    }
    return false;
}

bool Actor::IsSwimming() const
{
    if (const auto isSwimming = this->lsObject->GetMember("IsSwimming"); isSwimming.has_value())
    {
        return isSwimming->Int;
    }
    return false;
}

bool Actor::IsEncounterBroken() const
{
    if (const auto isEncounterBroken = this->lsObject->GetMember("IsEncounterBroken"); isEncounterBroken.has_value())
    {
        isEncounterBroken->Int;
    }
    return false;
}

bool Actor::IsInvisible() const
{
    if (const auto isInvisible = this->lsObject->GetMember("IsInvisible"); isInvisible.has_value())
    {
        return isInvisible->Int;
    }
    return false;
}

bool Actor::IsClimbing() const
{
    if (const auto isClimbing = this->lsObject->GetMember("IsClimbing"); isClimbing.has_value())
    {
        return isClimbing->Int;
    }
    return false;
}

bool Actor::IsJumping() const
{
    if (const auto isJumping = this->lsObject->GetMember("IsJumping"); isJumping.has_value())
    {
        return isJumping->Int;
    }
    return false;
}

bool Actor::IsFalling() const
{
    if (const auto isFalling = this->lsObject->GetMember("IsFalling"); isFalling.has_value())
    {
        return isFalling->Int;
    }
    return false;
}

bool Actor::IsFD() const
{
    if (const auto isFD = this->lsObject->GetMember("IsFD"); isFD.has_value())
    {
        return isFD->Int;
    }
    return false;
}

bool Actor::IsDead() const
{
    if (const auto isDead = this->lsObject->GetMember("IsDead"); isDead.has_value())
    {
        return isDead->Int;
    }
    return false;
}

bool Actor::IsRooted() const
{
    if (const auto isRooted = this->lsObject->GetMember("IsRooted"); isRooted.has_value())
    {
        return isRooted->Int;
    }
    return false;
}

bool Actor::CanTurn() const
{
    if (const auto canTurn = this->lsObject->GetMember("CanTurn"); canTurn.has_value())
    {
        return canTurn->Int;
    }
    return false;
}

bool Actor::InCombatMode() const
{
    if (const auto inCombatMode = this->lsObject->GetMember("InCombatMode"); inCombatMode.has_value())
    {
        return inCombatMode->Int;
    }
    return false;
}

bool Actor::IsCrouching() const
{
    if (const auto isCrouching = this->lsObject->GetMember("IsCrouching"); isCrouching.has_value())
    {
        return isCrouching->Int;
    }
    return false;
}

bool Actor::IsSitting() const
{
    if (const auto isSitting = this->lsObject->GetMember("IsSitting"); isSitting.has_value())
    {
        return isSitting->Int;
    }
    return false;
}

bool Actor::OnCarpet() const
{
    if (const auto onCarpet = this->lsObject->GetMember("OnCarpet"); onCarpet.has_value())
    {
        return onCarpet->Int;
    }
    return false;
}

bool Actor::OnHorse() const
{
    if (const auto onHorse = this->lsObject->GetMember("OnHorse"); onHorse.has_value())
    {
        return onHorse->Int;
    }
    return false;
}

bool Actor::ONGriphon() const
{
    if (const auto onGriphon = this->lsObject->GetMember("OnGriphon"); onGriphon.has_value())
    {
        return onGriphon->Int;
    }
    return false;
}

bool Actor::IsRunning() const
{
    if (const auto isRunning = this->lsObject->GetMember("IsRunning"); isRunning.has_value())
    {
        return isRunning->Int;
    }
    return false;
}

bool Actor::IsWalking() const
{
    if (const auto isWalking = this->lsObject->GetMember("IsWalking"); isWalking.has_value())
    {
        return isWalking->Int;
    }
    return false;
}

bool Actor::IsSprinting() const
{
    if (const auto isSprinting = this->lsObject->GetMember("IsSprinting"); isSprinting.has_value())
    {
        return isSprinting->Int;
    }
    return false;
}

bool Actor::IsBackingUp() const
{
    if (const auto isBackingUp = this->lsObject->GetMember("IsBackingUp"); isBackingUp.has_value())
    {
        return isBackingUp->Int;
    }
    return false;
}

bool Actor::IsStrafingLeft() const
{
    if (const auto isStrafingLeft = this->lsObject->GetMember("IsStrafingLeft"); isStrafingLeft.has_value())
    {
        return isStrafingLeft->Int;
    }
    return false;
}

bool Actor::IsStrafingRight() const
{
    if (const auto isStrafingRight = this->lsObject->GetMember("IsStrafingRight"); isStrafingRight.has_value())
    {
        return isStrafingRight->Int;
    }
    return false;
}

bool Actor::IsIdle() const
{
    if (const auto isIdle = this->lsObject->GetMember("IsIdle"); isIdle.has_value())
    {
        return isIdle->Int;
    }
    return false;
}

int Actor::EncounterSize() const
{
    if (const auto encounterSize = this->lsObject->GetMember("EncounterSize"); encounterSize.has_value())
    {
        return encounterSize->Int;
    }
    return {};
}

int Actor::Difficulty() const
{
    if (const auto difficulty = this->lsObject->GetMember("Difficulty"); difficulty.has_value())
    {
        return difficulty->Int;
    }
    return {};
}

int Actor::IsInSameEncounter(const u_long id) const
{
    if (const auto isInSameEncounter = this->lsObject->GetMember("IsInSameEncounter", id); isInSameEncounter.has_value())
    {
        return isInSameEncounter->Int;
    }
    return {};
}

int Actor::RaidSize() const
{
    if (const auto raidSize = this->lsObject->GetMember("RaidSize"); raidSize.has_value())
    {
        return raidSize->Int;
    }
    return {};
}

string Actor::TagTargetNumber() const
{
    if (const auto tagTargetNumber = this->lsObject->GetMember("TagTargetNumber"); tagTargetNumber.has_value())
    {
        return tagTargetNumber->CharPtr;
    }
    return {};
}

string Actor::TagTargetIcon() const
{
    if (const auto tagTargetIcon = this->lsObject->GetMember("TagTargetIcon"); tagTargetIcon.has_value())
    {
        return tagTargetIcon->CharPtr;
    }
    return {};
}

int Actor::EffectCount() const
{
    if (const auto effectCount = this->lsObject->GetMember("EffectCount"); effectCount.has_value())
    {
        return effectCount->Int;
    }
    return {};
}

void Actor::DoubleClick() const
{
    this->lsObject->CallMethod("DoubleClick");
}

void Actor::WaypointTo() const
{
    this->lsObject->CallMethod("WaypointTo");
}

void Actor::DoFace() const
{
    this->lsObject->CallMethod("DoFace");
}

void Actor::DoTarget() const
{
    this->lsObject->CallMethod("DoTarget");
}

void Actor::AddLocation(const string &notes) const
{
    this->lsObject->CallMethod("Location", "Add", notes);
}

void Actor::DeleteLocation() const
{
    this->lsObject->CallMethod("Location", "Delete");
}

void Actor::RequesteffectsInfo() const
{
    this->lsObject->CallMethod("RequesteffectsInfo");
}
