// Revision: 65 1.23 source/core/text/intl/compare/itxtcoll.hpp, text, ocdev
// itxtcoll.hpp
/**
 * This file contains the classes ICollation, IBitwiseCollation and IPortableCollation which provides language-sensitive text comparison.
 *
 * @package     Text and International
 * @category International Components
 *
 * @copyright
 *              IBM Open Class Library
 *              (C) Copyright International Business Machines Corporation 1997
 *              Licensed Material - Program-Property of IBM - All Rights Reserved.
 *
 * @author              Helena Shih
 */

#ifndef _ITXTCOLL_
#define _ITXTCOLL_

#include <iprimtyp.hpp>
#include <itext.hpp>
#include <ilocale.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma enum(4)
#pragma pack(push,4)

//========================================================================================
// CLASS ICollation
//========================================================================================
class ICollation
{
        public:
                /**
                 *              typedefs and constant definitions
                 */

                enum ECollationStrength {
                        kPrimaryDifference,
                        kSecondaryDifference,
                        kTertiaryDifference,
                        kNoDifference};

                enum ETextComparisonResult{
                        kSourceLess             = -1,
                        kSourceEqual    =  0,
                        kSourceGreater  =  1
                        };

            /**
                 * Instantiation Helper
                 */

                static          ICollation*             createCollation(
                                                const ILocaleKey& localeId = ILocaleKey::defaultLocale(),
                                                ECollationStrength      strength = kTertiaryDifference);

        protected:
                /**
                 *              Constructors and Destructor
                 */

                ICollation();

                ICollation(const ICollation& that);

                /**
                 *              Assignment
                 */

                ICollation&     operator=(const ICollation& that);
    public:
                virtual         ~ICollation();

        public:
            /**
                 * Comparison/Transforming/Hashing
                 */

                int                     compare(const UniChar* sourceLow,
                                                        const UniChar* sourceHigh,
                                                        const UniChar* targetLow,
                                                        const UniChar* targetHigh) const;

                int                     compare(const IText& source,
                                                        const IText& target) const;

                int                     compare(ITextIterator sourceBegin,
                                                        ITextIterator sourceEnd,
                                                        ITextIterator targetBegin,
                                                        ITextIterator targetEnd) const;


                IText           transform(const IText& source) const;

                IText           transform(ITextIterator sourceBegin,
                                                        ITextIterator sourceEnd) const;

                long            hash(const UniChar* sourceLow,
                                                const UniChar* sourceHigh) const;

                long            hash(const IText& source) const;

                long            hash(ITextIterator sourceBegin,
                                                ITextIterator sourceEnd) const;

                /**
                 * Getter/Setter for Information Access
                 */

                ILocaleKey      localeKey() const;

                ECollationStrength      strength() const;

                void                            setStrength(ECollationStrength newStrength);

                /**
                 * Simple Comparison Helper Functions
                 */

                virtual         bool    isEqual(const IText& sourceText,
                                                                const IText& targetText) const;

                virtual         bool    isGreaterThan(const IText& sourceText,
                                                                                const IText& targetText) const;

                virtual         bool    isLessThan(const IText& sourceText,
                                                                            const IText& targetText ) const;

                /**
                 * Displayable Name
                 */

                virtual         IText   displayName(
                                        const ILocaleKey& desiredLanguage = ILocaleKey::defaultLocale(),
                                        ILocaleKey::ELookupStrategy strategy = ILocaleKey::kAnyLanguage) const = 0;

protected:
                /**
                 * Implementation methods
                 */

                virtual         int             do_compare(     const UniChar* sourceLow,
                                                                                const UniChar* sourceHigh,
                                                                                const UniChar* targetLow,
                                                                                const UniChar* targetHigh) const = 0;

                virtual         IText   do_transform(const IText& source) const = 0;

                virtual         long    do_hash(const UniChar* sourceLow,
                                                                        const UniChar* sourceHigh) const;

