/*
******************************************************************************
* Copyright (C) 1996-2007, International Business Machines Corporation and
* others. All Rights Reserved.
******************************************************************************
*/

/**
* File tblcoll.h
*
* Created by: Helena Shih
*
* Modification History:
*
*  Date        Name        Description
*  2/5/97      aliu        Added streamIn and streamOut methods.  Added
*                          constructor which reads RuleBasedCollator object from
*                          a binary file.  Added writeToFile method which streams
*                          RuleBasedCollator out to a binary file.  The streamIn
*                          and streamOut methods use istream and ostream objects
*                          in binary mode.
*  2/12/97     aliu        Modified to use TableCollationData sub-object to
*                          hold invariant data.
*  2/13/97     aliu        Moved several methods into this class from Collation.
*                          Added a private RuleBasedCollator(Locale&) constructor,
*                          to be used by Collator::createDefault().  General
*                          clean up.
*  2/20/97     helena      Added clone, operator==, operator!=, operator=, and copy
*                          constructor and getDynamicClassID.
*  3/5/97      aliu        Modified constructFromFile() to add parameter
*                          specifying whether or not binary loading is to be
*                          attempted.  This is required for dynamic rule loading.
* 05/07/97     helena      Added memory allocation error detection.
*  6/17/97     helena      Added IDENTICAL strength for compare, changed getRules to
*                          use MergeCollation::getPattern.
*  6/20/97     helena      Java class name change.
*  8/18/97     helena      Added internal API documentation.
* 09/03/97     helena      Added createCollationKeyValues().
* 02/10/98     damiba      Added compare with "length" parameter
* 08/05/98     erm         Synched with 1.2 version of RuleBasedCollator.java
* 04/23/99     stephen     Removed EDecompositionMode, merged with
*                          Normalizer::EMode
* 06/14/99     stephen     Removed kResourceBundleSuffix
* 11/02/99     helena      Collator performance enhancements.  Eliminates the
*                          UnicodeString construction and special case for NO_OP.
* 11/23/99     srl         More performance enhancements. Updates to NormalizerIterator
*                          internal state management.
* 12/15/99     aliu        Update to support Thai collation.  Move NormalizerIterator
*                          to implementation file.
* 01/29/01     synwee      Modified into a C++ wrapper which calls C API
*                          (ucol.h)
*/

#ifndef TBLCOLL_H
#define TBLCOLL_H

#include "unicode/utypes.h"

/**
 * \file 
 * \brief C++ API: RuleBasedCollator class provides the simple implementation of Collator.
 */
 
#if !UCONFIG_NO_COLLATION

#include "unicode/coll.h"
#include "unicode/ucol.h"
#include "unicode/sortkey.h"
#include "unicode/normlzr.h"

U_NAMESPACE_BEGIN

/**
* @stable ICU 2.0
*/
class StringSearch;
/**
* @stable ICU 2.0
*/
class CollationElementIterator;

/**
 * The RuleBasedCollator class provides the simple implementation of
 * Collator, using data-driven tables. The user can create a customized
 * table-based collation.
 * <P>
 * <em>Important: </em>The ICU collation service has been reimplemented 
 * in order to achieve better performance and UCA compliance. 
 * For details, see the 
 * <a href="http://source.icu-project.org/repos/icu/icuhtml/trunk/design/collation/ICU_collation_design.htm">
 * collation design document</a>.
 * <p>
 * RuleBasedCollator is a thin C++ wrapper over the C implementation.
 * <p>
 * For more information about the collation service see 
 * <a href="http://icu-project.org/userguide/Collate_Intro.html">the users guide</a>.
 * <p>
 * Collation service provides correct sorting orders for most locales supported in ICU. 
 * If specific data for a locale is not available, the orders eventually falls back
 * to the <a href="http://www.unicode.org/unicode/reports/tr10/">UCA sort order</a>. 
 * <p>
 * Sort ordering may be customized by providing your own set of rules. For more on
 * this subject see the <a href="http://icu-project.org/userguide/Collate_Customization.html">
 * Collation customization</a> section of the users guide.
 * <p>
 * Note, RuleBasedCollator is not to be subclassed.
 * @see        Collator
 * @version    2.0 11/15/2001
 */
