/*
 * 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.
 */
#include "DoubleSupport.hpp"



#include <clocale>
#include <cmath>
#include <climits>
#if !defined(XALAN_NO_STD_NUMERIC_LIMITS)
#include <limits>
#endif


#include "DOMStringHelper.hpp"
#include "XalanUnicode.hpp"



namespace XALAN_CPP_NAMESPACE {



#if defined(XALAN_NO_STD_NUMERIC_LIMITS)
DoubleSupport::NumberUnion          DoubleSupport::s_NaN;
#else
const DoubleSupport::NumberUnion    DoubleSupport::s_NaN =
{
#if defined(XALAN_NO_STD_NAMESPACE)
    numeric_limits<double>::quiet_NaN()
#else
    std::numeric_limits<double>::quiet_NaN()
#endif
};
#endif

const DoubleSupport::NumberUnion    DoubleSupport::s_positiveInfinity = { HUGE_VAL };

const DoubleSupport::NumberUnion    DoubleSupport::s_negativeInfinity = { -HUGE_VAL };

const DoubleSupport::NumberUnion    DoubleSupport::s_positiveZero = { 0.0 };

const DoubleSupport::NumberUnion    DoubleSupport::s_negativeZero = { -s_positiveZero.d };



void
DoubleSupport::initialize()
{
#if defined(XALAN_NO_STD_NUMERIC_LIMITS)
    // We initialize this at here because some
    // platforms have had issues with signals
    // if we call sqrt(-2.01) during static
    // initialization.
#if defined(XALAN_STRICT_ANSI_HEADERS)
    s_NaN.d = std::sqrt(-2.01);
#else
    s_NaN.d = sqrt(-2.01);
#endif
#elif !defined(XALAN_NO_STD_NAMESPACE)
    // There seems to be problems with various standard libraries, so
    // this is disabled for now.  We need to revisit this when we
    // update our autoconf/automake system to detect the right value
    // for NaN at configuration time.
    // XALAN_STATIC_ASSERT(std::numeric_limits<double>::has_quiet_NaN);
#endif
}



void
DoubleSupport::terminate()
{
#if defined(XALAN_NO_STD_NUMERIC_LIMITS)
    s_NaN.d = 0.0L;
#endif
}



bool
DoubleSupport::equal(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true || isNaN(theRHS) == true)
    {
        return false;
    }
    else
    {
        return theLHS == theRHS;
    }
}



bool
DoubleSupport::lessThan(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true || isNaN(theRHS) == true)
    {
        return false;
    }
    else
    {
        return theLHS < theRHS;
    }
}



bool
DoubleSupport::lessThanOrEqual(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true || isNaN(theRHS) == true)
    {
        return false;
    }
    else
    {
        return theLHS <= theRHS;
    }
}



bool
DoubleSupport::greaterThan(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true || isNaN(theRHS) == true)
    {
        return false;
    }
    else
    {
        return theLHS > theRHS;
    }
}



bool
DoubleSupport::greaterThanOrEqual(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true || isNaN(theRHS) == true)
    {
        return false;
    }
    else
    {
        return theLHS >= theRHS;
    }
}



double
DoubleSupport::add(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true)
    {
        return theLHS;
    }
    else if (isNaN(theRHS) == true)
    {
        return theRHS;
    }
    else
    {
        return theLHS + theRHS;
    }
}



double
DoubleSupport::subtract(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true)
    {
        return theLHS;
    }
    else if (isNaN(theRHS) == true)
    {
        return theRHS;
    }
    else
    {
        return theLHS - theRHS;
    }
}



double
DoubleSupport::multiply(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true)
    {
        return theLHS;
    }
    else if (isNaN(theRHS) == true)
    {
        return theRHS;
    }
    else
    {
        return theLHS * theRHS;
    }
}



double
DoubleSupport::divide(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true)
    {
        return theLHS;
    }
    else if (isNaN(theRHS) == true)
    {
        return theRHS;
    }
    else if (theRHS != 0.0L)
    {
        return theLHS / theRHS;
    }
    else if (theLHS == 0.0L)
    {
        // This is NaN...
        return getNaN();
    }
    else if (theLHS > 0.0L && isPositiveZero(theRHS) == true)
    {
        // This is positive infinity...
        return getPositiveInfinity();
    }
    else
    {
        // This is negative infinity...
        return getNegativeInfinity();
    }
}



double
DoubleSupport::modulus(
            double  theLHS,
            double  theRHS)
{
    if (isNaN(theLHS) == true)
    {
        return theLHS;
    }
    else if (isNaN(theRHS) == true)
    {
        return theRHS;
    }
    else if (theRHS == 0.0)
    {
        return getNaN();
    }
    else if (long(theLHS) == theLHS && long(theRHS) == theRHS)
    {
        return long(theLHS) % long(theRHS);
    }
    else
    {
        double  theDummy;

        double  theResult = divide(theLHS, theRHS);

#if defined(XALAN_STRICT_ANSI_HEADERS)
        return std::modf(theResult, &theDummy) * theRHS;
#else
        return modf(theResult, &theDummy) * theRHS;
#endif
    }
}



