/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
#include <toolkit/controls/formattedcontrol.hxx>
#include <toolkit/helper/unopropertyarrayhelper.hxx>
#include <toolkit/helper/property.hxx>

#include <com/sun/star/awt/XVclWindowPeer.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>

#include <tools/diagnose_ex.h>
#include <comphelper/processfactory.hxx>
#include <osl/diagnose.h>

//........................................................................
namespace toolkit
{
//........................................................................

	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::awt;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::util;

	// -------------------------------------------------------------------
    namespace
    {
	    // ...............................................................
        ::osl::Mutex& getDefaultFormatsMutex()
        {
            static ::osl::Mutex s_aDefaultFormatsMutex;
            return s_aDefaultFormatsMutex;
        }

        // ...............................................................
        Reference< XNumberFormatsSupplier >& lcl_getDefaultFormatsAccess_nothrow()
        {
            static Reference< XNumberFormatsSupplier > s_xDefaultFormats;
            return s_xDefaultFormats;
        }

        // ...............................................................
        bool& lcl_getTriedCreation()
        {
            static bool s_bTriedCreation = false;
            return s_bTriedCreation;
        }

	    // ...............................................................
        const Reference< XNumberFormatsSupplier >& lcl_getDefaultFormats_throw()
        {
            ::osl::MutexGuard aGuard( getDefaultFormatsMutex() );

            bool& rbTriedCreation = lcl_getTriedCreation();
            Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
            if ( !rDefaultFormats.is() && !rbTriedCreation )
            {
                rbTriedCreation = true;
                rDefaultFormats = Reference< XNumberFormatsSupplier >(
                    ::comphelper::createProcessComponent(
                        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatsSupplier" ) ) ),
                    UNO_QUERY_THROW
                );
            }
            if ( !rDefaultFormats.is() )
                throw RuntimeException();

            return rDefaultFormats;
        }

        // ...............................................................
        static oslInterlockedCount  s_refCount(0);

        // ...............................................................
        void    lcl_registerDefaultFormatsClient()
        {
            osl_incrementInterlockedCount( &s_refCount );
        }

        // ...............................................................
        void    lcl_revokeDefaultFormatsClient()
        {
            ::osl::ClearableMutexGuard aGuard( getDefaultFormatsMutex() );
            if ( 0 == osl_decrementInterlockedCount( &s_refCount ) )
            {
                Reference< XNumberFormatsSupplier >& rDefaultFormats( lcl_getDefaultFormatsAccess_nothrow() );
                Reference< XNumberFormatsSupplier > xReleasePotentialLastReference( rDefaultFormats );
                rDefaultFormats.clear();
                lcl_getTriedCreation() = false;

                aGuard.clear();
                xReleasePotentialLastReference.clear();
            }
        }
    }

