/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Id: XSValue.hpp 568078 2007-08-21 11:43:25Z amassari $
 */

#if !defined(XSVALUE_HPP)
#define XSVALUE_HPP

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/ValueHashTableOf.hpp>

XERCES_CPP_NAMESPACE_BEGIN

class RegularExpression;

class XMLPARSER_EXPORT XSValue : public XMemory
{
public:

    enum DataType {
              dt_string               = 0,
              dt_boolean              = 1,
              dt_decimal              = 2,
              dt_float                = 3,
              dt_double               = 4,
              dt_duration             = 5,
              dt_dateTime             = 6,
              dt_time                 = 7,
              dt_date                 = 8,
              dt_gYearMonth           = 9,
              dt_gYear                = 10,
              dt_gMonthDay            = 11,
              dt_gDay                 = 12,
              dt_gMonth               = 13,
              dt_hexBinary            = 14,
              dt_base64Binary         = 15,
              dt_anyURI               = 16,
              dt_QName                = 17,
              dt_NOTATION             = 18,
              dt_normalizedString     = 19,
              dt_token                = 20,
              dt_language             = 21,
              dt_NMTOKEN              = 22,
              dt_NMTOKENS             = 23,
              dt_Name                 = 24,
              dt_NCName               = 25,
              dt_ID                   = 26,
              dt_IDREF                = 27,
              dt_IDREFS               = 28,
              dt_ENTITY               = 29,
              dt_ENTITIES             = 30,
              dt_integer              = 31,
              dt_nonPositiveInteger   = 32,
              dt_negativeInteger      = 33,
              dt_long                 = 34,
              dt_int                  = 35,
              dt_short                = 36,
              dt_byte                 = 37,
              dt_nonNegativeInteger   = 38,
              dt_unsignedLong         = 39,
              dt_unsignedInt          = 40,
              dt_unsignedShort        = 41,
              dt_unsignedByte         = 42,
              dt_positiveInteger      = 43,
              dt_MAXCOUNT             = 44
    };

    enum XMLVersion {
            ver_10,
            ver_11
    };

    enum Status {
            st_Init,
            st_NoContent,
            st_NoCanRep,
            st_NoActVal,
            st_NotSupported,
            st_CantCreateRegEx,
            st_FOCA0002,        //invalid lexical value 
            st_FOCA0001,        //input value too large/too small for decimal 
            st_FOCA0003,        //input value too large for integer 
            st_FODT0003,        //invalid timezone value 
            st_UnknownType
    };

    enum DataGroup {
            dg_numerics,            
            dg_datetimes,
            dg_strings
    };

    enum DoubleFloatType
    {
        DoubleFloatType_NegINF,
        DoubleFloatType_PosINF,
        DoubleFloatType_NaN,
        DoubleFloatType_Zero,
        DoubleFloatType_Normal
    };

    //  Constructors and Destructor
    // -----------------------------------------------------------------------
    /** @name Destructor */
    //@{
    ~XSValue();
    //@}

    //---------------------------------
    /** @name Externalization methods */
    //@{

