/*
**********************************************************************
*   Copyright (C) 1999, International Business Machines
*   Corporation and others.  All Rights Reserved.
**********************************************************************
*   Date        Name        Description
*   11/17/99    aliu        Creation.
**********************************************************************
*/
#include "unirange.h"
#include "uvector.h"
#include "unicode/unistr.h"

U_NAMESPACE_BEGIN

UnicodeRange::UnicodeRange(UChar theStart, int32_t theLength) {
    start = theStart;
    length = theLength;
}

UnicodeRange* UnicodeRange::clone() const {
    return new UnicodeRange(start, length);
}

/**
 * CALLER OWNS RESULT.
 */
UBool UnicodeRange::contains(UChar c) const {
    return c >= start && (c - start) < length;
}

/**
 * Assume that contains(c) is true.  Split this range into two new
 * ranges around the character c.  Make this range one of the new ranges
 * (modify it in place) and return the other new range.  The character
 * itself is not included in either range.  If the split results in an
 * empty range (that is, if c == start or c == start + length - 1) then
 * return null.
 *
 * MODIFIES THIS RANGE IN PLACE.
 *
 * CALLER OWNS RESULT.
 */
UnicodeRange* UnicodeRange::split(UChar c) {
    if (c == start) {
        ++start;
        --length;
        return 0;
    } else if (c - start == length - 1) {
        --length;
        return 0;
    } else {
        ++c;
        UnicodeRange* r = new UnicodeRange(c, start + length - c);
        length = --c - start;
        return r;
    }
}

/**
 * Finds the largest unused subrange by the given string.  A
 * subrange is unused by a string if the string contains no
 * characters in that range.  If the given string contains no
 * characters in this range, then this range itself is
 * returned.
 *
 * CALLER OWNS RESULT.
 */
UnicodeRange*
UnicodeRange::largestUnusedSubrange(const UnicodeString& str, UErrorCode &status) const {
    int32_t n = str.length();

    UVector v(status);
    if (U_FAILURE(status)) {
        return NULL;
    }
    v.setDeleter(UnicodeRange::deleter);
    v.addElement(clone(), status);
    for (int32_t i=0; i<n; ++i) {
        UChar c = str.charAt(i);
        if (contains(c)) {
            for (int32_t j=0; j<v.size(); ++j) {
                UnicodeRange* r = (UnicodeRange*) v.elementAt(j);
                if (r->contains(c)) {
                    r = r->split(c);
                    if (r != 0) {
                        v.addElement(r, status);
                    }
                    break;
                }
            }
        }
    }

    UnicodeRange* bestRange = 0;
    int32_t ibest = -1;
    for (int32_t j=0; j<v.size(); ++j) {
        UnicodeRange* r = (UnicodeRange*) v.elementAt(j);
        if (bestRange == 0 || r->length > bestRange->length) {
            bestRange = r;
            ibest = j;
        }
    }

    v.orphanElementAt(ibest); // So bestRange doesn't get deleted

    return bestRange;
}

// For UVector of UnicodeRange* objects
void U_CALLCONV UnicodeRange::deleter(void* e) {
    delete (UnicodeRange*) e;
}

U_NAMESPACE_END