class U_I18N_API RuleBasedCollator : public Collator
{
public:

  // constructor -------------------------------------------------------------

    /**
     * RuleBasedCollator constructor. This takes the table rules and builds a
     * collation table out of them. Please see RuleBasedCollator class
     * description for more details on the collation rule syntax.
     * @param rules the collation rules to build the collation table from.
     * @param status reporting a success or an error.
     * @see Locale
     * @stable ICU 2.0
     */
    RuleBasedCollator(const UnicodeString& rules, UErrorCode& status);

    /**
     * RuleBasedCollator constructor. This takes the table rules and builds a
     * collation table out of them. Please see RuleBasedCollator class
     * description for more details on the collation rule syntax.
     * @param rules the collation rules to build the collation table from.
     * @param collationStrength default strength for comparison
     * @param status reporting a success or an error.
     * @see Locale
     * @stable ICU 2.0
     */
    RuleBasedCollator(const UnicodeString& rules,
                       ECollationStrength collationStrength,
                       UErrorCode& status);

    /**
     * RuleBasedCollator constructor. This takes the table rules and builds a
     * collation table out of them. Please see RuleBasedCollator class
     * description for more details on the collation rule syntax.
     * @param rules the collation rules to build the collation table from.
     * @param decompositionMode the normalisation mode
     * @param status reporting a success or an error.
     * @see Locale
     * @stable ICU 2.0
     */
    RuleBasedCollator(const UnicodeString& rules,
                    UColAttributeValue decompositionMode,
                    UErrorCode& status);

    /**
     * RuleBasedCollator constructor. This takes the table rules and builds a
     * collation table out of them. Please see RuleBasedCollator class
     * description for more details on the collation rule syntax.
     * @param rules the collation rules to build the collation table from.
     * @param collationStrength default strength for comparison
     * @param decompositionMode the normalisation mode
     * @param status reporting a success or an error.
     * @see Locale
     * @stable ICU 2.0
     */
    RuleBasedCollator(const UnicodeString& rules,
                    ECollationStrength collationStrength,
                    UColAttributeValue decompositionMode,
                    UErrorCode& status);

    /**
     * Copy constructor.
     * @param other the RuleBasedCollator object to be copied
     * @see Locale
     * @stable ICU 2.0
     */
    RuleBasedCollator(const RuleBasedCollator& other);


    /** Opens a collator from a collator binary image created using
    *  cloneBinary. Binary image used in instantiation of the 
    *  collator remains owned by the user and should stay around for 
    *  the lifetime of the collator. The API also takes a base collator
    *  which usualy should be UCA.
    *  @param bin binary image owned by the user and required through the
    *             lifetime of the collator
    *  @param length size of the image. If negative, the API will try to
    *                figure out the length of the image
    *  @param base fallback collator, usually UCA. Base is required to be
    *              present through the lifetime of the collator. Currently 
    *              it cannot be NULL.
    *  @param status for catching errors
    *  @return newly created collator
    *  @see cloneBinary
    *  @draft ICU 3.4
    */
    RuleBasedCollator(const uint8_t *bin, int32_t length, 
                    const RuleBasedCollator *base, 
                    UErrorCode &status);
    // destructor --------------------------------------------------------------

    /**
     * Destructor.
     * @stable ICU 2.0
     */
    virtual ~RuleBasedCollator();

    // public methods ----------------------------------------------------------

    /**
     * Assignment operator.
     * @param other other RuleBasedCollator object to compare with.
     * @stable ICU 2.0
     */
    RuleBasedCollator& operator=(const RuleBasedCollator& other);

    /**
     * Returns true if argument is the same as this object.
     * @param other Collator object to be compared.
     * @return true if arguments is the same as this object.
     * @stable ICU 2.0
     */
    virtual UBool operator==(const Collator& other) const;

