/*
*******************************************************************************
* Copyright (C) 1999, International Business Machines Corporation and         *
* others. All Rights Reserved.                                                *
*******************************************************************************
*   Date        Name        Description
*   10/22/99    alan        Creation.
**********************************************************************
*/

#include "uvector.h"
#include "cmemory.h"

UBool UVector::outOfMemory = FALSE;

UVector::UVector(int32_t initialCapacity) :
    count(0),
    capacity(0),
    elements(0),
    deleter(0),
    comparer(0) {

    _init(initialCapacity);
}

UVector::UVector(Deleter d, Comparer c, int32_t initialCapacity) :
    count(0),
    capacity(0),
    elements(0),
    deleter(d),
    comparer(c) {
   
    _init(initialCapacity);
}

void UVector::_init(int32_t initialCapacity) {
    elements = new void*[initialCapacity];
    if (elements == 0) {
        outOfMemory = TRUE;
    } else {
        capacity = initialCapacity;
    }
}

UVector::~UVector() {
    removeAllElements();
    delete[] elements;
    elements = 0;
}

void UVector::addElement(void* obj) {
    if (ensureCapacity(count + 1)) {
        elements[count++] = obj;
    }
}

void UVector::setElementAt(void* obj, int32_t index) {
    if (0 <= index && index < count) {
        if (elements[index] != 0 && deleter != 0) {
            (*deleter)(elements[index]);
        }
        elements[index] = obj;
    }
    /* else index out of range */
}

void UVector::insertElementAt(void* obj, int32_t index) {
    // must have 0 <= index <= count
    if (0 <= index && index <= count && ensureCapacity(count + 1)) {
        for (int32_t i=count; i>index; --i) {
            elements[i] = elements[i-1];
        }
        elements[index] = obj;
    }
    /* else index out of range */
}

void* UVector::elementAt(int32_t index) const {
    return (0 <= index && index < count) ? elements[index] : 0;
}

void UVector::removeElementAt(int32_t index) {
    void* e = orphanElementAt(index);
    if (e != 0 && deleter != 0) {
        (*deleter)(e);
    }
}

UBool UVector::removeElement(void* obj) {
    int32_t i = indexOf(obj);
    if (i >= 0) {
        removeElementAt(i);
        return TRUE;
    }
    return FALSE;
}

void UVector::removeAllElements(void) {
    if (deleter != 0) {
        for (int32_t i=0; i<count; ++i) {
            if (elements[i] != 0) {
                (*deleter)(elements[i]);
            }
        }
    }
    count = 0;
}

int32_t UVector::indexOf(void* obj, int32_t startIndex) const {
    if (comparer != 0) {
        for (int32_t i=startIndex; i<count; ++i) {
            if ((*comparer)(obj, elements[i])) {
                return i;
            }
        }
    }
    return -1;
}

UBool UVector::ensureCapacity(int32_t minimumCapacity) {
    if (capacity >= minimumCapacity) {
        return TRUE;
    } else {
        int32_t newCap = capacity * 2;
        void** newElems = new void*[newCap];
        if (newElems == 0) {
            outOfMemory = TRUE;
            return FALSE;
        }
        uprv_memcpy(newElems, elements, sizeof(void*) * count);
        delete[] elements;
        elements = newElems;
        capacity = newCap;
        return TRUE;
    }
}

UVector::Deleter UVector::setDeleter(Deleter d) {
    Deleter old = deleter;
    deleter = d;
    return old;
}

UVector::Comparer UVector::setComparer(Comparer d) {
    Comparer old = comparer;
    comparer = d;
    return old;
}

UBool UVector::isOutOfMemory(void) {
    return outOfMemory;
}

/**
 * Removes the element at the given index from this vector and
 * transfer ownership of it to the caller.  After this call, the
 * caller owns the result and must delete it and the vector entry
 * at 'index' is removed, shifting all subsequent entries back by
 * one index and shortening the size of the vector by one.  If the
 * index is out of range or if there is no item at the given index
 * then 0 is returned and the vector is unchanged.
 */
void* UVector::orphanElementAt(int32_t index) {
    void* e = 0;
    if (0 <= index && index < count) {
        e = elements[index];
        for (int32_t i=index; i<count-1; ++i) {
            elements[i] = elements[i+1];
        }
        --count;
    }
    /* else index out of range */
    return e;
}

UStack::UStack(int32_t initialCapacity) :
    UVector(initialCapacity) {
}

UStack::UStack(Deleter d, Comparer c, int32_t initialCapacity) :
    UVector(d, c, initialCapacity) {
}

void* UStack::pop(void) {
    void* obj = lastElement();
    if (obj != 0) {
        removeElementAt(size() - 1);
    }
    return obj;
}

int32_t UStack::search(void* obj) const {
    int32_t i = indexOf(obj);
    return (i >= 0) ? size() - i : i;
}
