/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */
#if !defined(XOBJECT_HEADER_GUARD_1357924680)
#define XOBJECT_HEADER_GUARD_1357924680



// Base include file.  Must be first.
#include <xalanc/XPath/XPathDefinitions.hpp>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



#include <xalanc/PlatformSupport/DoubleSupport.hpp>
#include <xalanc/PlatformSupport/FormatterListener.hpp>
#include <xalanc/PlatformSupport/XalanReferenceCountedObject.hpp>



#include <xalanc/DOMSupport/DOMServices.hpp>



#include <xalanc/XPath/NodeRefListBase.hpp>
#include <xalanc/XPath/XalanXPathException.hpp>



XALAN_CPP_NAMESPACE_BEGIN



class MutableNodeRefList;
class NodeRefListBase;
class XalanDocumentFragment;
class XObjectFactory;
class XObjectTypeCallback;
class XPathExecutionContext;



/**
 * Class to hold XPath return types.
 */
class XALAN_XPATH_EXPORT XObject : protected XalanReferenceCountedObject
{
public:

    friend class XObjectPtr;

    /**
     * Enumeration of possible object types
     */
    enum    eObjectType { eTypeNull = 0,
                          eTypeUnknown = 1,
                          eTypeBoolean = 2,
                          eTypeNumber = 3,
                          eTypeString = 4,
                          eTypeNodeSet = 5,
                          eTypeResultTreeFrag = 6,
                          eTypeUserDefined = 7,
                          // These next types are implementation-specific, and
                          // are never returned by getType().
                          eTypeStringReference = 8,
                          eTypeStringAdapter = 9,
                          eTypeStringCached = 10,
                          eTypeXTokenNumberAdapter = 11,
                          eTypeXTokenStringAdapter = 12,
                          eTypeNodeSetNodeProxy = 13,
                          eUnknown
                        };

    /**
     * Perform static initialization.  See class XPathInit.
     */
    static void
    initialize();

    /**
     * Perform static shut down.  See class XPathInit.
     */
    static void
    terminate();

    /**
     * Create an XObject.
     *
     * @param theObjectType The enum for the type of the object.
     */
    XObject(eObjectType     theObjectType);

    XObject(const XObject&  source);

    /**
     * Clone the instance
     *
     * @param If theAddress is not null, the XObject will clone itself into that address.
     * @return a clone of the instance.
     */
    virtual XObject*
    clone(void*     theAddress = 0) const = 0;

    /**
     * Given a request type, return the equivalent string. 
     * For diagnostic purposes.
     *
     * @return string for type
     */
    virtual const XalanDOMString&
    getTypeString() const = 0;

    /**
     * Cast result object to a number.
     *
     * @return numeric value
     */
    virtual double
    num() const;

    /**
     * Cast result object to a boolean.
     *
     * @return boolean value
     */
    virtual bool
    boolean() const;

    /**
     * Cast result object to a string.
     *
     * @return string value
     */
    virtual const XalanDOMString&
    str() const;

    typedef void (FormatterListener::*MemberFunctionPtr)(const XMLCh* const, const unsigned int);

    /**
     * Send the string value to a FormatterListener instance.
     *
     * @param formatterListener The FormatterListener instance
     * @param function A pointer to the member function of FormatterListener to call
     * 
     */
    virtual void
    str(
            FormatterListener&  formatterListener,
            MemberFunctionPtr   function) const = 0;

    /**
     * Get the length of the string value of the instance..
     *
     * @return The length of the string value
     */
    virtual double
    stringLength() const = 0;

    /**
     * Append the string value directly a string
     *
     * @param theBuffer The buffer for the data
     */
    virtual void
    str(XalanDOMString& theBuffer) const;

    /**
     * Cast result object to a result tree fragment.
     *
     * @return result tree fragment
     */
    virtual const XalanDocumentFragment&
    rtree() const;

    /**
     * Cast result object to a nodelist.
     *
     * @return node list
     */
    virtual const NodeRefListBase&
    nodeset() const;

    /**
     * Process a callback request for preferred type information.
     *
     * @param theCallbackObject object to call back
     */
    virtual void
    ProcessXObjectTypeCallback(XObjectTypeCallback&     theCallbackObject) = 0;

    /**
     * Process a callback request for preferred type information.
     *
     * @param theCallbackObject object to call back
     */
    virtual void
    ProcessXObjectTypeCallback(XObjectTypeCallback&     theCallbackObject) const = 0;

