//
// Generated by dtk
// Translation Unit: JSUList.cpp
//

#include "JSystem/JSystem.h" // IWYU pragma: keep

#include "JSystem/JSupport/JSUList.h"

/* 802BEFE4-802BEFFC       .text __ct__10JSUPtrLinkFPv */
JSUPtrLink::JSUPtrLink(void* object) {
    mList = NULL;
    mObject = object;
    mPrev = NULL;
    mNext = NULL;
}

/* 802BEFFC-802BF05C       .text __dt__10JSUPtrLinkFv */
JSUPtrLink::~JSUPtrLink() {
    if (mList != NULL) {
        mList->remove(this);
    }
}

/* 802BF05C-802BF094       .text __ct__10JSUPtrListFb */
JSUPtrList::JSUPtrList(bool init) {
    if (init) {
        initiate();
    }
}

/* 802BF094-802BF0FC       .text __dt__10JSUPtrListFv */
JSUPtrList::~JSUPtrList() {
    JSUPtrLink* node = mHead;
    s32 removed = 0;
    while (mLength > removed) {
        node->mList = NULL;
        node = node->getNext();
        removed += 1;
    }
}

/* 802BF0FC-802BF110       .text initiate__10JSUPtrListFv */
void JSUPtrList::initiate() {
    mHead = NULL;
    mTail = NULL;
    mLength = 0;
}

/* 802BF110-802BF134       .text setFirst__10JSUPtrListFP10JSUPtrLink */
void JSUPtrList::setFirst(JSUPtrLink* first) {
    first->mList = this;
    first->mPrev = NULL;
    first->mNext = NULL;
    mTail = first;
    mHead = first;
    mLength = 1;
}

/* 802BF134-802BF1D8       .text append__10JSUPtrListFP10JSUPtrLink */
bool JSUPtrList::append(JSUPtrLink* ptr) {
    JSUPtrList* list = ptr->mList;
    bool result = (NULL == list);
    if (!result) {
        result = list->remove(ptr);
    }

    if (result) {
        if (mLength == 0) {
            setFirst(ptr);
        } else {
            ptr->mList = this;
            ptr->mPrev = mTail;
            ptr->mNext = NULL;
            mTail->mNext = ptr;
            mTail = ptr;
            mLength++;
        }
    }

    return result;
}

/* 802BF1D8-802BF27C       .text prepend__10JSUPtrListFP10JSUPtrLink */
bool JSUPtrList::prepend(JSUPtrLink* ptr) {
    JSUPtrList* list = ptr->mList;
    bool result = (NULL == list);
    if (!result) {
        result = list->remove(ptr);
    }

    if (result) {
        if (mLength == 0) {
            setFirst(ptr);
        } else {
            ptr->mList = this;
            ptr->mPrev = NULL;
            ptr->mNext = mHead;
            mHead->mPrev = ptr;
            mHead = ptr;
            mLength++;
        }
    }

    return result;
}

/* 802BF27C-802BF344       .text insert__10JSUPtrListFP10JSUPtrLinkP10JSUPtrLink */
bool JSUPtrList::insert(JSUPtrLink* before, JSUPtrLink* ptr) {
    if (before == mHead) {
        return prepend(ptr);
    } else if (before == NULL) {
        return append(ptr);
    }

    if (before->mList != this) {
        return false;
    }

    bool result = (NULL == ptr->mList);
    if (!result) {
        result = ptr->mList->remove(ptr);
    }

    if (result) {
        JSUPtrLink* prev = before->mPrev;
        ptr->mList = this;
        ptr->mPrev = prev;
        ptr->mNext = before;
        prev->mNext = ptr;
        before->mPrev = ptr;
        mLength++;
    }

    return result;
}

/* 802BF344-802BF3F4       .text remove__10JSUPtrListFP10JSUPtrLink */
bool JSUPtrList::remove(JSUPtrLink* ptr) {
    bool is_parent = (ptr->mList == this);
    if (is_parent) {
        if (mLength == 1) {
            mHead = NULL;
            mTail = NULL;
        } else if (ptr == mHead) {
            ptr->mNext->mPrev = NULL;
            mHead = ptr->mNext;
        } else if (ptr == mTail) {
            ptr->mPrev->mNext = NULL;
            mTail = ptr->mPrev;
        } else {
            ptr->mPrev->mNext = ptr->mNext;
            ptr->mNext->mPrev = ptr->mPrev;
        }

        ptr->mList = NULL;
        mLength--;
    }

    return is_parent;
}
