// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/fxcrt/fx_basic.h"
#include "plex.h"
CFX_PtrList::CFX_PtrList(int nBlockSize, IFX_Allocator* pAllocator)
    : m_pAllocator(pAllocator)
    , m_pNodeHead(NULL)
    , m_pNodeTail(NULL)
    , m_nCount(0)
    , m_pNodeFree(NULL)
    , m_pBlocks(NULL)
    , m_nBlockSize(nBlockSize)
{
}
FX_POSITION CFX_PtrList::AddTail(void* newElement)
{
    CNode* pNewNode = NewNode(m_pNodeTail, NULL);
    pNewNode->data = newElement;
    if (m_pNodeTail != NULL) {
        m_pNodeTail->pNext = pNewNode;
    } else {
        m_pNodeHead = pNewNode;
    }
    m_pNodeTail = pNewNode;
    return (FX_POSITION) pNewNode;
}
FX_POSITION CFX_PtrList::AddHead(void* newElement)
{
    CNode* pNewNode = NewNode(NULL, m_pNodeHead);
    pNewNode->data = newElement;
    if (m_pNodeHead != NULL) {
        m_pNodeHead->pPrev = pNewNode;
    } else {
        m_pNodeTail = pNewNode;
    }
    m_pNodeHead = pNewNode;
    return (FX_POSITION) pNewNode;
}
FX_POSITION CFX_PtrList::InsertAfter(FX_POSITION position, void* newElement)
{
    if (position == NULL) {
        return AddTail(newElement);
    }
    CNode* pOldNode = (CNode*) position;
    CNode* pNewNode = NewNode(pOldNode, pOldNode->pNext);
    pNewNode->data = newElement;
    if (pOldNode->pNext != NULL) {
        pOldNode->pNext->pPrev = pNewNode;
    } else {
        m_pNodeTail = pNewNode;
    }
    pOldNode->pNext = pNewNode;
    return (FX_POSITION) pNewNode;
}
void CFX_PtrList::RemoveAt(FX_POSITION position)
{
    CNode* pOldNode = (CNode*) position;
    if (pOldNode == m_pNodeHead) {
        m_pNodeHead = pOldNode->pNext;
    } else {
        pOldNode->pPrev->pNext = pOldNode->pNext;
    }
    if (pOldNode == m_pNodeTail) {
        m_pNodeTail = pOldNode->pPrev;
    } else {
        pOldNode->pNext->pPrev = pOldNode->pPrev;
    }
    FreeNode(pOldNode);
}
void CFX_PtrList::FreeNode(CFX_PtrList::CNode* pNode)
{
    pNode->pNext = m_pNodeFree;
    m_pNodeFree = pNode;
    m_nCount--;
    if (m_nCount == 0) {
        RemoveAll();
    }
}
void CFX_PtrList::RemoveAll()
{
    m_nCount = 0;
    m_pNodeHead = m_pNodeTail = m_pNodeFree = NULL;
    m_pBlocks->FreeDataChain(m_pAllocator);
    m_pBlocks = NULL;
}
CFX_PtrList::CNode*
CFX_PtrList::NewNode(CFX_PtrList::CNode* pPrev, CFX_PtrList::CNode* pNext)
{
    if (m_pNodeFree == NULL) {
        CFX_Plex* pNewBlock = CFX_Plex::Create(m_pAllocator, m_pBlocks, m_nBlockSize, sizeof(CNode));
        CNode* pNode = (CNode*)pNewBlock->data();
        pNode += m_nBlockSize - 1;
        for (int i = m_nBlockSize - 1; i >= 0; i--, pNode--) {
            pNode->pNext = m_pNodeFree;
            m_pNodeFree = pNode;
        }
    }
    ASSERT(m_pNodeFree != NULL);
    CFX_PtrList::CNode* pNode = m_pNodeFree;
    m_pNodeFree = m_pNodeFree->pNext;
    pNode->pPrev = pPrev;
    pNode->pNext = pNext;
    m_nCount++;
    ASSERT(m_nCount > 0);
    pNode->data = 0;
    return pNode;
}
CFX_PtrList::~CFX_PtrList()
{
    RemoveAll();
    ASSERT(m_nCount == 0);
}
FX_POSITION CFX_PtrList::FindIndex(int nIndex) const
{
    if (nIndex >= m_nCount || nIndex < 0) {
        return NULL;
    }
    CNode* pNode = m_pNodeHead;
    while (nIndex--) {
        pNode = pNode->pNext;
    }
    return (FX_POSITION) pNode;
}
FX_POSITION CFX_PtrList::Find(void* searchValue, FX_POSITION startAfter) const
{
    CNode* pNode = (CNode*) startAfter;
    if (pNode == NULL) {
        pNode = m_pNodeHead;
    } else {
        pNode = pNode->pNext;
    }
    for (; pNode != NULL; pNode = pNode->pNext)
        if (pNode->data == searchValue) {
            return (FX_POSITION) pNode;
        }
    return NULL;
}
