// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *
 * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
 *
 */

#include "layout/LETypes.h"
#include "layout/loengine.h"
#include "layout/plruns.h"

#include "unicode/locid.h"

#include "layout/LayoutEngine.h"
#include "layout/RunArrays.h"

U_NAMESPACE_USE

U_CAPI pl_fontRuns * U_EXPORT2
pl_openFontRuns(const le_font **fonts,
                const le_int32 *limits,
                le_int32 count)
{
    return (pl_fontRuns *) new FontRuns((const LEFontInstance **) fonts, limits, count);
}

U_CAPI pl_fontRuns * U_EXPORT2
pl_openEmptyFontRuns(le_int32 initialCapacity)
{
    return (pl_fontRuns *) new FontRuns(initialCapacity);
}

U_CAPI void U_EXPORT2
pl_closeFontRuns(pl_fontRuns *fontRuns)
{
    FontRuns *fr = (FontRuns *) fontRuns;

    delete fr;
}

U_CAPI le_int32 U_EXPORT2
pl_getFontRunCount(const pl_fontRuns *fontRuns)
{
    const FontRuns *fr = (const FontRuns *) fontRuns;

    if (fr == nullptr) {
        return -1;
    }

    return fr->getCount();
}

U_CAPI void U_EXPORT2
pl_resetFontRuns(pl_fontRuns *fontRuns)
{
    FontRuns *fr = (FontRuns *) fontRuns;

    if (fr != nullptr) {
        fr->reset();
    }
}

U_CAPI le_int32 U_EXPORT2
pl_getFontRunLastLimit(const pl_fontRuns *fontRuns)
{
    const FontRuns *fr = (const FontRuns *) fontRuns;

    if (fr == nullptr) {
        return -1;
    }

    return fr->getLimit();
}

U_CAPI le_int32 U_EXPORT2
pl_getFontRunLimit(const pl_fontRuns *fontRuns,
                   le_int32 run)
{
    const FontRuns *fr = (const FontRuns *) fontRuns;

    if (fr == nullptr) {
        return -1;
    }

    return fr->getLimit(run);
}

U_CAPI const le_font * U_EXPORT2
pl_getFontRunFont(const pl_fontRuns *fontRuns,
                    le_int32 run)
{
    const FontRuns *fr = (const FontRuns *) fontRuns;

    if (fr == nullptr) {
        return nullptr;
    }

    return (const le_font *) fr->getFont(run);
}

U_CAPI le_int32 U_EXPORT2
pl_addFontRun(pl_fontRuns *fontRuns,
              const le_font *font,
              le_int32 limit)
{
    FontRuns *fr = (FontRuns *) fontRuns;

    if (fr == nullptr) {
        return -1;
    }

    return fr->add((const LEFontInstance *) font, limit);
}

U_CAPI pl_valueRuns * U_EXPORT2
pl_openValueRuns(const le_int32 *values,
                 const le_int32 *limits,
                 le_int32 count)
{
    return (pl_valueRuns *) new ValueRuns(values, limits, count);
}

U_CAPI pl_valueRuns * U_EXPORT2
pl_openEmptyValueRuns(le_int32 initialCapacity)
{
    return (pl_valueRuns *) new ValueRuns(initialCapacity);
}

U_CAPI void U_EXPORT2
pl_closeValueRuns(pl_valueRuns *valueRuns)
{
    ValueRuns *vr = (ValueRuns *) valueRuns;

    delete vr;
}

U_CAPI le_int32 U_EXPORT2
pl_getValueRunCount(const pl_valueRuns *valueRuns)
{
    const ValueRuns *vr = (const ValueRuns *) valueRuns;

    if (vr == nullptr) {
        return -1;
    }

    return vr->getCount();
}

U_CAPI void U_EXPORT2
pl_resetValueRuns(pl_valueRuns *valueRuns)
{
    ValueRuns *vr = (ValueRuns *) valueRuns;

    if (vr != nullptr) {
        vr->reset();
    }
}

U_CAPI le_int32 U_EXPORT2
pl_getValueRunLastLimit(const pl_valueRuns *valueRuns)
{
    const ValueRuns *vr = (const ValueRuns *) valueRuns;

    if (vr == nullptr) {
        return -1;
    }

    return vr->getLimit();
}

U_CAPI le_int32 U_EXPORT2
pl_getValueRunLimit(const pl_valueRuns *valueRuns,
                    le_int32 run)
{
    const ValueRuns *vr = (const ValueRuns *) valueRuns;

    if (vr == nullptr) {
        return -1;
    }

    return vr->getLimit(run);
}