    /**
     * Tell if two objects are functionally equal.
     *
     * @param theRHS object to compare
     * @param executionContext the current execution context
     * @return true if they are equal
     */
    bool
    equals(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if two objects are functionally not equal.
     *
     * @param theRHS object to compare
     * @param executionContext the current execution context
     * @return true if they are equal
     */
    bool
    notEquals(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one object is less than the other.
     *
     * @param theRHS object to compare
     * @return true if they are equal
     */
    bool
    lessThan(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one object is less than or equal
     * the other.
     *
     * @param theRHS object to compare
     * @return true if they are equal
     */
    bool
    lessThanOrEquals(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one object is greater than the other.
     *
     * @param theRHS object to compare
     * @return true if they are equal
     */
    bool
    greaterThan(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one object is greater than or equal
     * the other.
     *
     * @param theRHS object to compare
     * @return true if they are equal
     */
    bool
    greaterThanOrEquals(
            const XObject&          theRHS,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell what kind of class this is.
     *
     * @return numeric type value
     */
    eObjectType
    getType() const
    {
        return m_objectType;
    }

    /**
     * Static conversion function.
     *
     * @return bool value
     */
    static bool
    boolean(double  theNumber)
    {
        return !DoubleSupport::isNaN(theNumber) && !DoubleSupport::equal(theNumber, 0.0);
    }

    /**
     * Static conversion function.
     *
     * @return bool value
     */
    static bool
    boolean(const XalanDOMString&   theString)
    {
        return theString.length() == 0 ? false : true;
    }

    /**
     * Static conversion function.
     *
     * @return bool value
     */
    static bool
    boolean(const NodeRefListBase&  theNodeList)
    {
        return theNodeList.getLength() == 0 ? false : true;
    }

    /**
     * Static conversion function.
     *
     * @return The string value of the number
     */
    static const XalanDOMString&
    string(bool     theBool)
    {
        return theBool == true ? s_trueString : s_falseString;
    }

    static void
    string(
            bool                theBool,
            FormatterListener&  formatterListener,
            MemberFunctionPtr   function)
    {
        if(theBool == true)
        {
            (formatterListener.*function)(s_trueString.c_str(), s_trueString.length());
        }
        else
        {
            (formatterListener.*function)(s_falseString.c_str(), s_falseString.length());
        }
    }

    /**
     * Static conversion function.
     *
     * @return The string value of the number
     */
    static void
    string(
            double              theNumber,
            XalanDOMString&     theString)
    {
        DoubleToDOMString(theNumber, theString);
    }

    static void
    string(
            double              theNumber,
            FormatterListener&  formatterListener,
            MemberFunctionPtr   function)
    {
        DOMStringHelper::DoubleToCharacters(theNumber, formatterListener, function);
    }

    /**
     * Static conversion function.
     *
     * @return The string value of the node
     */
    static void
    string(
            const XalanNode&    theNode,
            XalanDOMString&     theString)
    {
        DOMServices::getNodeData(theNode, theString);
    }

    static void
    string(
            const XalanNode&    theNode,
            FormatterListener&  formatterListener,
            MemberFunctionPtr   function)
    {
        DOMServices::getNodeData(theNode, formatterListener, function);
    }

    /**
     * Static conversion function.
     *
     * @return The string value of the node list
     */
    static void
    string(
            const NodeRefListBase&  theNodeList,
            XalanDOMString&         theString)
    {
        if (theNodeList.getLength() > 0)
        {
            assert(theNodeList.item(0) != 0);

            string(*theNodeList.item(0), theString);
        }
    }

    static void
    string(
            const NodeRefListBase&  theNodeList,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function)
    {
        if (theNodeList.getLength() > 0)
        {
            assert(theNodeList.item(0) != 0);

            DOMServices::getNodeData(*theNodeList.item(0), formatterListener, function);
        }
    }

    /**
     * Static conversion function.
     *
     * @return bool value
     */
    static double
    number(bool     theBoolean)
    {
        return theBoolean == true ? 1.0 : 0.0;
    }

    static double
    number(const XalanDOMString&    theString)
    {
        return DoubleSupport::toDouble(theString);
    }

    /**
     * Static conversion function.
     *
     * @return The number value of the node list
     */
    static double
    number(
            XPathExecutionContext&  executionContext,
            const NodeRefListBase&  theNodeList);

    /**
     * Static conversion function.
     *
     * @return The number value of the node
     */
    static double
    number(
            XPathExecutionContext&  executionContext,
            const XalanNode&        theNode);


    // All XObject instances are controlled by an instance of an XObjectFactory.
    friend class XObjectFactory;

    void
    setFactory(XObjectFactory*  theFactory)
    {
        m_factory = theFactory;
    }

    // Base class for all XObject exceptions...
    class XObjectException : public XalanXPathException
    {
    public:

        explicit
        XObjectException(
                const XalanDOMString&   message);

        virtual
        ~XObjectException();

        virtual const XalanDOMChar*
        getType() const
        {
            return m_type;
        }
    private:

        static const XalanDOMChar   m_type[];
    };

    class XObjectInvalidConversionException : public XObjectException
    {
    public:

        XObjectInvalidConversionException(
                const XalanDOMString&   fromType,
                const XalanDOMString&   toType);

        virtual
        ~XObjectInvalidConversionException();

        const XalanDOMString&
        getFromType() const
        {
            return m_fromType;
        }

        const XalanDOMString&
        getToType() const
        {
            return m_toType;
        }


        virtual const XalanDOMChar*
        getType() const
        {
            return m_type;
        }
    private:

        static const XalanDOMChar   m_type[];

        static const XalanDOMString
        formatErrorString(
                const XalanDOMString&   fromType,
                const XalanDOMString&   toType);

        const XalanDOMString    m_fromType;

        const XalanDOMString    m_toType;
    };

protected:

    /**
     * Tell what kind of class this is.
     *
     * @return numeric type value
     */
    virtual eObjectType
    getRealType() const;

    virtual void 
    referenced();

    virtual void 
    dereferenced();

    virtual
    ~XObject();

    static const XalanDOMString     s_emptyString;

    static const XalanDOMString&    s_booleanString;

    static const XalanDOMString&    s_falseString;

    static const XalanDOMString&    s_nodesetString;

    static const XalanDOMString&    s_numberString;

    static const XalanDOMString&    s_resultTreeFragmentString;

    static const XalanDOMString&    s_stringString;

    static const XalanDOMString&    s_trueString;

private:

    // Not implemented...
    XObject&
    operator=(const XObject&);

    const eObjectType   m_objectType;

    XObjectFactory*     m_factory;
};



/**
 * Class to hold XObjectPtr return types.
 */
class XALAN_XPATH_EXPORT XObjectPtr
{
public:

    friend bool operator==(const XObjectPtr&, const XObjectPtr&);
    friend bool operator<(const XObjectPtr&, const XObjectPtr&);

    /**
     * Create an XObjectPtr.
     */
    explicit
    XObjectPtr(XObject*     theXObject = 0) :
        m_xobjectPtr(theXObject)
    {
        XalanReferenceCountedObject::addReference(theXObject);
    }
    
    XObjectPtr(const XObjectPtr&    theSource) :
        m_xobjectPtr(theSource.m_xobjectPtr)
    { 
        XalanReferenceCountedObject::addReference(m_xobjectPtr);
    };

    XObjectPtr&
    operator=(const XObjectPtr&     theRHS)
    { 
        if (m_xobjectPtr != theRHS.m_xobjectPtr)
        {
            XalanReferenceCountedObject::removeReference(m_xobjectPtr);

            m_xobjectPtr = theRHS.m_xobjectPtr;

            XalanReferenceCountedObject::addReference(m_xobjectPtr);
        }

        return *this;
    }

    ~XObjectPtr()
    {
        XalanReferenceCountedObject::removeReference(m_xobjectPtr);
    };  

    void
    release()
    {
        XObject* const  xobjectPtr = m_xobjectPtr;

        m_xobjectPtr = 0;

        XalanReferenceCountedObject::removeReference(xobjectPtr);
    }

    bool
    null() const
    {
        return m_xobjectPtr == 0 ? true : false;
    }

    const XObject&
    operator*() const
    {
        return *m_xobjectPtr;
    };

    XObject&
    operator*() 
    {
        return *m_xobjectPtr;
    };

    const XObject*
    operator->() const
    {
        return m_xobjectPtr;
    };

    XObject*
    operator->()
    {
        return m_xobjectPtr;
    };

    const XObject*
    get() const
    {
        return m_xobjectPtr;
    };

    XObject*
    get()
    {
        return m_xobjectPtr;
    };

private:

    XObject*    m_xobjectPtr;
};



inline bool
operator==(
            const XObjectPtr&   theLHS,
            const XObjectPtr&   theRHS)
{
    return theLHS.m_xobjectPtr == theRHS.m_xobjectPtr;
}



inline bool
operator!=(
            const XObjectPtr&   theLHS,
            const XObjectPtr&   theRHS)
{
    return !(theLHS == theRHS);
}



inline bool
operator<(
            const XObjectPtr&   theLHS,
            const XObjectPtr&   theRHS)
{
    return theLHS.m_xobjectPtr < theRHS.m_xobjectPtr;
}



XALAN_CPP_NAMESPACE_END



#endif  // XOBJECT_HEADER_GUARD_1357924680