    /** 
      * Validate a given string of the data type specified
      *
      * @param  content    data to be validated
      * @param  datatype   schema datatype
      * @param  status     validation status which is set upon validation fails
      * @param  version    xml version
      * @param  manager    memory manager provided
      */
    static
    bool     validate
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version    = ver_10
              ,       MemoryManager*  const manager    = XMLPlatformUtils::fgMemoryManager
             );

    /** 
      * Get the canonical representation for a given string of the 
      * data type specified
      *
      * @param  content    raw data
      * @param  datatype   schema datatype
      * @param  status     validation status which is set upon validation fails
      * @param  version    xml version
      * @param  toValidate to validate the content before generate canonical representation
      * @param  manager    memory manager provided
      */
    static
    XMLCh*   getCanonicalRepresentation
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version    = ver_10
              ,       bool                  toValidate = true 
              ,       MemoryManager*  const manager    = XMLPlatformUtils::fgMemoryManager
             );

    /** 
      * Get the actual value, in the form of XSValue, for a given string of the 
      * data type specified
      *
      * Client application is responsible for the deleletion of the XSValue returned.
      *
      * @param  content    raw data
      * @param  datatype   schema datatype
      * @param  status     validation status which is set upon validation fails
      * @param  version    xml version
      * @param  toValidate to validate the content before generate actual value
      * @param  manager    memory manager provided
      */
    static
    XSValue* getActualValue
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version    = ver_10
              ,       bool                  toValidate = true 
              ,       MemoryManager*  const manager    = XMLPlatformUtils::fgMemoryManager
             );

    static
    DataType  getDataType  (const XMLCh* const dtString);

    //@}

    //----------------------------------
    /** public data */

    struct XSValue_Data {

        DataType f_datatype;
        
        union {
                         bool      f_bool;
                         char      f_char;                    
                unsigned char      f_uchar;
                         short     f_short;
                unsigned short     f_ushort;
                         int       f_int;
                unsigned int       f_uint;
                         long      f_long;
                unsigned long      f_ulong;
                         float     f_float;
                         double    f_double;
                         XMLCh*    f_strVal;
                         XMLByte*  f_byteVal;

                struct decimal {
                                double           f_dvalue;
                } f_decimal;

                struct datetime {
                                int       f_year;
                                int       f_month;
                                int       f_day;
                                int       f_hour;
                                int       f_min;
                                int       f_second;
                                double    f_milisec;

                } f_datetime;

                struct doubletype {
                                double          f_double;
                                DoubleFloatType f_doubleEnum;
                } f_doubleType;

                struct floattype {
                                float           f_float;
                                DoubleFloatType f_floatEnum;
                } f_floatType;



        } fValue;

    } fData;

    static
    void reinitMutex();

    static
    void reinitRegEx();

    static
    void reinitRegistry();

private:

    typedef union
    {
                long  f_long;
       unsigned long  f_ulong;
    } t_value;

    /** @name Constructors */
    //@{
    /**
      * The default constructor 
      *
      */
    XSValue(
             DataType        const dt
           , MemoryManager*  const manager = XMLPlatformUtils::fgMemoryManager
           );

    //@};

    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    XSValue(const XSValue&);
    XSValue & operator=(const XSValue &);

    //---------------------------------
    /** @name Helpers */

    //@{

    static const XSValue::DataGroup inGroup[];
    static const bool numericSign[];

    //@}

    static
    bool     validateNumerics
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status              
              ,       MemoryManager*  const manager
             );

    static
    bool     validateDateTimes
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status              
              ,       MemoryManager*  const manager
             );

    static
    bool     validateStrings
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version
              ,       MemoryManager*  const manager
             );

    static
    XMLCh*   getCanRepNumerics
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status             
              ,       bool                  toValidate
              ,       MemoryManager*  const manager
             );

    static
    XMLCh*   getCanRepDateTimes
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status             
              ,       bool                  toValidate
              ,       MemoryManager*  const manager
             );

    static
    XMLCh*   getCanRepStrings
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version
              ,       bool                  toValidate
              ,       MemoryManager*  const manager
             );

    static
    XSValue*  getActValNumerics
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status   
              ,       bool                  toValidate
              ,       MemoryManager*  const manager
             );

    static
    XSValue*  getActValDateTimes
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status              
              ,       MemoryManager*  const manager
             );

    static
    XSValue*  getActValStrings
             (
                const XMLCh*          const content    
              ,       DataType              datatype
              ,       Status&               status
              ,       XMLVersion            version
              ,       bool                  toValidate
              ,       MemoryManager*  const manager
             );

    static
    bool      getActualNumericValue
              (
                 const XMLCh*         const content
               ,       Status&               status                                
               ,       t_value&              retVal                              
               ,       MemoryManager* const  manager
               ,       DataType              datatype
               );

    static ValueHashTableOf<DataType>*    fDataTypeRegistry;

    // -----------------------------------------------------------------------
    //  static helper methods
    // -----------------------------------------------------------------------
    static void initializeRegistry();
    friend class XMLInitializer;

    // -----------------------------------------------------------------------
    //  data members
    // -----------------------------------------------------------------------
    bool                fMemAllocated;
    MemoryManager*      fMemoryManager;

};

XERCES_CPP_NAMESPACE_END

#endif