U_CAPI le_int32 U_EXPORT2
pl_getValueRunValue(const pl_valueRuns *valueRuns,
                     le_int32 run)
{
    const ValueRuns *vr = (const ValueRuns *) valueRuns;

    if (vr == nullptr) {
        return -1;
    }

    return vr->getValue(run);
}

U_CAPI le_int32 U_EXPORT2
pl_addValueRun(pl_valueRuns *valueRuns,
               le_int32 value,
               le_int32 limit)
{
    ValueRuns *vr = (ValueRuns *) valueRuns;

    if (vr == nullptr) {
        return -1;
    }

    return vr->add(value, limit);
}

U_NAMESPACE_BEGIN
class ULocRuns : public LocaleRuns
{
public:
    /**
     * Construct a <code>LocaleRuns</code> object from pre-existing arrays of locales
     * and limit indices.
     *
     * @param locales is the address of an array of locale name strings. This array,
     *                and the <code>Locale</code> objects to which it points, must remain valid until
     *                the <code>LocaleRuns</code> object is destroyed.
     *
     * @param limits is the address of an array of limit indices. This array must remain valid until the
     *               <code>LocaleRuns</code> object is destroyed.
     *
     * @param count is the number of entries in the two arrays.
     *
     * @draft ICU 3.8
     */
    ULocRuns(const char **locales, const le_int32 *limits, le_int32 count);

    /**
     * Construct an empty <code>LoIDRuns</code> object. Clients can add locale and limit
     * indices arrays using the <code>add</code> method.
     *
     * @param initialCapacity is the initial size of the locale and limit indices arrays. If
     *        this value is zero, no arrays will be allocated.
     *
     * @see add
     *
     * @draft ICU 3.8
     */
    ULocRuns(le_int32 initialCapacity);

    /**
     * The destructor; virtual so that subclass destructors are invoked as well.
     *
     * @draft ICU 3.8
     */
    virtual ~ULocRuns();

    /**
     * Get the name of the locale associated with the given run
     * of text. Use <code>RunArray::getLimit(run)</code> to get the corresponding
     * limit index.
     *
     * @param run is the index into the font and limit indices arrays.
     *
     * @return the locale name associated with the given text run.
     *
     * @see RunArray::getLimit
     *
     * @draft ICU 3.8
     */
    const char *getLocaleName(le_int32 run) const;

    /**
     * Add a <code>Locale</code> and limit index pair to the data arrays and return
     * the run index where the data was stored. This  method calls
     * <code>RunArray::add(limit)</code> which will create or grow the arrays as needed.
     *
     * If the <code>ULocRuns</code> object was created with a client-supplied
     * locale and limit indices arrays, this method will return a run index of -1.
     *
     * Subclasses should not override this method. Rather they should provide a new <code>add</code>
     * method which takes a locale name and a limit index along with whatever other data they implement.
     * The new <code>add</code> method should first call this method to grow the font and limit indices
     * arrays, and use the returned run index to store data their own arrays.
     *
     * @param locale is the name of the locale to add. This object must remain valid
     *               until the <code>ULocRuns</code> object is destroyed.
     *
     * @param limit is the limit index to add
     *
     * @return the run index where the locale and limit index were stored, or -1 if the data cannot be stored.
     *
     * @draft ICU 3.8
     */
    le_int32 add(const char *locale, le_int32 limit);

    /**
     * ICU "poor man's RTTI", returns a UClassID for this class.
     *
     * @draft ICU 3.8
     */
    static inline UClassID getStaticClassID();

    /**
     * ICU "poor man's RTTI", returns a UClassID for the actual class.
     *
     * @draft ICU 3.8
     */
    inline UClassID getDynamicClassID() const override;

protected:
    void init(le_int32 capacity) override;
    void grow(le_int32 capacity) override;

private:

    inline ULocRuns();
    inline ULocRuns(const ULocRuns &other);
    inline ULocRuns &operator=(const ULocRuns & /*other*/) { return *this; }
    const char **fLocaleNames;
};

inline ULocRuns::ULocRuns()
    : LocaleRuns(0), fLocaleNames(nullptr)
{
    // nothing else to do...
}

inline ULocRuns::ULocRuns(const ULocRuns & /*other*/)
    : LocaleRuns(0), fLocaleNames(nullptr)
{
    // nothing else to do...
}

static const Locale **getLocales(const char **localeNames, le_int32 count)
{
    Locale **locales = LE_NEW_ARRAY(Locale *, count);

    for (int i = 0; i < count; i += 1) {
        locales[i] = new Locale(Locale::createFromName(localeNames[i]));
    }

    return (const Locale **) locales;
}