double
DoubleSupport::negative(double  theDouble)
{
    if (isNaN(theDouble) == true)
    {
        return getNaN();
    }
    else
    {
        return -theDouble;
    }
}



double
DoubleSupport::abs(double theDouble)
{
    if (isNaN(theDouble) == true)
    {
        return getNaN();
    }
    else
    {
#if defined(XALAN_STRICT_ANSI_HEADERS)
    using std::fabs;
#endif
        return fabs(theDouble);
    }
}



double
DoubleSupport::toDouble(
            const XalanDOMString&   theString,
            MemoryManager&          theManager)
{
    return toDouble(theString.c_str(), theManager);
}



inline void
consumeWhitespace(const XalanDOMChar*&  theString)
{
    while(*theString != 0 &&
          isXMLWhitespace(*theString))
    {
        ++theString;
    }
}



inline void
consumeWhitespace(
            const XalanDOMChar*&        theString,
            XalanDOMString::size_type&  theLength)
{
    while(*theString != 0 &&
          isXMLWhitespace(*theString))
    {
        ++theString;
        --theLength;
    }
}



inline static void
consumeNumbers(const XalanDOMChar*& theString)
{
    while(*theString &&
          *theString >= XalanUnicode::charDigit_0 &&
          *theString <= XalanUnicode::charDigit_9)
    {
            ++theString;
    }
}



static bool
doValidate(
            const XalanDOMChar*     theString,
            bool&                   fGotDecimalPoint)
{
    assert(theString != 0);

    bool    fError = false;
    bool    fGotDigit = false;
    bool    fGotMinus = false;
    bool    fGotWhitespace = false;

    const XalanDOMChar*     theCurrent = theString;

    // trim any whitespace
    consumeWhitespace(theCurrent);

    while(*theCurrent != 0 && fError == false)
    {
        switch(*theCurrent)
        {
        case XalanUnicode::charFullStop:
            if (fGotDecimalPoint == true || // can't have more than one...
                fGotWhitespace == true) // can't have one after whitespace...
            {
                fError = true;
            }
            else
            {
                fGotDecimalPoint = true;

                ++theCurrent;
            }
            break;

        case XalanUnicode::charHyphenMinus:
            if (fGotDecimalPoint == true ||
                fGotMinus == true ||
                fGotDigit == true ||
                fGotWhitespace == true)
            {
                // Error -- more than one, or in bad position.
                fError = true;
            }
            else
            {
                fGotMinus = true;

                ++theCurrent;
            }
            break;

        case XalanUnicode::charDigit_0:
        case XalanUnicode::charDigit_1:
        case XalanUnicode::charDigit_2:
        case XalanUnicode::charDigit_3:
        case XalanUnicode::charDigit_4:
        case XalanUnicode::charDigit_5:
        case XalanUnicode::charDigit_6:
        case XalanUnicode::charDigit_7:
        case XalanUnicode::charDigit_8:
        case XalanUnicode::charDigit_9:
            if (fGotWhitespace == true)
            {
                fError = true;
            }
            else
            {
                fGotDigit = true;

                consumeNumbers(theCurrent);
            }
            break;

        case XalanUnicode::charSpace:
        case XalanUnicode::charCR:
        case XalanUnicode::charHTab:
        case XalanUnicode::charLF:
            if (fGotWhitespace == true)
            {
                fError = true;
            }
            else
            {
                fGotWhitespace = true;

                consumeWhitespace(theCurrent);
            }
            break;

        default:
            fError = true;
            break;
        }
    }

    // If there was no error, check to see that we got
    // at least one digit.  Otherwise, return false if
    // there was an error.
    return fError == false ? fGotDigit : false;
}



static bool
doValidate(const XalanDOMChar*  theString)
{
    bool    fDummy = false;

    return doValidate(theString, fDummy);
}



#if defined(XALAN_NON_ASCII_PLATFORM)
static void
translateWideString(
            const XalanDOMChar*         theWideString,
            char*                       theNarrowString,
            XalanDOMString::size_type   theStringLength,
            char                        theDecimalPointCharacter)
{
    for(XalanDOMString::size_type i = 0; i < theStringLength; ++i)
    {
        switch(theWideString[i])
        {
        case XalanUnicode::charHyphenMinus:
            theNarrowString[i] = '-';
            break;

        case XalanUnicode::charFullStop:
            theNarrowString[i] = theDecimalPointCharacter;
            break;

        case XalanUnicode::charDigit_0:
            theNarrowString[i] = '0';
            break;

        case XalanUnicode::charDigit_1:
            theNarrowString[i] = '1';
            break;

        case XalanUnicode::charDigit_2:
            theNarrowString[i] = '2';
            break;

        case XalanUnicode::charDigit_3:
            theNarrowString[i] = '3';
            break;

        case XalanUnicode::charDigit_4:
            theNarrowString[i] = '4';
            break;

        case XalanUnicode::charDigit_5:
            theNarrowString[i] = '5';
            break;

        case XalanUnicode::charDigit_6:
            theNarrowString[i] = '6';
            break;

        case XalanUnicode::charDigit_7:
            theNarrowString[i] = '7';
            break;

        case XalanUnicode::charDigit_8:
            theNarrowString[i] = '8';
            break;

        case XalanUnicode::charDigit_9:
            theNarrowString[i] = '9';
            break;

        default:
            theNarrowString[i] = char(0);
            break;
        }
    }
    
    theNarrowString[theStringLength] = char(0);
}
#endif



