/*
 * 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>
#include <limits>


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



namespace XALAN_CPP_NAMESPACE {



const DoubleSupport::NumberUnion    DoubleSupport::s_NaN =
{
    std::numeric_limits<double>::quiet_NaN()
};

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()
{
    // 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);
}



void
DoubleSupport::terminate()
{
}



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);

        return std::modf(theResult, &theDummy) * theRHS;
    }
}



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
    {
        using std::fabs;
        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
    {
        using std::localeconv;
        using std::atof;

        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;

        std::modf(theValue + 0.5, &intPart);

    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 = 
            std::modf(theValue, &intPart);

        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);
        }
    }
}



}