    /**
     * Returns true if argument is not the same as this object.
     * @param other Collator object to be compared
     * @return returns true if argument is not the same as this object.
     * @stable ICU 2.0
     */
    virtual UBool operator!=(const Collator& other) const;

    /**
     * Makes a deep copy of the object.
     * The caller owns the returned object.
     * @return the cloned object.
     * @stable ICU 2.0
     */
    virtual Collator* clone(void) const;

    /**
     * Creates a collation element iterator for the source string. The caller of
     * this method is responsible for the memory management of the return
     * pointer.
     * @param source the string over which the CollationElementIterator will
     *        iterate.
     * @return the collation element iterator of the source string using this as
     *         the based Collator.
     * @stable ICU 2.2
     */
    virtual CollationElementIterator* createCollationElementIterator(
                                           const UnicodeString& source) const;

    /**
     * Creates a collation element iterator for the source. The caller of this
     * method is responsible for the memory management of the returned pointer.
     * @param source the CharacterIterator which produces the characters over
     *        which the CollationElementItgerator will iterate.
     * @return the collation element iterator of the source using this as the
     *         based Collator.
     * @stable ICU 2.2
     */
    virtual CollationElementIterator* createCollationElementIterator(
                                         const CharacterIterator& source) const;

    /**
     * Compares a range of character data stored in two different strings based
     * on the collation rules. Returns information about whether a string is
     * less than, greater than or equal to another string in a language.
     * This can be overriden in a subclass.
     * @param source the source string.
     * @param target the target string to be compared with the source string.
     * @return the comparison result. GREATER if the source string is greater
     *         than the target string, LESS if the source is less than the
     *         target. Otherwise, returns EQUAL.
     * @deprecated ICU 2.6 Use overload with UErrorCode&
     */
    virtual EComparisonResult compare(const UnicodeString& source,
                                      const UnicodeString& target) const;


    /**
    * The comparison function compares the character data stored in two
    * different strings. Returns information about whether a string is less 
    * than, greater than or equal to another string.
    * @param source the source string to be compared with.
    * @param target the string that is to be compared with the source string.
    * @param status possible error code
    * @return Returns an enum value. UCOL_GREATER if source is greater
    * than target; UCOL_EQUAL if source is equal to target; UCOL_LESS if source is less
    * than target
    * @stable ICU 2.6
    **/
    virtual UCollationResult compare(const UnicodeString& source,
                                      const UnicodeString& target,
                                      UErrorCode &status) const;

    /**
     * Compares a range of character data stored in two different strings based
     * on the collation rules up to the specified length. Returns information
     * about whether a string is less than, greater than or equal to another
     * string in a language. This can be overriden in a subclass.
     * @param source the source string.
     * @param target the target string to be compared with the source string.
     * @param length compares up to the specified length
     * @return the comparison result. GREATER if the source string is greater
     *         than the target string, LESS if the source is less than the
     *         target. Otherwise, returns EQUAL.
     * @deprecated ICU 2.6 Use overload with UErrorCode&
     */
    virtual EComparisonResult compare(const UnicodeString& source,
                                      const UnicodeString&  target,
                                      int32_t length) const;

    /**
    * Does the same thing as compare but limits the comparison to a specified 
    * length
    * @param source the source string to be compared with.
    * @param target the string that is to be compared with the source string.
    * @param length the length the comparison is limited to
    * @param status possible error code
    * @return Returns an enum value. UCOL_GREATER if source (up to the specified 
    *         length) is greater than target; UCOL_EQUAL if source (up to specified 
    *         length) is equal to target; UCOL_LESS if source (up to the specified 
    *         length) is less  than target.
    * @stable ICU 2.6
    */
    virtual UCollationResult compare(const UnicodeString& source,
                                      const UnicodeString& target,
                                      int32_t length,
                                      UErrorCode &status) const;

