// Revision: 55 1.19 source/core/text/intl/locale/ilocale.hpp, text, ocdev
// ilocale.hpp
/**
 * The ILocaleKey and ILocaleKeyIterator classes provide support for identifying linguistic and local conventions.
 *
 * @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 _ILOCALE_
#define _ILOCALE_

#include <itext.hpp>
#include <imstrmbl.hpp>

#if defined(__OS2__) || defined(_AIX) || defined(__AS400__)
#define USE_POSIX
#endif

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

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


//========================================================================================
// CLASS ILocaleKey
//========================================================================================
class ILocaleKey : public IMSTREAMABLE
{
        StreamableDeclarationsMacro(ILocaleKey);
    public:
                /**
                 *              typedefs and constant definitions
                 */

        enum ELookupStrategy {
            kExactLocale,
            kExactLanguage,
            kAnyLanguage
        };

                /**
                 *              constructors and destructor
                 */

        ILocaleKey();

        ILocaleKey(const IText& languageID,
                   const IText& regionID = IText(),
                   const IText& ext = IText());

        ILocaleKey(const ILocaleKey& that);

        ILocaleKey(unsigned long hostLocaleID);

        ~ILocaleKey();

                /**
                 *              Assignment
                 */

        ILocaleKey&     operator=(const ILocaleKey& that);

                /**
                 *       Setter/Getter for ILocaleKey information
                 */

        IText           posixID() const;

        void            setPOSIXID(const IText& localeID);

        IText           languageID() const;

        void            setLanguageID(const IText&      languageID);

        IText           regionID() const;

        void            setRegionID(const IText&        regionID);

        IText           extension() const;

        void            setExtension(const IText&       extension);

        unsigned long   hostID() const;

        void                    setHostID(unsigned long localeID);

        bool            isCLocale() const;

        static  ILocaleKey      defaultLocale();

        /**
         * Comparison operator
                 */

        bool            operator==(const ILocaleKey& other) const;

        bool            operator!=(const ILocaleKey& other) const;

        /**
         * Displayable Name
         */

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

        static  IText   displayName(const IText& key,
                            const ILocaleKey&  desiredLanguage = defaultLocale(),
                            ELookupStrategy strategy = kAnyLanguage);
    protected:
        /**
         * Streaming operations
                 */

        virtual void    writeToStream(IDataStream& toWhere) const;

        virtual void    readFromStream(IDataStream& fromWhere);

    private:

        IText   exactLocaleMatch(const ILocaleKey& desiredLanguage) const;

        IText   exactLanguageMatch(const ILocaleKey& desiredLanguage) const;

        IText   anyLanguageMatch(const ILocaleKey& desiredLanguage) const;

        static bool  parsePOSIXID(const IText& posixID,
                                                        IText& langID,
                                                        IText& regionID,
                                                        IText& extension);
        friend class ILocaleKeyIterator;

        unsigned long  fHostID;
        IText          fLanguageID;
        IText          fRegionID;
        IText          fExtension;

};

//========================================================================================
// CLASS ILocaleKeyIterator
//========================================================================================

class ILocaleKeyIterator
{
    public:
                /**
                 *              Constructors and destructor
                 */

        ILocaleKeyIterator();

        ILocaleKeyIterator(const ILocaleKeyIterator& that);

        ~ILocaleKeyIterator();

        /**
         * Assignment
                 */

        ILocaleKeyIterator& operator=(const ILocaleKeyIterator& that);

        /**
         * Comparison
                 */

        bool                operator==(const ILocaleKeyIterator& that) const;

        bool                operator!=(const ILocaleKeyIterator& that) const;

        /**
         * Iterator End Detections
                 */

        operator                        bool() const;

        static ILocaleKeyIterator end();

        /**
         * Cursor actions
                 */

        void                            reset();

        ILocaleKey                      operator*() const;

            const ILocaleKey*   operator->() const;

                /**
                 * Increment operators
                 */

        ILocaleKeyIterator& operator++();

        ILocaleKeyIterator      operator++(int);

    private:
#ifdef USE_POSIX
        int  ILocaleKeyIterator::enumPOSIXLocale();
#endif

        ILocaleKey     *fLocales;
        int            fIndex;

};

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

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

#endif