inline double
convertHelper(
            const XalanDOMChar*     theString,
            bool                    fGotDecimalPoint,
            MemoryManager&          theManager)
{
    // This is a big hack.  If the length of the
    // string is less than n characters, we'll convert
    // it as a long and coerce that to a double.  This
    // is _much_ cheaper...
    const XalanDOMString::size_type     theLongHackThreshold = 10;

    XalanDOMString::size_type   theLength = length(theString);

    if (fGotDecimalPoint == false && theLength < theLongHackThreshold)
    {
        return double(WideStringToLong(theString));
    }
    else
    {
#if defined(XALAN_STRICT_ANSI_HEADERS)
        using std::localeconv;
        using std::atof;
#endif

        const char  theDecimalPointChar =
            localeconv()->decimal_point[0];

        // trim any whitespace
        consumeWhitespace(theString, theLength);

        // Use a stack-based buffer, when possible...
        const XalanDOMString::size_type     theBufferSize = 200u;

        if (theLength < theBufferSize)
        {
            char    theBuffer[theBufferSize];

#if defined(XALAN_NON_ASCII_PLATFORM)
            translateWideString(
                theString,
                theBuffer,
                theLength,
                theDecimalPointChar);
#else
            for(XalanDOMString::size_type i = 0; i < theLength; ++i)
            {
                if (theString[i] == XalanUnicode::charFullStop)
                {
                    theBuffer[i] = theDecimalPointChar;
                }
                else
                {
                    theBuffer[i] = char(theString[i]);
                }
            }

            theBuffer[theLength] = '\0';
#endif

            return atof(theBuffer);
        }
        else
        {
            CharVectorType  theVector(theManager);

#if !defined(XALAN_NON_ASCII_PLATFORM)
            theVector.reserve(theLength + 1);

            CopyWideStringToVector(theString, theVector);
#else
            theVector.resize(
                theLength + 1,
                CharVectorType::value_type(0));

            translateWideString(
                theString,
                &*theVector.begin(),
                theLength,
                theDecimalPointChar);
#endif

            return atof(&*theVector.begin());
        }
    }
}



inline double
doConvert(
            const XalanDOMChar*     theString,
            MemoryManager&          theManager)
{
    assert(theString != 0);
    assert(*theString != 0);

    bool    fGotDecimalPoint = false;

    if (doValidate(theString, fGotDecimalPoint) == false)
    {
        return DoubleSupport::getNaN();
    }
    else
    {
        return convertHelper(
                    theString,
                    fGotDecimalPoint,
                    theManager);
    }
}



double
DoubleSupport::toDouble(
            const XalanDOMChar*     theString,
            MemoryManager&          theManager)
{
    if (theString == 0 ||
        *theString == 0)
    {
        return getNaN();
    }
    else
    {
        return doConvert(theString, theManager);
    }
}



bool
DoubleSupport::isValid(const XalanDOMString&    theString)
{
    return isValid(theString.c_str());
}



bool
DoubleSupport::isValid(const XalanDOMChar*      theString)
{
    return doValidate(theString);
}



inline double
modfRound(double  theValue)
{
    double          intPart = 0;

#if defined(XALAN_STRICT_ANSI_HEADERS)
        std::modf(theValue + 0.5, &intPart);
#else
        modf(theValue + 0.5, &intPart);
#endif

    return intPart;
}



double
DoubleSupport::round(double     theValue)
{
    if (isNaN(theValue))
    {
        return getNaN();
    }
    else if (isPositiveInfinity(theValue))
    {
        return getPositiveInfinity();
    }
    else if (isNegativeInfinity(theValue))
    {
        return getNegativeInfinity();
    }
    else if (theValue == 0)
    {
        return 0.0;
    }
    else if (theValue > 0)
    {
        // If the value is less than the maximum value for
        // a long, this is the fastest way to do it.
        if (theValue < LONG_MAX)
        {
            return long(theValue + 0.5);
        }
        else
        {
            return modfRound(theValue);
        }
    }
    else
    {
        // Negative numbers are a special case.  Any time we
        // have -0.5 as the fractional part, we have to
        // round up (toward 0), rather than down.
        double          intPart = 0;

        const double    fracPart = 
#if defined(XALAN_STRICT_ANSI_HEADERS)
            std::modf(theValue, &intPart);
#else
            modf(theValue, &intPart);
#endif

        const double    theAdjustedValue =
            fracPart == -0.5 ? theValue + 0.5 : theValue - 0.5;

        // If the value is greater than the minimum value for
        // a long, this is the fastest way to do it.
        if (theAdjustedValue > LONG_MIN)
        {
            return long(theAdjustedValue);
        }
        else
        {
            return modfRound(theAdjustedValue);
        }
    }
}



}