    /**
     * The comparison function compares the character data stored in two
     * different string arrays. Returns information about whether a string array
     * is less than, greater than or equal to another string array.
     * <p>Example of use:
     * <pre>
     * .       UChar ABC[] = {0x41, 0x42, 0x43, 0};  // = "ABC"
     * .       UChar abc[] = {0x61, 0x62, 0x63, 0};  // = "abc"
     * .       UErrorCode status = U_ZERO_ERROR;
     * .       Collator *myCollation =
     * .                         Collator::createInstance(Locale::US, status);
     * .       if (U_FAILURE(status)) return;
     * .       myCollation->setStrength(Collator::PRIMARY);
     * .       // result would be Collator::EQUAL ("abc" == "ABC")
     * .       // (no primary difference between "abc" and "ABC")
     * .       Collator::EComparisonResult result =
     * .                             myCollation->compare(abc, 3, ABC, 3);
     * .       myCollation->setStrength(Collator::TERTIARY);
     * .       // result would be Collator::LESS ("abc" &lt;&lt;&lt; "ABC")
     * .       // (with tertiary difference between "abc" and "ABC")
     * .       result =  myCollation->compare(abc, 3, ABC, 3);
     * </pre>
     * @param source the source string array to be compared with.
     * @param sourceLength the length of the source string array. If this value
     *        is equal to -1, the string array is null-terminated.
     * @param target the string that is to be compared with the source string.
     * @param targetLength the length of the target string array. If this value
     *        is equal to -1, the string array is null-terminated.
     * @return Returns a byte value. GREATER if source is greater than target;
     *         EQUAL if source is equal to target; LESS if source is less than
     *         target
     * @deprecated ICU 2.6 Use overload with UErrorCode&
     */
    virtual EComparisonResult compare(const UChar* source, int32_t sourceLength,
                                      const UChar* target, int32_t targetLength)
                                      const;

    /**
    * The comparison function compares the character data stored in two
    * different string arrays. Returns information about whether a string array 
    * is less than, greater than or equal to another string array.
    * @param source the source string array to be compared with.
    * @param sourceLength the length of the source string array.  If this value
    *        is equal to -1, the string array is null-terminated.
    * @param target the string that is to be compared with the source string.
    * @param targetLength the length of the target string array.  If this value
    *        is equal to -1, the string array is null-terminated.
    * @param status possible error code
    * @return Returns an enum value. UCOL_GREATER if source is greater
    * than target; UCOL_EQUAL if source is equal to target; UCOL_LESS if source is less
    * than target
    * @stable ICU 2.6
    */
    virtual UCollationResult compare(const UChar* source, int32_t sourceLength,
                                      const UChar* target, int32_t targetLength,
                                      UErrorCode &status) const;

    /**
    * Transforms a specified region of the string into a series of characters
    * that can be compared with CollationKey.compare. Use a CollationKey when
    * you need to do repeated comparisions on the same string. For a single
    * comparison the compare method will be faster.
    * @param source the source string.
    * @param key the transformed key of the source string.
    * @param status the error code status.
    * @return the transformed key.
    * @see CollationKey
    * @deprecated ICU 2.8 Use getSortKey(...) instead
    */
    virtual CollationKey& getCollationKey(const UnicodeString& source,
                                          CollationKey& key,
                                          UErrorCode& status) const;

    /**
    * Transforms a specified region of the string into a series of characters
    * that can be compared with CollationKey.compare. Use a CollationKey when
    * you need to do repeated comparisions on the same string. For a single
    * comparison the compare method will be faster.
    * @param source the source string.
    * @param sourceLength the length of the source string.
    * @param key the transformed key of the source string.
    * @param status the error code status.
    * @return the transformed key.
    * @see CollationKey
    * @deprecated ICU 2.8 Use getSortKey(...) instead
    */
    virtual CollationKey& getCollationKey(const UChar *source,
                                          int32_t sourceLength,
                                          CollationKey& key,
                                          UErrorCode& status) const;

    /**
     * Generates the hash code for the rule-based collation object.
     * @return the hash code.
     * @stable ICU 2.0
     */
    virtual int32_t hashCode(void) const;