	// ===================================================================
	// = UnoControlFormattedFieldModel
	// ===================================================================
	// -------------------------------------------------------------------
	UnoControlFormattedFieldModel::UnoControlFormattedFieldModel( const Reference< XMultiServiceFactory >& i_factory )
        :UnoControlModel( i_factory )
        ,m_bRevokedAsClient( false )
        ,m_bSettingValueAndText( false )
	{
		ImplRegisterProperty( BASEPROPERTY_ALIGN );
		ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
		ImplRegisterProperty( BASEPROPERTY_BORDER );
		ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
		ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
		ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_DEFAULT );
		ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_VALUE );
		ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX );
		ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN );
		ImplRegisterProperty( BASEPROPERTY_ENABLED );
		ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE );
		ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
		ImplRegisterProperty( BASEPROPERTY_FORMATKEY );
		ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER );
		ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
		ImplRegisterProperty( BASEPROPERTY_HELPURL );
		ImplRegisterProperty( BASEPROPERTY_MAXTEXTLEN );
		ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
    	ImplRegisterProperty( BASEPROPERTY_REPEAT );
        ImplRegisterProperty( BASEPROPERTY_REPEAT_DELAY );
		ImplRegisterProperty( BASEPROPERTY_READONLY );
		ImplRegisterProperty( BASEPROPERTY_SPIN );
		ImplRegisterProperty( BASEPROPERTY_STRICTFORMAT );
		ImplRegisterProperty( BASEPROPERTY_TABSTOP );
		ImplRegisterProperty( BASEPROPERTY_TEXT );
		ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
    	ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
		ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT );
		ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
		ImplRegisterProperty( BASEPROPERTY_WRITING_MODE );
        ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE );
        ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR );

		Any aTreatAsNumber;
		aTreatAsNumber <<= (sal_Bool) sal_True;
		ImplRegisterProperty( BASEPROPERTY_TREATASNUMBER, aTreatAsNumber );

        lcl_registerDefaultFormatsClient();
	}

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

	// -------------------------------------------------------------------
	::rtl::OUString UnoControlFormattedFieldModel::getServiceName() throw(RuntimeException)
	{
		return ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedFieldModel );
	}

	// -------------------------------------------------------------------
    void SAL_CALL UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
    {
        UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );

        switch ( nHandle )
        {
        case BASEPROPERTY_EFFECTIVE_VALUE:
            if ( !m_bSettingValueAndText )
                impl_updateTextFromValue_nothrow();
            break;
        case BASEPROPERTY_FORMATSSUPPLIER:
            impl_updateCachedFormatter_nothrow();
            impl_updateTextFromValue_nothrow();
            break;
        case BASEPROPERTY_FORMATKEY:
            impl_updateCachedFormatKey_nothrow();
            impl_updateTextFromValue_nothrow();
            break;
        }
    }

	// -------------------------------------------------------------------
    void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow()
    {
        if ( !m_xCachedFormatter.is() )
            impl_updateCachedFormatter_nothrow();
        if ( !m_xCachedFormatter.is() )
            return;

        try
        {
            Any aEffectiveValue;
            getFastPropertyValue( aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE );

            ::rtl::OUString sStringValue;
            if ( !( aEffectiveValue >>= sStringValue ) )
            {
                double nDoubleValue(0);
                if ( aEffectiveValue >>= nDoubleValue )
                {
                    sal_Int32 nFormatKey( 0 );
                    if ( m_aCachedFormat.hasValue() )
                        m_aCachedFormat >>= nFormatKey;
                    sStringValue = m_xCachedFormatter->convertNumberToString( nFormatKey, nDoubleValue );
                }
            }

            Reference< XPropertySet > xThis( *this, UNO_QUERY );
            xThis->setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), makeAny( sStringValue ) );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

	// -------------------------------------------------------------------
    void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow()
    {
        Any aFormatsSupplier;
        getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER );
        try
        {
            Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY );
            if ( !xSupplier.is() )
                xSupplier = lcl_getDefaultFormats_throw();

            if ( !m_xCachedFormatter.is() )
            {
                m_xCachedFormatter = Reference< XNumberFormatter >(
                    ::comphelper::createProcessComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ),
                    UNO_QUERY_THROW
                );
            }
            m_xCachedFormatter->attachNumberFormatsSupplier( xSupplier );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

	// -------------------------------------------------------------------
    void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow()
    {
        Any aFormatKey;
        getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY );
        m_aCachedFormat = aFormatKey;
    }

	// -------------------------------------------------------------------
	void UnoControlFormattedFieldModel::dispose(  ) throw(RuntimeException)
    {
        UnoControlModel::dispose();

        ::osl::MutexGuard aGuard( GetMutex() );
        if ( !m_bRevokedAsClient )
        {
            lcl_revokeDefaultFormatsClient();
            m_bRevokedAsClient = true;
        }
    }

    // -------------------------------------------------------------------
    void UnoControlFormattedFieldModel::ImplNormalizePropertySequence( const sal_Int32 _nCount, sal_Int32* _pHandles,
	    Any* _pValues, sal_Int32* _pValidHandles ) const SAL_THROW(())
    {
        ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_EFFECTIVE_VALUE, BASEPROPERTY_TEXT );

        UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles );
    }

    // -------------------------------------------------------------------
    namespace
    {
        class ResetFlagOnExit
        {
        private:
            bool&   m_rFlag;

        public:
            ResetFlagOnExit( bool& _rFlag )
                :m_rFlag( _rFlag )
            {
            }
            ~ResetFlagOnExit()
            {
                m_rFlag = false;
            }
        };
    }

    // -------------------------------------------------------------------
	void SAL_CALL UnoControlFormattedFieldModel::setPropertyValues( const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues ) throw(PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
    {
        bool bSettingValue = false;
        bool bSettingText = false;
        for (   const ::rtl::OUString* pPropertyNames = _rPropertyNames.getConstArray();
                pPropertyNames != _rPropertyNames.getConstArray() + _rPropertyNames.getLength();
                ++pPropertyNames
            )
        {
            if ( BASEPROPERTY_EFFECTIVE_VALUE == GetPropertyId( *pPropertyNames ) )
                bSettingValue = true;

            if ( BASEPROPERTY_TEXT == GetPropertyId( *pPropertyNames ) )
                bSettingText = true;
        }

        m_bSettingValueAndText = ( bSettingValue && bSettingText );
        ResetFlagOnExit aResetFlag( m_bSettingValueAndText );
        UnoControlModel::setPropertyValues( _rPropertyNames, _rValues );
    }

    // -------------------------------------------------------------------
	sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue(
				Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId,
				const Any& rValue ) throw (IllegalArgumentException)
	{
		if ( BASEPROPERTY_EFFECTIVE_DEFAULT == nPropId && rValue.hasValue() )
		{
			double dVal = 0;
			sal_Int32  nVal = 0;
			::rtl::OUString sVal;
			sal_Bool bStreamed = (rValue >>= dVal);
			if ( bStreamed )
            {
				rConvertedValue <<= dVal;
            }
			else
            {
                bStreamed = (rValue >>= nVal);
                if ( bStreamed )
                {
                    rConvertedValue <<= static_cast<double>(nVal);
                }
                else
                {
                    bStreamed = (rValue >>= sVal);
                    if ( bStreamed )
                    {
                        rConvertedValue <<= sVal;
                    }
                }
            }

			if ( bStreamed )
			{
				getFastPropertyValue( rOldValue, nPropId );
				return !CompareProperties( rConvertedValue, rOldValue );
			}

			throw IllegalArgumentException(
						( ::rtl::OUString::createFromAscii("Unable to convert the given value for the property ")
					+=	GetPropertyName((sal_uInt16)nPropId) )
					+=  ::rtl::OUString::createFromAscii(" (double, integer, or string expected)."),
				static_cast< XPropertySet* >(this),
				1);
		}

		return UnoControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nPropId, rValue );
	}

	// -------------------------------------------------------------------
	Any UnoControlFormattedFieldModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
	{
		Any aReturn;
		switch (nPropId)
		{
			case BASEPROPERTY_DEFAULTCONTROL: aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlFormattedField ) ); break;

			case BASEPROPERTY_TREATASNUMBER: aReturn <<= (sal_Bool)sal_True; break;

			case BASEPROPERTY_EFFECTIVE_DEFAULT:
			case BASEPROPERTY_EFFECTIVE_VALUE:
			case BASEPROPERTY_EFFECTIVE_MAX:
			case BASEPROPERTY_EFFECTIVE_MIN:
			case BASEPROPERTY_FORMATKEY:
			case BASEPROPERTY_FORMATSSUPPLIER:
				// (void)
				break;

			default : aReturn = UnoControlModel::ImplGetDefaultValue( nPropId ); break;
		}

		return aReturn;
	}

	// -------------------------------------------------------------------
	::cppu::IPropertyArrayHelper& UnoControlFormattedFieldModel::getInfoHelper()
	{
		static UnoPropertyArrayHelper* pHelper = NULL;
		if ( !pHelper )
		{
			Sequence<sal_Int32>	aIDs = ImplGetPropertyIds();
			pHelper = new UnoPropertyArrayHelper( aIDs );
		}
		return *pHelper;
	}

	// beans::XMultiPropertySet
	// -------------------------------------------------------------------
	Reference< XPropertySetInfo > UnoControlFormattedFieldModel::getPropertySetInfo(  ) throw(RuntimeException)
	{
		static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
		return xInfo;
	}

	// ===================================================================
	// = UnoFormattedFieldControl
	// ===================================================================
	// -------------------------------------------------------------------
	UnoFormattedFieldControl::UnoFormattedFieldControl( const Reference< XMultiServiceFactory >& i_factory )
        :UnoSpinFieldControl( i_factory )
	{
	}

	// -------------------------------------------------------------------
	::rtl::OUString UnoFormattedFieldControl::GetComponentServiceName()
	{
		return ::rtl::OUString::createFromAscii( "FormattedField" );
	}

	// -------------------------------------------------------------------
	void UnoFormattedFieldControl::textChanged(const TextEvent& e) throw(RuntimeException)
	{
		Reference< XVclWindowPeer >  xPeer(getPeer(), UNO_QUERY);
		OSL_ENSURE(xPeer.is(), "UnoFormattedFieldControl::textChanged : what kind of peer do I have ?");

        Sequence< ::rtl::OUString > aNames( 2 );
        aNames[0] = GetPropertyName( BASEPROPERTY_EFFECTIVE_VALUE );
        aNames[1] = GetPropertyName( BASEPROPERTY_TEXT );

        Sequence< Any > aValues( 2 );
        aValues[0] = xPeer->getProperty( aNames[0] );
        aValues[1] = xPeer->getProperty( aNames[1] );

        ImplSetPropertyValues( aNames, aValues, sal_False );

		if ( GetTextListeners().getLength() )
			GetTextListeners().textChanged( e );
	}

//........................................................................
}	// namespace toolkit
//........................................................................
