#include "Layout/ButtonMiiverse.h"

#include "Library/Controller/InputFunction.h"
#include "Library/Layout/LayoutActionFunction.h"
#include "Library/Layout/LayoutActorUtil.h"
#include "Library/Layout/LayoutInitInfo.h"
#include "Library/Nerve/NerveSetupUtil.h"
#include "Library/Nerve/NerveUtil.h"

namespace {
NERVE_IMPL(ButtonMiiverse, Wait);
NERVE_IMPL(ButtonMiiverse, Decide);
NERVE_IMPL(ButtonMiiverse, OnWait);
NERVE_IMPL(ButtonMiiverse, Disable);
NERVE_IMPL(ButtonMiiverse, HoldOn);
NERVE_IMPL(ButtonMiiverse, HoldOff);

NERVES_MAKE_STRUCT(ButtonMiiverse, Wait, Decide, OnWait, Disable, HoldOn, HoldOff);
}  // namespace

ButtonMiiverse::ButtonMiiverse() : al::LayoutActor("Miiverseボタン") {}

void ButtonMiiverse::init(const al::LayoutInitInfo& info) {
    al::initLayoutActor(this, info, "ButtonMiiverse");
    initNerve(&NrvButtonMiiverse.Wait);
    appear();
}

bool ButtonMiiverse::isOn() const {
    return al::isNerve(this, &NrvButtonMiiverse.Decide) ||
           al::isNerve(this, &NrvButtonMiiverse.OnWait);
}

void ButtonMiiverse::setOff() {
    al::setNerve(this, &NrvButtonMiiverse.Wait);
}

void ButtonMiiverse::validate() {
    if (al::isNerve(this, &NrvButtonMiiverse.Disable))
        setOff();
}

void ButtonMiiverse::forceValidate() {
    setOff();
}

void ButtonMiiverse::invalidate() {
    if (!al::isNerve(this, &NrvButtonMiiverse.Disable))
        al::setNerve(this, &NrvButtonMiiverse.Disable);
}

void ButtonMiiverse::exeWait() {
    if (al::isFirstStep(this))
        al::startAction(this, "Wait");
    if (al::isHoldTouchPane(this, "Hit"))
        al::setNerve(this, &NrvButtonMiiverse.HoldOn);
}

void ButtonMiiverse::exeHoldOn() {
    if (al::isFirstStep(this))
        al::startAction(this, "Touch");
    if (al::isReleaseTouchPane(this, "Hit"))
        al::setNerve(this, &NrvButtonMiiverse.Decide);
    else if (!al::isTouchPosInPane(this, "Hit"))
        al::setNerve(this, &NrvButtonMiiverse.HoldOff);
}

void ButtonMiiverse::exeHoldOff() {
    if (al::isFirstStep(this))
        al::startAction(this, "Wait");
    if (al::isTouchPosInPane(this, "Hit"))
        al::setNerve(this, &NrvButtonMiiverse.HoldOn);
    else if (al::isPadReleaseTouch())
        setOff();
}

void ButtonMiiverse::exeDecide() {
    if (al::isFirstStep(this))
        al::startAction(this, "Decide");
    al::setNerveAtActionEnd(this, &NrvButtonMiiverse.OnWait);
}

void ButtonMiiverse::exeOnWait() {
    if (al::isFirstStep(this))
        al::startAction(this, "Wait");
}

void ButtonMiiverse::exeDisable() {
    if (al::isFirstStep(this))
        al::startAction(this, "Disable");
}