    /**
    * Gets the locale of the Collator
    * @param type can be either requested, valid or actual locale. For more
    *             information see the definition of ULocDataLocaleType in
    *             uloc.h
    * @param status the error code status.
    * @return locale where the collation data lives. If the collator
    *         was instantiated from rules, locale is empty.
    * @deprecated ICU 2.8 likely to change in ICU 3.0, based on feedback
    */
    virtual const Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;

    /**
     * Gets the table-based rules for the collation object.
     * @return returns the collation rules that the table collation object was
     *         created from.
     * @stable ICU 2.0
     */
    const UnicodeString& getRules(void) const;

    /**
     * Gets the version information for a Collator.
     * @param info the version # information, the result will be filled in
     * @stable ICU 2.0
     */
    virtual void getVersion(UVersionInfo info) const;

    /**
     * Return the maximum length of any expansion sequences that end with the
     * specified comparison order.
     * @param order a collation order returned by previous or next.
     * @return maximum size of the expansion sequences ending with the collation
     *         element or 1 if collation element does not occur at the end of
     *         any expansion sequence
     * @see CollationElementIterator#getMaxExpansion
     * @stable ICU 2.0
     */
    int32_t getMaxExpansion(int32_t order) const;

    /**
     * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
     * method is to implement a simple version of RTTI, since not all C++
     * compilers support genuine RTTI. Polymorphic operator==() and clone()
     * methods call this method.
     * @return The class ID for this object. All objects of a given class have
     *         the same class ID. Objects of other classes have different class
     *         IDs.
     * @stable ICU 2.0
     */
    virtual UClassID getDynamicClassID(void) const;

    /**
     * Returns the class ID for this class. This is useful only for comparing to
     * a return value from getDynamicClassID(). For example:
     * <pre>
     * Base* polymorphic_pointer = createPolymorphicObject();
     * if (polymorphic_pointer->getDynamicClassID() ==
     *                                          Derived::getStaticClassID()) ...
     * </pre>
     * @return The class ID for all objects of this class.
     * @stable ICU 2.0
     */
    static UClassID U_EXPORT2 getStaticClassID(void);

    /**
     * Returns the binary format of the class's rules. The format is that of
     * .col files.
     * @param length Returns the length of the data, in bytes
     * @param status the error code status.
     * @return memory, owned by the caller, of size 'length' bytes.
     * @stable ICU 2.2
     */
    uint8_t *cloneRuleData(int32_t &length, UErrorCode &status);


    /** Creates a binary image of a collator. This binary image can be stored and 
    *  later used to instantiate a collator using ucol_openBinary.
    *  This API supports preflighting.
    *  @param buffer a fill-in buffer to receive the binary image
    *  @param capacity capacity of the destination buffer
    *  @param status for catching errors
    *  @return size of the image
    *  @see ucol_openBinary
    *  @draft ICU 3.4
    */
    int32_t cloneBinary(uint8_t *buffer, int32_t capacity, UErrorCode &status);

    /**
     * Returns current rules. Delta defines whether full rules are returned or
     * just the tailoring.
     * @param delta one of UCOL_TAILORING_ONLY, UCOL_FULL_RULES.
     * @param buffer UnicodeString to store the result rules
     * @stable ICU 2.2
     */
    void getRules(UColRuleOption delta, UnicodeString &buffer);

    /**
     * Universal attribute setter
     * @param attr attribute type
     * @param value attribute value
     * @param status to indicate whether the operation went on smoothly or there were errors
     * @stable ICU 2.2
     */
    virtual void setAttribute(UColAttribute attr, UColAttributeValue value,
                              UErrorCode &status);

    /**
     * Universal attribute getter.
     * @param attr attribute type
     * @param status to indicate whether the operation went on smoothly or there were errors
     * @return attribute value
     * @stable ICU 2.2
     */
    virtual UColAttributeValue getAttribute(UColAttribute attr,
                                            UErrorCode &status);