                void            setLocaleKey(const ILocaleKey& newLocale);

        /**
         * Hidden Members
         */

                UniChar*        createUniCharChunk(     const IText& source,
                                                                                IText::length_type& chunkLength) const;

        private:

                ILocaleKey                      fLocaleKey;
                ECollationStrength      fStrength;

};

//========================================================================================
// CLASS IBitwiseCollation
//========================================================================================
class IBitwiseCollation : public ICollation
{
        public:
                /**
                 *              constructors and destructor
                 */

                IBitwiseCollation();

        protected:

                IBitwiseCollation(const IBitwiseCollation& that);

    public:
                virtual ~IBitwiseCollation();

                /**
                 *              Displayable names
                 */

                virtual IText displayName(
                                const ILocaleKey& desiredLanguage = ILocaleKey::defaultLocale(),
                                ILocaleKey::ELookupStrategy strategy = ILocaleKey::kAnyLanguage) const;

protected:
                /**
                 * Assignment operator
                 */

                IBitwiseCollation& operator=(const IBitwiseCollation& that);

                /**
                 * Implementation
                 */

                virtual         int             do_compare(     const UniChar* sourceLow,
                                                                                const UniChar* sourceHigh,
                                                                                const UniChar* targetLow,
                                                                                const UniChar* targetHigh ) const;

                virtual         IText   do_transform(const IText& source) const;

        private:

};

//========================================================================================
// CLASS IPortableCollation
//========================================================================================
class IPortableCollation : public ICollation
{
        public:
            /**
                 * Instatiation helper
                 */

                static IPortableCollation* createCollation(
                                const ILocaleKey& key,
                                ICollation::ECollationStrength  strength = kTertiaryDifference);

        protected:
                /**
                 *              Constructors and destructor
                 */

                IPortableCollation();

                IPortableCollation(const IPortableCollation& that);

                IPortableCollation(const IText& rules);
    public:
                virtual ~IPortableCollation();

        /**
         * Display Name
         */

                IText   displayName(
                                const ILocaleKey& desiredLanguage = ILocaleKey::defaultLocale(),
                                ILocaleKey::ELookupStrategy strategy = ILocaleKey::kAnyLanguage) const;

        public:
            /**
                 * Comparison/Transforming/Hashing
                 */

                virtual         int compare(const UniChar* sourceLow,
                                                const UniChar* sourceHigh,
                                                const UniChar* targetLow,
                                                const UniChar* targetHigh,
                                                IText::length_type&  matchSourceLen = nlength,
                                                IText::length_type&  matchTargetLen = nlength) const;

                virtual         int compare(const ITextIterator& sourceBegin,
                                                const ITextIterator& sourceEnd,
                                                const ITextIterator& targetBegin,
                                                const ITextIterator& targetEnd,
                                                IText::length_type&  matchSourceLen = nlength,
                                                IText::length_type&  matchTargetLen = nlength) const;

                virtual         int compare(const IText& source,
                                                const IText& target,
                                                IText::length_type&  matchSourceLen = nlength,
                                                IText::length_type&  matchTargetLen = nlength) const;

    protected :
                /**
                 *              Assignment
                 */

                IPortableCollation& operator=(const IPortableCollation& that);

                /**
                 * ANSI compliant Implementation
                 */

                virtual         int     do_compare( const UniChar* sourceLow,
                                                const UniChar* sourceHigh,
                                                const UniChar* targetLow,
                                                const UniChar* targetHigh) const;

                virtual         int     do_matchCompare(const UniChar* sourceLow,
                                                const UniChar* sourceHigh,
                                                const UniChar* targetLow,
                                                const UniChar* targetHigh,
                                                IText::length_type&  matchSourceLen,
                                                IText::length_type&  matchTargetLen) const = 0;

                virtual         IText   do_transform(const IText& source) const = 0;

    private:

                static IText::length_type       nlength;

                IText   fCollationRules;

};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _ITXTCOLL_
