#ifndef __ARRAY_LIST_H__
#define __ARRAY_LIST_H__

#include "mzstdCommon.h"
#include "mzObject.h"
#include "mzString.h"

namespace mzstd {

class DECLSPEC_MZSTD CmzArrayList : public CmzObject {
public:
    WINAPI CmzArrayList(ULONG capacity = 100);
    virtual WINAPI ~CmzArrayList();

    VOID WINAPI append(LONG data);
    inline VOID WINAPI push(LONG data) { this->append(data); };
    VOID WINAPI addAsFirst(LONG data);
    VOID WINAPI insert(ULONG pos, LONG data);
    ULONG WINAPI del(LONG data);
    BOOL WINAPI delFirst(LONG data);
    BOOL WINAPI delAt(ULONG pos);
    LONG WINAPI pos(LONG data);
    BOOL WINAPI contains(LONG data);
    LONG WINAPI getMinValue();
    LONG WINAPI getMaxValue();
    // Bubble-sort (default in ascending order)
    VOID WINAPI sort(BOOL asc = TRUE);
    VOID WINAPI insertRandomValues(ULONG count, ULONG minValue, ULONG maxValue);
    // Makes all values are set randomed
    VOID WINAPI randomizeAll();
    VOID WINAPI randomizeAll(ULONG minValue, ULONG maxValue);
    // as methods: randomizeAll() and randomizeAll(ULONG minValue, ULONG maxValue) but first
    // makes this->_size = this->_capacity
    VOID WINAPI randomizeAllCapacity();
    VOID WINAPI randomizeAllCapacity(ULONG minValue, ULONG maxValue);
    // Finds min value that is greater than the this->getMinValue() and is not in the array
    LONG WINAPI getFirstAvailableValue();
    inline LONG WINAPI getAt(ULONG pos) { if (pos < this->_size) return this->_items[pos]; return 0; };
    VOID WINAPI setAt(ULONG pos, LONG data);
    inline LONG WINAPI getFirst() { if (this->_size > 0) return this->_items[0]; return 0; };
    inline LONG WINAPI getLast() { if (this->_size > 0) return this->_items[this->_size - 1]; return 0; };
    inline LONG WINAPI pop() {
        LONG retval;
        if (this->_size < 1) { return 0; }
        retval = this->getAt(this->_size - 1);
        this->delAt(this->_size - 1);
        return retval;
    }
    inline ULONG WINAPI size() { return this->_size; };
    inline ULONG WINAPI capacity() { return this->_capacity; };
    virtual VOID WINAPI clear();
    inline LONG* WINAPI getItemsBuf() { return this->_items; }

    CmzArrayList* WINAPI clone();
    virtual CmzString WINAPI toString();

protected:
    LONG* _items;
    ULONG _size;
    ULONG _capacity;

    LONG* WINAPI _createNullArray(ULONG capacity);
};

}

#endif