    /**
     * Sets the variable top to a collation element value of a string supplied.
     * @param varTop one or more (if contraction) UChars to which the variable top should be set
     * @param len length of variable top string. If -1 it is considered to be zero terminated.
     * @param status error code. If error code is set, the return value is undefined. Errors set by this function are: <br>
     *    U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such a contraction<br>
     *    U_PRIMARY_TOO_LONG_ERROR if the primary for the variable top has more than two bytes
     * @return a 32 bit value containing the value of the variable top in upper 16 bits. Lower 16 bits are undefined
     * @stable ICU 2.0
     */
    virtual uint32_t setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status);

    /**
     * Sets the variable top to a collation element value of a string supplied.
     * @param varTop an UnicodeString size 1 or more (if contraction) of UChars to which the variable top should be set
     * @param status error code. If error code is set, the return value is undefined. Errors set by this function are: <br>
     *    U_CE_NOT_FOUND_ERROR if more than one character was passed and there is no such a contraction<br>
     *    U_PRIMARY_TOO_LONG_ERROR if the primary for the variable top has more than two bytes
     * @return a 32 bit value containing the value of the variable top in upper 16 bits. Lower 16 bits are undefined
     * @stable ICU 2.0
     */
    virtual uint32_t setVariableTop(const UnicodeString varTop, UErrorCode &status);

    /**
     * Sets the variable top to a collation element value supplied. Variable top is set to the upper 16 bits.
     * Lower 16 bits are ignored.
     * @param varTop CE value, as returned by setVariableTop or ucol)getVariableTop
     * @param status error code (not changed by function)
     * @stable ICU 2.0
     */
    virtual void setVariableTop(const uint32_t varTop, UErrorCode &status);

    /**
     * Gets the variable top value of a Collator.
     * Lower 16 bits are undefined and should be ignored.
     * @param status error code (not changed by function). If error code is set, the return value is undefined.
     * @stable ICU 2.0
     */
    virtual uint32_t getVariableTop(UErrorCode &status) const;

    /**
     * Get an UnicodeSet that contains all the characters and sequences tailored in 
     * this collator.
     * @param status      error code of the operation
     * @return a pointer to a UnicodeSet object containing all the 
     *         code points and sequences that may sort differently than
     *         in the UCA. The object must be disposed of by using delete
     * @stable ICU 2.4
     */
    virtual UnicodeSet *getTailoredSet(UErrorCode &status) const;

    /**
     * Thread safe cloning operation.
     * @return pointer to the new clone, user should remove it.
     * @stable ICU 2.2
     */
    virtual Collator* safeClone(void);

    /**
     * Get the sort key as an array of bytes from an UnicodeString.
     * @param source string to be processed.
     * @param result buffer to store result in. If NULL, number of bytes needed
     *        will be returned.
     * @param resultLength length of the result buffer. If if not enough the
     *        buffer will be filled to capacity.
     * @return Number of bytes needed for storing the sort key
     * @stable ICU 2.0
     */
    virtual int32_t getSortKey(const UnicodeString& source, uint8_t *result,
                               int32_t resultLength) const;

    /**
     * Get the sort key as an array of bytes from an UChar buffer.
     * @param source string to be processed.
     * @param sourceLength length of string to be processed. If -1, the string
     *        is 0 terminated and length will be decided by the function.
     * @param result buffer to store result in. If NULL, number of bytes needed
     *        will be returned.
     * @param resultLength length of the result buffer. If if not enough the
     *        buffer will be filled to capacity.
     * @return Number of bytes needed for storing the sort key
     * @stable ICU 2.2
     */
    virtual int32_t getSortKey(const UChar *source, int32_t sourceLength,
                               uint8_t *result, int32_t resultLength) const;

    /**
    * Determines the minimum strength that will be use in comparison or
    * transformation.
    * <p>E.g. with strength == SECONDARY, the tertiary difference is ignored
    * <p>E.g. with strength == PRIMARY, the secondary and tertiary difference
    * are ignored.
    * @return the current comparison level.
    * @see RuleBasedCollator#setStrength
    * @deprecated ICU 2.6 Use getAttribute(UCOL_STRENGTH...) instead
    */
    virtual ECollationStrength getStrength(void) const;

    /**
    * Sets the minimum strength to be used in comparison or transformation.
    * @see RuleBasedCollator#getStrength
    * @param newStrength the new comparison level.
    * @deprecated ICU 2.6 Use setAttribute(UCOL_STRENGTH...) instead
    */
    virtual void setStrength(ECollationStrength newStrength);

