/**************************************************************
 *
 * 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 "precompiled_svtools.hxx"

#include "cellvalueconversion.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/util/XNumberFormatter.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Time.hpp>
#include <com/sun/star/util/XNumberFormatTypes.hpp>
#include <com/sun/star/util/NumberFormat.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <rtl/math.hxx>
#include <rtl/strbuf.hxx>
#include <tools/date.hxx>
#include <tools/time.hxx>
#include <tools/diagnose_ex.h>
#include <unotools/syslocale.hxx>

#include <boost/shared_ptr.hpp>
#include <hash_map>

//......................................................................................................................
namespace svt
{
//......................................................................................................................

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::util::XNumberFormatter;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::util::XNumberFormatsSupplier;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::uno::UNO_SET_THROW;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::util::DateTime;
    using ::com::sun::star::uno::TypeClass;
    using ::com::sun::star::util::XNumberFormatTypes;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::uno::Type;
    using ::com::sun::star::uno::TypeClass_BYTE;
    using ::com::sun::star::uno::TypeClass_SHORT;
    using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT;
    using ::com::sun::star::uno::TypeClass_LONG;
    using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG;
    using ::com::sun::star::uno::TypeClass_HYPER;
    /** === end UNO using === **/
    namespace NumberFormat = ::com::sun::star::util::NumberFormat;

    typedef ::com::sun::star::util::Time UnoTime;
    typedef ::com::sun::star::util::Date UnoDate;

    //==================================================================================================================
    //= helper
    //==================================================================================================================
    namespace
    {
        //--------------------------------------------------------------------------------------------------------------
        double lcl_convertDateToDays( long const i_day, long const i_month, long const i_year )
        {
            long const nNullDateDays = ::Date::DateToDays( 1, 1, 1900 );
            long const nValueDateDays = ::Date::DateToDays( i_day, i_month, i_year );

            return nValueDateDays - nNullDateDays;
        }

        //--------------------------------------------------------------------------------------------------------------
        double lcl_convertTimeToDays( long const i_hours, long const i_minutes, long const i_seconds, long const i_100thSeconds )
        {
            return Time( i_hours, i_minutes, i_seconds, i_100thSeconds ).GetTimeInDays();
        }
    }

    //==================================================================================================================
    //= IValueNormalization
    //==================================================================================================================
    class SAL_NO_VTABLE IValueNormalization
    {
    public:
        virtual ~IValueNormalization() { }

        /** converts the given <code>Any</code> into a <code>double</code> value to be fed into a number formatter
        */
        virtual double convertToDouble( Any const & i_value ) const = 0;

        /** returns the format key to be used for formatting values
        */
        virtual ::sal_Int32 getFormatKey() const = 0;
    };

    typedef ::boost::shared_ptr< IValueNormalization >                                      PValueNormalization;
    typedef ::std::hash_map< ::rtl::OUString, PValueNormalization, ::rtl::OUStringHash >    NormalizerCache;

    //==================================================================================================================
    //= CellValueConversion_Data
    //==================================================================================================================
    struct CellValueConversion_Data
    {
        ::comphelper::ComponentContext const    aContext;
        Reference< XNumberFormatter >           xNumberFormatter;
        bool                                    bAttemptedFormatterCreation;
        NormalizerCache                         aNormalizers;

        CellValueConversion_Data( ::comphelper::ComponentContext const & i_context )
            :aContext( i_context )
            ,xNumberFormatter()
            ,bAttemptedFormatterCreation( false )
            ,aNormalizers()
        {
        }
    };

    //==================================================================================================================
    //= StandardFormatNormalizer
    //==================================================================================================================
    class StandardFormatNormalizer : public IValueNormalization
    {
    protected:
        StandardFormatNormalizer( Reference< XNumberFormatter > const & i_formatter, ::sal_Int32 const i_numberFormatType )
            :m_nFormatKey( 0 )
        {
            try
            {
                ENSURE_OR_THROW( i_formatter.is(), "StandardFormatNormalizer: no formatter!" );
                Reference< XNumberFormatsSupplier > const xSupplier( i_formatter->getNumberFormatsSupplier(), UNO_SET_THROW );
                Reference< XNumberFormatTypes > const xTypes( xSupplier->getNumberFormats(), UNO_QUERY_THROW );
                m_nFormatKey = xTypes->getStandardFormat( i_numberFormatType, SvtSysLocale().GetLocale() );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
        }

        virtual ::sal_Int32 getFormatKey() const
        {
            return m_nFormatKey;
        }

    private:
        ::sal_Int32 m_nFormatKey;
    };

    //==================================================================================================================
    //= DoubleNormalization
    //==================================================================================================================
    class DoubleNormalization : public StandardFormatNormalizer
    {
    public:
        DoubleNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
        {
        }

        virtual double convertToDouble( Any const & i_value ) const
        {
            double returnValue(0);
            ::rtl::math::setNan( &returnValue );
            OSL_VERIFY( i_value >>= returnValue );
            return returnValue;
        }

        virtual ~DoubleNormalization() { }
    };

    //==================================================================================================================
    //= IntegerNormalization
    //==================================================================================================================
    class IntegerNormalization : public StandardFormatNormalizer
    {
    public:
        IntegerNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::NUMBER )
        {
        }

        virtual ~IntegerNormalization() {}

        virtual double convertToDouble( Any const & i_value ) const
        {
            sal_Int64 value( 0 );
            OSL_VERIFY( i_value >>= value );
            return value;
        }
    };

    //==================================================================================================================
    //= BooleanNormalization
    //==================================================================================================================
    class BooleanNormalization : public StandardFormatNormalizer
    {
    public:
        BooleanNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::LOGICAL )
        {
        }

        virtual ~BooleanNormalization() {}

        virtual double convertToDouble( Any const & i_value ) const
        {
            bool value( false );
            OSL_VERIFY( i_value >>= value );
            return value ? 1 : 0;
        }
    };

    //==================================================================================================================
    //= DateTimeNormalization
    //==================================================================================================================
    class DateTimeNormalization : public StandardFormatNormalizer
    {
    public:
        DateTimeNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::DATETIME )
        {
        }

        virtual ~DateTimeNormalization() {}

        virtual double convertToDouble( Any const & i_value ) const
        {
            double returnValue(0);
            ::rtl::math::setNan( &returnValue );

            // extract actual UNO value
            DateTime aDateTimeValue;
            ENSURE_OR_RETURN( i_value >>= aDateTimeValue, "allowed for DateTime values only", returnValue );

            // date part
            returnValue = lcl_convertDateToDays( aDateTimeValue.Day, aDateTimeValue.Month, aDateTimeValue.Year );

            // time part
            returnValue += lcl_convertTimeToDays(
                aDateTimeValue.Hours, aDateTimeValue.Minutes, aDateTimeValue.Seconds, aDateTimeValue.HundredthSeconds );

            // done
            return returnValue;
        }
    };

    //==================================================================================================================
    //= DateNormalization
    //==================================================================================================================
    class DateNormalization : public StandardFormatNormalizer
    {
    public:
        DateNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::DATE )
        {
        }

        virtual ~DateNormalization() {}

        virtual double convertToDouble( Any const & i_value ) const
        {
            double returnValue(0);
            ::rtl::math::setNan( &returnValue );

            // extract
            UnoDate aDateValue;
            ENSURE_OR_RETURN( i_value >>= aDateValue, "allowed for Date values only", returnValue );

            // convert
            returnValue = lcl_convertDateToDays( aDateValue.Day, aDateValue.Month, aDateValue.Year );

            // done
            return returnValue;
        }
    };

    //==================================================================================================================
    //= TimeNormalization
    //==================================================================================================================
    class TimeNormalization : public StandardFormatNormalizer
    {
    public:
        TimeNormalization( Reference< XNumberFormatter > const & i_formatter )
            :StandardFormatNormalizer( i_formatter, NumberFormat::TIME )
        {
        }

        virtual ~TimeNormalization() {}

        virtual double convertToDouble( Any const & i_value ) const
        {
            double returnValue(0);
            ::rtl::math::setNan( &returnValue );

            // extract
            UnoTime aTimeValue;
            ENSURE_OR_RETURN( i_value >>= aTimeValue, "allowed for Time values only", returnValue );

            // convert
            returnValue += lcl_convertTimeToDays(
                aTimeValue.Hours, aTimeValue.Minutes, aTimeValue.Seconds, aTimeValue.HundredthSeconds );

            // done
            return returnValue;
        }
    };

    //==================================================================================================================
    //= operations
    //==================================================================================================================
    namespace
    {
        //--------------------------------------------------------------------------------------------------------------
        bool lcl_ensureNumberFormatter( CellValueConversion_Data & io_data )
        {
            if ( io_data.bAttemptedFormatterCreation )
                return io_data.xNumberFormatter.is();
            io_data.bAttemptedFormatterCreation = true;

            try
            {
                // a number formatter
                Reference< XNumberFormatter > const xFormatter(
                    io_data.aContext.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW );

                // a supplier of number formats
                Sequence< Any > aInitArgs(1);
                aInitArgs[0] <<= SvtSysLocale().GetLocale();

                Reference< XNumberFormatsSupplier > const xSupplier(
                    io_data.aContext.createComponentWithArguments( "com.sun.star.util.NumberFormatsSupplier", aInitArgs ),
                    UNO_QUERY_THROW
                );

                // ensure a NullDate we will assume later on
                UnoDate const aNullDate( 1, 1, 1900 );
                Reference< XPropertySet > const xFormatSettings( xSupplier->getNumberFormatSettings(), UNO_SET_THROW );
                xFormatSettings->setPropertyValue( ::rtl::OUString::createFromAscii( "NullDate" ), makeAny( aNullDate ) );

                // knit
                xFormatter->attachNumberFormatsSupplier( xSupplier );

                // done
                io_data.xNumberFormatter = xFormatter;
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }

            return io_data.xNumberFormatter.is();
        }

        //--------------------------------------------------------------------------------------------------------------
        bool lcl_getValueNormalizer( CellValueConversion_Data & io_data, Type const & i_valueType,
            PValueNormalization & o_formatter )
        {
            NormalizerCache::const_iterator pos = io_data.aNormalizers.find( i_valueType.getTypeName() );
            if ( pos == io_data.aNormalizers.end() )
            {
                // never encountered this type before
                o_formatter.reset();

                ::rtl::OUString const sTypeName( i_valueType.getTypeName() );
                TypeClass const eTypeClass = i_valueType.getTypeClass();

                if ( sTypeName.equals( ::cppu::UnoType< DateTime >::get().getTypeName() ) )
                {
                    o_formatter.reset( new DateTimeNormalization( io_data.xNumberFormatter ) );
                }
                else if ( sTypeName.equals( ::cppu::UnoType< UnoDate >::get().getTypeName() ) )
                {
                    o_formatter.reset( new DateNormalization( io_data.xNumberFormatter ) );
                }
                else if ( sTypeName.equals( ::cppu::UnoType< UnoTime >::get().getTypeName() ) )
                {
                    o_formatter.reset( new TimeNormalization( io_data.xNumberFormatter ) );
                }
                else if ( sTypeName.equals( ::cppu::UnoType< ::sal_Bool >::get().getTypeName() ) )
                {
                    o_formatter.reset( new BooleanNormalization( io_data.xNumberFormatter ) );
                }
                else if (   sTypeName.equals( ::cppu::UnoType< double >::get().getTypeName() )
                        ||  sTypeName.equals( ::cppu::UnoType< float >::get().getTypeName() )
                        )
                {
                    o_formatter.reset( new DoubleNormalization( io_data.xNumberFormatter ) );
                }
                else if (   ( eTypeClass == TypeClass_BYTE )
                        ||  ( eTypeClass == TypeClass_SHORT )
                        ||  ( eTypeClass == TypeClass_UNSIGNED_SHORT )
                        ||  ( eTypeClass == TypeClass_LONG )
                        ||  ( eTypeClass == TypeClass_UNSIGNED_LONG )
                        ||  ( eTypeClass == TypeClass_HYPER )
                        )
                {
                    o_formatter.reset( new IntegerNormalization( io_data.xNumberFormatter ) );
                }
                else
                {
#if OSL_DEBUG_LEVEL > 0
                    ::rtl::OStringBuffer message( "lcl_getValueNormalizer: unsupported type '" );
                    message.append( ::rtl::OUStringToOString( sTypeName, RTL_TEXTENCODING_ASCII_US ) );
                    message.append( "'!" );
                    OSL_ENSURE( false, message.getStr() );
#endif
                }
                io_data.aNormalizers[ sTypeName ] = o_formatter;
            }
            else
                o_formatter = pos->second;

            return !!o_formatter;
        }
    }

    //==================================================================================================================
    //= CellValueConversion
    //==================================================================================================================
    //------------------------------------------------------------------------------------------------------------------
    CellValueConversion::CellValueConversion( ::comphelper::ComponentContext const & i_context )
        :m_pData( new CellValueConversion_Data( i_context ) )
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    CellValueConversion::~CellValueConversion()
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    ::rtl::OUString CellValueConversion::convertToString( const Any& i_value )
    {
        ::rtl::OUString sStringValue;
        if ( !i_value.hasValue() )
            return sStringValue;

        if ( ! ( i_value >>= sStringValue ) )
        {
            if ( lcl_ensureNumberFormatter( *m_pData ) )
            {
                PValueNormalization pNormalizer;
                if ( lcl_getValueNormalizer( *m_pData, i_value.getValueType(), pNormalizer ) )
                {
                    try
                    {
                        double const formatterCompliantValue = pNormalizer->convertToDouble( i_value );
                        sal_Int32 const formatKey = pNormalizer->getFormatKey();
                        sStringValue = m_pData->xNumberFormatter->convertNumberToString(
                            formatKey, formatterCompliantValue );
                    }
                    catch( const Exception& )
                    {
                    	DBG_UNHANDLED_EXCEPTION();
                    }
                }
            }
        }

        return sStringValue;
    }

//......................................................................................................................
} // namespace svt
//......................................................................................................................
