/*
 * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "DeprecatedValueListImpl.h"

#include "Shared.h"
#include <stdlib.h>

namespace WebCore {

class DeprecatedValueListImpl::Private : public Shared<DeprecatedValueListImpl::Private>
{
public:
    Private(void (*deleteFunc)(DeprecatedValueListImplNode *), DeprecatedValueListImplNode *(*copyFunc)(DeprecatedValueListImplNode *));
    Private(const Private &other);

    ~Private();

    void copyList(DeprecatedValueListImplNode *l, DeprecatedValueListImplNode *&head, DeprecatedValueListImplNode *&tail) const;
    void deleteList(DeprecatedValueListImplNode *l);

    DeprecatedValueListImplNode *head;
    DeprecatedValueListImplNode *tail;

    void (*deleteNode)(DeprecatedValueListImplNode *);
    DeprecatedValueListImplNode *(*copyNode)(DeprecatedValueListImplNode *);
    unsigned count;
};

inline DeprecatedValueListImpl::Private::Private(void (*deleteFunc)(DeprecatedValueListImplNode*),
        DeprecatedValueListImplNode* (*copyFunc)(DeprecatedValueListImplNode*)) : 
    head(NULL),
    tail(NULL),
    deleteNode(deleteFunc),
    copyNode(copyFunc),
    count(0)
{
}

inline DeprecatedValueListImpl::Private::Private(const Private &other) :
    Shared<DeprecatedValueListImpl::Private>(),
    deleteNode(other.deleteNode),
    copyNode(other.copyNode),
    count(other.count)
{
    other.copyList(other.head, head, tail);
}

inline DeprecatedValueListImpl::Private::~Private()
{
    deleteList(head);
}

void DeprecatedValueListImpl::Private::copyList(DeprecatedValueListImplNode *l, DeprecatedValueListImplNode *&head, DeprecatedValueListImplNode *&tail) const
{
    DeprecatedValueListImplNode *prev = NULL;
    DeprecatedValueListImplNode *node = l;

    head = NULL;

    while (node != NULL) {
        DeprecatedValueListImplNode *copy = copyNode(node);
        if (prev == NULL) {
            head = copy;
        } else {
            prev->next = copy;
        }

        copy->prev = prev;
        copy->next = NULL;

        prev = copy;
        node = node->next;
    }

    tail = prev;
}

void DeprecatedValueListImpl::Private::deleteList(DeprecatedValueListImplNode *l)
{
    DeprecatedValueListImplNode *p = l;
    
    while (p != NULL) {
        DeprecatedValueListImplNode *next = p->next;
        deleteNode(p);
        p = next;
    }
}

DeprecatedValueListImpl::DeprecatedValueListImpl(void (*deleteFunc)(DeprecatedValueListImplNode *), DeprecatedValueListImplNode *(*copyFunc)(DeprecatedValueListImplNode *)) :
    d(new Private(deleteFunc, copyFunc))
{
}

DeprecatedValueListImpl::DeprecatedValueListImpl(const DeprecatedValueListImpl &other) :
    d(other.d)
{
}

DeprecatedValueListImpl::~DeprecatedValueListImpl()
{
}

void DeprecatedValueListImpl::clear()
{
    if (d->head) {
        copyOnWrite();
        d->deleteList(d->head);
        d->head = NULL;
        d->tail = NULL;
        d->count = 0;
    }
}

unsigned DeprecatedValueListImpl::count() const
{
    return d->count;
}

bool DeprecatedValueListImpl::isEmpty() const
{
    return d->count == 0;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::appendNode(DeprecatedValueListImplNode *node)
{
    copyOnWrite();

    node->next = NULL;
    node->prev = d->tail;
    d->tail = node;
    
    if (d->head == NULL) {
        d->head = node;
    } else {
        node->prev->next = node;
    }

    d->count++;
    
    return node;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::prependNode(DeprecatedValueListImplNode *node)
{
    copyOnWrite();

    node->next = d->head;
    node->prev = NULL;
    d->head = node;

    if (d->tail == NULL) {
        d->tail = node;
    } else {
        node->next->prev = node;
    }

    d->count++;
    
    return node;
}

void DeprecatedValueListImpl::removeEqualNodes(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *))
{
    copyOnWrite();

    DeprecatedValueListImplNode *next;
    for (DeprecatedValueListImplNode *p = d->head; p != NULL; p = next) {
        next = p->next;
        if (equalFunc(node, p)) {
            if (p->next != NULL) {
                p->next->prev = p->prev;
            } else {
                d->tail = p->prev;
            }

            if (p->prev != NULL) {
                p->prev->next = p->next;
            } else {
                d->head = p->next;
            }

            d->deleteNode(p);

            d->count--;
        }
    }
}

unsigned DeprecatedValueListImpl::containsEqualNodes(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const
{
    unsigned contains = 0;

    for (DeprecatedValueListImplNode *p = d->head; p != NULL; p = p->next) {
        if (equalFunc(node, p)) {
            ++contains;
        }
    }
    
    return contains;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::findEqualNode(DeprecatedValueListImplNode *node, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const
{
    DeprecatedValueListImplIterator it = begin();
    DeprecatedValueListImplIterator endIt = end();
    while (it != endIt) {
        if (equalFunc(node, it.node())) {
            break;
        }
        it++;
    }
    return it;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::insert(const DeprecatedValueListImplIterator &iterator, DeprecatedValueListImplNode *node)
{
    copyOnWrite();
    
    DeprecatedValueListImplNode *next = iterator.nodeImpl;
    
    if (next == NULL)
        return appendNode(node);
    
    if (next == d->head)
        return prependNode(node);
    
    DeprecatedValueListImplNode *prev = next->prev;
    
    node->next = next;
    node->prev = prev;
    next->prev = node;
    prev->next = node;
    
    d->count++;
    
    return node;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::removeIterator(DeprecatedValueListImplIterator &iterator)
{
    copyOnWrite();

    if (iterator.nodeImpl == NULL) {
        return iterator;
    }

    DeprecatedValueListImplNode *next = iterator.nodeImpl->next;

    // detach node
    if (iterator.nodeImpl->next != NULL) {
        iterator.nodeImpl->next->prev = iterator.nodeImpl->prev;
    } else {
        d->tail = iterator.nodeImpl->prev;
    }
    if (iterator.nodeImpl->prev != NULL) {
        iterator.nodeImpl->prev->next = iterator.nodeImpl->next;
    } else {
        d->head = iterator.nodeImpl->next;
    }
    
    d->deleteNode(iterator.nodeImpl);
    d->count--;

    return DeprecatedValueListImplIterator(next);
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::fromLast()
{
    copyOnWrite();
    return DeprecatedValueListImplIterator(lastNode());
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::firstNode()
{
    copyOnWrite();
    return ((const DeprecatedValueListImpl *)this)->firstNode();
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::lastNode()
{
    copyOnWrite();
    return ((const DeprecatedValueListImpl *)this)->lastNode();
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::firstNode() const
{
    return d->head;
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::lastNode() const
{
    return d->tail;
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::begin()
{
    copyOnWrite();
    return ((const DeprecatedValueListImpl *)this)->begin();
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::end()
{
    copyOnWrite();
    return ((const DeprecatedValueListImpl *)this)->end();
}


DeprecatedValueListImplIterator DeprecatedValueListImpl::begin() const
{
    return DeprecatedValueListImplIterator(firstNode());
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::end() const
{
    return DeprecatedValueListImplIterator(NULL);
}

DeprecatedValueListImplIterator DeprecatedValueListImpl::fromLast() const
{
    return DeprecatedValueListImplIterator(lastNode());
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::nodeAt(unsigned index)
{
    copyOnWrite();

    if (d->count <= index) {
        return NULL;
    }

    DeprecatedValueListImplNode *p = d->head;

    for (unsigned i = 0; i < index; i++) {
        p = p->next;
    }

    return p;
}

DeprecatedValueListImplNode *DeprecatedValueListImpl::nodeAt(unsigned index) const
{
    if (d->count <= index) {
        return NULL;
    }

    DeprecatedValueListImplNode *p = d->head;

    for (unsigned i = 0; i < index; i++) {
        p = p->next;
    }

    return p;
}

DeprecatedValueListImpl& DeprecatedValueListImpl::operator=(const DeprecatedValueListImpl &other)
{
    DeprecatedValueListImpl tmp(other);
    RefPtr<Private> tmpD = tmp.d;

    tmp.d = d;
    d = tmpD;

    return *this;
}

void DeprecatedValueListImpl::copyOnWrite()
{
    if (!d->hasOneRef())
        d = new Private(*d);
}

bool DeprecatedValueListImpl::isEqual(const DeprecatedValueListImpl &other, bool (*equalFunc)(const DeprecatedValueListImplNode *, const DeprecatedValueListImplNode *)) const
{
    DeprecatedValueListImplNode *p, *q;
    for (p = d->head, q = other.d->head; p && q; p = p->next, q = q->next) {
        if (!equalFunc(p, q)) {
            return false;
        }
    }
    return !p && !q;
}

}