private:

    // private static constants -----------------------------------------------

    enum {
        /* need look up in .commit() */
        CHARINDEX = 0x70000000,
        /* Expand index follows */
        EXPANDCHARINDEX = 0x7E000000,
        /* contract indexes follows */
        CONTRACTCHARINDEX = 0x7F000000,
        /* unmapped character values */
        UNMAPPED = 0xFFFFFFFF,
        /* primary strength increment */
        PRIMARYORDERINCREMENT = 0x00010000,
        /* secondary strength increment */
        SECONDARYORDERINCREMENT = 0x00000100,
        /* tertiary strength increment */
        TERTIARYORDERINCREMENT = 0x00000001,
        /* mask off anything but primary order */
        PRIMARYORDERMASK = 0xffff0000,
        /* mask off anything but secondary order */
        SECONDARYORDERMASK = 0x0000ff00,
        /* mask off anything but tertiary order */
        TERTIARYORDERMASK = 0x000000ff,
        /* mask off ignorable char order */
        IGNORABLEMASK = 0x0000ffff,
        /* use only the primary difference */
        PRIMARYDIFFERENCEONLY = 0xffff0000,
        /* use only the primary and secondary difference */
        SECONDARYDIFFERENCEONLY = 0xffffff00,
        /* primary order shift */
        PRIMARYORDERSHIFT = 16,
        /* secondary order shift */
        SECONDARYORDERSHIFT = 8,
        /* starting value for collation elements */
        COLELEMENTSTART = 0x02020202,
        /* testing mask for primary low element */
        PRIMARYLOWZEROMASK = 0x00FF0000,
        /* reseting value for secondaries and tertiaries */
        RESETSECONDARYTERTIARY = 0x00000202,
        /* reseting value for tertiaries */
        RESETTERTIARY = 0x00000002,

        PRIMIGNORABLE = 0x0202
    };

    // private data members ---------------------------------------------------

    UBool dataIsOwned;

    UBool isWriteThroughAlias;

    /**
    * c struct for collation. All initialisation for it has to be done through
    * setUCollator().
    */
    UCollator *ucollator;

    /**
    * Rule UnicodeString
    */
    UnicodeString urulestring;

    // friend classes --------------------------------------------------------

    /**
    * Used to iterate over collation elements in a character source.
    */
    friend class CollationElementIterator;

    /**
    * Collator ONLY needs access to RuleBasedCollator(const Locale&,
    *                                                       UErrorCode&)
    */
    friend class Collator;

    /**
    * Searching over collation elements in a character source
    */
    friend class StringSearch;

    // private constructors --------------------------------------------------

    /**
     * Default constructor
     */
    RuleBasedCollator();

    /**
     * RuleBasedCollator constructor. This constructor takes a locale. The
     * only caller of this class should be Collator::createInstance(). If
     * createInstance() happens to know that the requested locale's collation is
     * implemented as a RuleBasedCollator, it can then call this constructor.
     * OTHERWISE IT SHOULDN'T, since this constructor ALWAYS RETURNS A VALID
     * COLLATION TABLE. It does this by falling back to defaults.
     * @param desiredLocale locale used
     * @param status error code status
     */
    RuleBasedCollator(const Locale& desiredLocale, UErrorCode& status);

    /**
     * common constructor implementation
     *
     * @param rules the collation rules to build the collation table from.
     * @param collationStrength default strength for comparison
     * @param decompositionMode the normalisation mode
     * @param status reporting a success or an error.
     */
    void
    construct(const UnicodeString& rules,
              UColAttributeValue collationStrength,
              UColAttributeValue decompositionMode,
              UErrorCode& status);

    // private methods -------------------------------------------------------

    /**
    * Creates the c struct for ucollator
    * @param locale desired locale
    * @param status error status
    */
    void setUCollator(const Locale& locale, UErrorCode& status);

    /**
    * Creates the c struct for ucollator
    * @param locale desired locale name
    * @param status error status
    */
    void setUCollator(const char* locale, UErrorCode& status);

    /**
    * Creates the c struct for ucollator. This used internally by StringSearch.
    * Hence the responsibility of cleaning up the ucollator is not done by
    * this RuleBasedCollator. The isDataOwned flag is set to FALSE.
    * @param collator new ucollator data
    * @param rules corresponding collation rules
    */
    void setUCollator(UCollator *collator);