ULocRuns::ULocRuns(const char **locales, const le_int32 *limits, le_int32 count)
    : LocaleRuns(getLocales(locales, count), limits, count), fLocaleNames(locales)
{
    // nothing else to do...
}

ULocRuns::ULocRuns(le_int32 initialCapacity)
    : LocaleRuns(initialCapacity), fLocaleNames(nullptr)
{
    if(initialCapacity > 0) {
        fLocaleNames = LE_NEW_ARRAY(const char *, initialCapacity);
    }
}

ULocRuns::~ULocRuns()
{
    le_int32 count = getCount();

    for(int i = 0; i < count; i += 1) {
        delete fLocales[i];
    }

    if (fClientArrays) {
        LE_DELETE_ARRAY(fLocales);
        fLocales = nullptr;
    } else {
        LE_DELETE_ARRAY(fLocaleNames);
        fLocaleNames = nullptr;
    }
}

void ULocRuns::init(le_int32 capacity)
{
    LocaleRuns::init(capacity);
    fLocaleNames = LE_NEW_ARRAY(const char *, capacity);
}

void ULocRuns::grow(le_int32 capacity)
{
    LocaleRuns::grow(capacity);
    fLocaleNames = static_cast<const char**>(LE_GROW_ARRAY(fLocaleNames, capacity));
}

le_int32 ULocRuns::add(const char *locale, le_int32 limit)
{
    Locale *loc = new Locale(Locale::createFromName(locale));
    le_int32 index = LocaleRuns::add(loc, limit);

    if (index >= 0) {
        char** localeNames = const_cast<char**>(fLocaleNames);

        localeNames[index] = const_cast<char*>(locale);
    }

    return index;
}

const char *ULocRuns::getLocaleName(le_int32 run) const
{
    if (run < 0 || run >= getCount()) {
        return nullptr;
    }

    return fLocaleNames[run];
}
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ULocRuns)
U_NAMESPACE_END

U_CAPI pl_localeRuns * U_EXPORT2
pl_openLocaleRuns(const char **locales,
                  const le_int32 *limits,
                  le_int32 count)
{
    return (pl_localeRuns *) new ULocRuns(locales, limits, count);
}

U_CAPI pl_localeRuns * U_EXPORT2
pl_openEmptyLocaleRuns(le_int32 initialCapacity)
{
    return (pl_localeRuns *) new ULocRuns(initialCapacity);
}

U_CAPI void U_EXPORT2
pl_closeLocaleRuns(pl_localeRuns *localeRuns)
{
    ULocRuns *lr = (ULocRuns *) localeRuns;

    delete lr;
}

U_CAPI le_int32 U_EXPORT2
pl_getLocaleRunCount(const pl_localeRuns *localeRuns)
{
    const ULocRuns *lr = (const ULocRuns *) localeRuns;

    if (lr == nullptr) {
        return -1;
    }

    return lr->getCount();
}

U_CAPI void U_EXPORT2
pl_resetLocaleRuns(pl_localeRuns *localeRuns)
{
    ULocRuns *lr = (ULocRuns *) localeRuns;

    if (lr != nullptr) {
        lr->reset();
    }
}

U_CAPI le_int32 U_EXPORT2
pl_getLocaleRunLastLimit(const pl_localeRuns *localeRuns)
{
    const ULocRuns *lr = (const ULocRuns *) localeRuns;

    if (lr == nullptr) {
        return -1;
    }

    return lr->getLimit();
}

U_CAPI le_int32 U_EXPORT2
pl_getLocaleRunLimit(const pl_localeRuns *localeRuns,
                     le_int32 run)
{
    const ULocRuns *lr = (const ULocRuns *) localeRuns;

    if (lr == nullptr) {
        return -1;
    }

    return lr->getLimit(run);
}

U_CAPI const char * U_EXPORT2
pl_getLocaleRunLocale(const pl_localeRuns *localeRuns,
                      le_int32 run)
{
    const ULocRuns *lr = (const ULocRuns *) localeRuns;

    if (lr == nullptr) {
        return nullptr;
    }

    return lr->getLocaleName(run);
}

U_CAPI le_int32 U_EXPORT2
pl_addLocaleRun(pl_localeRuns *localeRuns,
                const char *locale,
                le_int32 limit)
{
    ULocRuns *lr = (ULocRuns *) localeRuns;

    if (lr == nullptr) {
        return -1;
    }

    return lr->add(locale, limit);
}
