//--------------------------------------------------------------------------------------------------
// Copyright (c) id3 Technologies
// All Rights Reserved.
//--------------------------------------------------------------------------------------------------
#pragma once
#include <id3BiosealCppWrapper/id3BiosealException.hpp>
#include <id3Bioseal/id3BiosealStringArray.h>

namespace id3BiosealCppWrapper
{

/**
 * Represents an array of strings.
 */
class StringArray
{
private:
    ID3_BIOSEAL_STRING_ARRAY handle_{};

public:
    StringArray() {
        check_error(id3BiosealStringArray_Initialize(&handle_));
    }

    virtual ~StringArray() {
        if (handle_) {
            id3BiosealStringArray_Dispose(&handle_);
        }
    }


    StringArray(StringArray &&src) noexcept: handle_(src.handle_) {
        src.handle_ = nullptr;
    }

    ID3_BIOSEAL_STRING_ARRAY getHandle() const { return handle_; }
    operator ID3_BIOSEAL_STRING_ARRAY () const { return handle_; }

    // --- Iterator Support ---
    class iterator {
    private:
        StringArray *list_;
        int index_;
    public:
        iterator(StringArray *list, int index) : list_(list), index_(index) {}

        std::string operator*() const
        { return list_->get(index_); }

        iterator &operator++() {
            ++index_;
            return *this;
        }

        bool operator!=(const iterator &src) const
        { return index_ != src.index_; }
    };

    iterator begin()
    { return iterator(this, 0); }

    iterator end()
    { return iterator(this, getCount()); }

    // public getters and setters
    // public methods
    /**
    * Gets an item of the StringArray object.
    * @param index [in] Index of the  item to get.
    * @param item [out]  item to get.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval  item to get.
    */
    void get(int index, std::string & item) {
        int itemSize = -1;
        auto err = id3BiosealStringArray_Get(handle_, index, item.data(), &itemSize);
        if (err == (int)id3BiosealError_InsufficientBuffer) {
            item.resize(itemSize);
            err = id3BiosealStringArray_Get(handle_, index, item.data(), &itemSize);
            if (err == 0) { item.resize(itemSize); }
        }
        check_error(err);
    }

    /**
    * Gets an item of the StringArray object.
    * @param index [in] Index of the  item to get.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval  item to get.
    */
    std::string get(int index) {
        std::string item;
        get(index, item);
        return item;
    }

    /**
    * Gets the number of elements in the StringArray object.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval Number of elements in the  object.
    */
    int getCount() {
        int count;
        check_error(id3BiosealStringArray_GetCount(handle_, &count));
        return count;
    }

    /**
    * Returns a value indicating whether a specified string occurs in this string array.
    * @param item [in] The string to seek.
    * @exception BiosealException An error has occured during Bioseal library execution.
    * @retval true if the item parameter occurs within this string array; otherwise, false.
    */
    bool contains(const char *item) {
        bool result;
        check_error(id3BiosealStringArray_Contains(handle_, item, &result));
        return result;
    }

};
};