#include "jp/ggaf/core/actor/GgafActor.h"

#include "jp/ggaf/core/actor/ex/GgafFormation.h"

using namespace GgafCore;

GgafActor::GgafActor(const char* prm_name, GgafStatus* prm_pStat) :
    GgafElement<GgafActor>(prm_name),
    _pScene_platform(nullptr),
    _pDependenceDepository(nullptr),
    _pFormation(nullptr),
    _can_hit_flg(false),
    _can_hit_out_of_view(true),
    _pStatus(prm_pStat)
{
    _class_name = "GgafActor";
    _obj_class = Obj_GgafActor;
    if (_pStatus == nullptr) {
        _pStatus = NEW GgafStatus(12);
        getStatus()->set(0, 0);
    }
    _TRACE_("new "<<_class_name<<"("<<this<<")["<<prm_name<<"] _id="<<getId());
}

GgafActor::~GgafActor() {
    _pFormation = nullptr;
    GGAF_DELETE(_pStatus);
    _TRACE_("delete "<<_class_name<<"("<<this<<")["<<getName()<<"] _id="<<getId());
    //OutputDebugStringA("*");
}

void GgafActor::setPlatformScene(GgafScene* prm_pScene_platform) {
    _pScene_platform = prm_pScene_platform;
    GgafActor* pActor_tmp = _pSubFirst;
    while (pActor_tmp) {
        pActor_tmp->setPlatformScene(prm_pScene_platform);
        if (pActor_tmp->_is_last_flg) {
            break;
        } else {
            pActor_tmp = pActor_tmp->_pNext;
        }
    }
}

void GgafActor::setHitAble(bool prm_can_hit_flg, bool prm_can_hit_out_of_view_flg) {
    _can_hit_flg = prm_can_hit_flg;
    _can_hit_out_of_view = prm_can_hit_out_of_view_flg;
}

void GgafActor::setHitAble(bool prm_can_hit_flg) {
    _can_hit_flg = prm_can_hit_flg;
}

void GgafActor::setHitAbleTree(bool prm_can_hit_flg, bool prm_can_hit_out_of_view_flg) {
    _can_hit_flg = prm_can_hit_flg;
    _can_hit_out_of_view = prm_can_hit_out_of_view_flg;
    GgafActor* pActor_tmp = _pSubFirst;
    while (pActor_tmp) {
        pActor_tmp->setHitAble(prm_can_hit_flg, prm_can_hit_out_of_view_flg);
        if (pActor_tmp->_is_last_flg) {
            break;
        } else {
            pActor_tmp = pActor_tmp->_pNext;
        }
    }
}

void GgafActor::setHitAbleTree(bool prm_can_hit_flg) {
    _can_hit_flg = prm_can_hit_flg;
    GgafActor* pActor_tmp = _pSubFirst;
    while (pActor_tmp) {
        pActor_tmp->setHitAble(prm_can_hit_flg);
        if (pActor_tmp->_is_last_flg) {
            break;
        } else {
            pActor_tmp = pActor_tmp->_pNext;
        }
    }
}

GgafScene* GgafActor::getPlatformScene() {
    if (_pScene_platform == nullptr) {
        if (getParent()) {
            _pScene_platform = getParent()->getPlatformScene();
        } else {
            _pScene_platform = nullptr;
        }
    }
    return _pScene_platform;
}

void GgafActor::sayonara(frame prm_offset_frames) {
    if (_pDependenceDepository) {
        inactivateDelay(prm_offset_frames);
    } else {
        end(prm_offset_frames);
    }
    GgafActor* pActor = _pSubFirst;
    while (pActor) {
        pActor->sayonara(prm_offset_frames);
        if (pActor->_is_last_flg) {
            break;
        } else {
            pActor = pActor->_pNext;
        }
    }
}

GgafActor* GgafActor::extract() {
    GgafActor* pActor = GgafElement<GgafActor>::extract();
    pActor->setPlatformScene(nullptr); //強懏僔乕儞儕僙僢僩
    return pActor;
}

void GgafActor::notifyDestroyedToFormation() {
    if (_pFormation) {
        _pFormation->destroyedFollower(this);
    }
}

GgafFormation* GgafActor::getFormation() {
    return _pFormation;
}

void GgafActor::dump() {
    _TRACE_("\t\t\t\t\t\t\t\t"<<_class_name<<"("<<this<<")["<<getName()<<"]"<<DUMP_FLGS);

    GgafActor* pActor_tmp = _pSubFirst;
    while (pActor_tmp) {
        pActor_tmp->dump("\t\t\t\t\t\t\t\t乥");
        if (pActor_tmp->_pNext) {
            pActor_tmp = pActor_tmp->_pNext;
        } else {
            _TRACE_("亂寈崘亃"<<_class_name<<"("<<this<<")["<<getName()<<"]偺next偑nullptr偭偰偄傑偡");
            break;
        }
        if (pActor_tmp->_is_first_flg) {
            _TRACE_("\t\t\t\t\t\t\t\t劋劅");
            break;
        }
    }
}

void GgafActor::dump(std::string prm_parent) {
    _TRACE_(prm_parent << _class_name<<"("<<this<<")["<<getName()<<"]"<<DUMP_FLGS);
    GgafActor* pActor_tmp = _pSubFirst;
    while (pActor_tmp) {
        pActor_tmp->dump(prm_parent + "乥");
        if (pActor_tmp->_pNext) {
            pActor_tmp = pActor_tmp->_pNext;
        } else {
            _TRACE_("亂寈崘亃"<<_class_name<<"("<<this<<")["<<getName()<<"]偺next偑nullptr偭偰偄傑偡");
            break;
        }
        if (pActor_tmp->_is_first_flg) {
            _TRACE_(prm_parent+"劋劅");
            break;
        }
    }
}