public:
    /**
    * Get UCollator data struct. Used only by StringSearch & intltest.
    * @return UCollator data struct
    * @internal
    */
    const UCollator * getUCollator();

protected:
   /**
    * Used internally by registraton to define the requested and valid locales.
    * @param requestedLocale the requsted locale
    * @param validLocale the valid locale
    * @internal
    */
    virtual void setLocales(const Locale& requestedLocale, const Locale& validLocale);

private:

    // if not owned and not a write through alias, copy the ucollator
    void checkOwned(void);

    // utility to init rule string used by checkOwned and construct
    void setRuleStringFromCollator();

    /**
    * Converts C's UCollationResult to EComparisonResult
    * @param result member of the enum UComparisonResult
    * @return EComparisonResult equivalent of UCollationResult
    * @deprecated ICU 2.6. We will not need it.
    */
    Collator::EComparisonResult getEComparisonResult(
                                            const UCollationResult &result) const;

    /**
    * Converts C's UCollationStrength to ECollationStrength
    * @param strength member of the enum UCollationStrength
    * @return ECollationStrength equivalent of UCollationStrength
    */
    Collator::ECollationStrength getECollationStrength(
                                        const UCollationStrength &strength) const;

    /**
    * Converts C++'s ECollationStrength to UCollationStrength
    * @param strength member of the enum ECollationStrength
    * @return UCollationStrength equivalent of ECollationStrength
    */
    UCollationStrength getUCollationStrength(
      const Collator::ECollationStrength &strength) const;
};

// inline method implementation ---------------------------------------------

inline void RuleBasedCollator::setUCollator(const Locale &locale,
                                               UErrorCode &status)
{
    setUCollator(locale.getName(), status);
}


inline void RuleBasedCollator::setUCollator(UCollator     *collator)
{

    if (ucollator && dataIsOwned) {
        ucol_close(ucollator);
    }
    ucollator   = collator;
    dataIsOwned = FALSE;
    isWriteThroughAlias = TRUE;
	setRuleStringFromCollator();
}

inline const UCollator * RuleBasedCollator::getUCollator()
{
    return ucollator;
}

inline Collator::EComparisonResult RuleBasedCollator::getEComparisonResult(
                                           const UCollationResult &result) const
{
    switch (result)
    {
    case UCOL_LESS :
        return Collator::LESS;
    case UCOL_EQUAL :
        return Collator::EQUAL;
    default :
        return Collator::GREATER;
    }
}

inline Collator::ECollationStrength RuleBasedCollator::getECollationStrength(
                                       const UCollationStrength &strength) const
{
    switch (strength)
    {
    case UCOL_PRIMARY :
        return Collator::PRIMARY;
    case UCOL_SECONDARY :
        return Collator::SECONDARY;
    case UCOL_TERTIARY :
        return Collator::TERTIARY;
    case UCOL_QUATERNARY :
        return Collator::QUATERNARY;
    default :
        return Collator::IDENTICAL;
    }
}

inline UCollationStrength RuleBasedCollator::getUCollationStrength(
                             const Collator::ECollationStrength &strength) const
{
    switch (strength)
    {
    case Collator::PRIMARY :
        return UCOL_PRIMARY;
    case Collator::SECONDARY :
        return UCOL_SECONDARY;
    case Collator::TERTIARY :
        return UCOL_TERTIARY;
    case Collator::QUATERNARY :
        return UCOL_QUATERNARY;
    default :
        return UCOL_IDENTICAL;
    }
}

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_COLLATION */

#endif
