/**************************************************************
 * 
 * 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_forms.hxx"
#include "scrollbar.hxx"
#include <comphelper/streamsection.hxx>
#include <comphelper/basicio.hxx>
#include <rtl/math.hxx>

//--------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_OScrollBarModel()
{
	static ::frm::OMultiInstanceAutoRegistration< ::frm::OScrollBarModel >   aRegisterModel;
}

//........................................................................
namespace frm
{
//........................................................................

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

    //====================================================================
	//= helper
	//====================================================================
    //--------------------------------------------------------------------
    Any translateExternalDoubleToControlIntValue( 
        const Any& _rExternalValue, const Reference< XPropertySet >& _rxProperties,
        const ::rtl::OUString& _rMinValueName, const ::rtl::OUString& _rMaxValueName )
    {
        OSL_ENSURE( _rxProperties.is(), "translateExternalDoubleToControlIntValue: no aggregate!?" );

        sal_Int32 nControlValue( 0 );
        double nExternalValue = 0;
        if ( _rExternalValue >>= nExternalValue )
        {
            if ( ::rtl::math::isInf( nExternalValue ) )
            {
                // set the minimum or maximum of the scroll values
                ::rtl::OUString sLimitPropertyName = ::rtl::math::isSignBitSet( nExternalValue )
                    ? _rMinValueName : _rMaxValueName;
                if ( _rxProperties.is() )
                    _rxProperties->getPropertyValue( sLimitPropertyName ) >>= nControlValue;
            }
            else
            {
                nControlValue = (sal_Int32)::rtl::math::round( nExternalValue );
            }
        }
        else
        {
            if ( _rxProperties.is() )
                _rxProperties->getPropertyValue( _rMinValueName ) >>= nControlValue;
        }

        return makeAny( nControlValue );
    }

    //--------------------------------------------------------------------
    Any translateControlIntToExternalDoubleValue( const Any& _rControlIntValue )
    {
        Any aExternalDoubleValue;
        sal_Int32 nScrollValue = 0;
        if ( _rControlIntValue >>= nScrollValue )
            aExternalDoubleValue <<= (double)nScrollValue;
        else
        {
            OSL_ENSURE( sal_False, "translateControlIntToExternalDoubleValue: no integer scroll value!" );
            // aExternalDoubleValue is void here, which is okay for this purpose ...
        }

        return aExternalDoubleValue;
    }

    //====================================================================
	//= OScrollBarModel
	//====================================================================
	//--------------------------------------------------------------------
    DBG_NAME( OScrollBarModel )
    //--------------------------------------------------------------------
    OScrollBarModel::OScrollBarModel( const Reference<XMultiServiceFactory>& _rxFactory )
        :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_SCROLLBAR, VCL_CONTROL_SCROLLBAR, sal_True, sal_True, sal_False )
        ,m_nDefaultScrollValue( 0 )
    {
	    DBG_CTOR( OScrollBarModel, NULL );

	    m_nClassId = FormComponentType::SCROLLBAR;
        initValueProperty( PROPERTY_SCROLL_VALUE, PROPERTY_ID_SCROLL_VALUE );
    }

    //--------------------------------------------------------------------
    OScrollBarModel::OScrollBarModel( const OScrollBarModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
	    :OBoundControlModel( _pOriginal, _rxFactory )
    {
	    DBG_CTOR( OScrollBarModel, NULL );
        m_nDefaultScrollValue = _pOriginal->m_nDefaultScrollValue;
    }

    //--------------------------------------------------------------------
    OScrollBarModel::~OScrollBarModel( )
    {
        DBG_DTOR( OScrollBarModel, NULL );
    }

    //--------------------------------------------------------------------
    IMPLEMENT_SERVICE_REGISTRATION_2( OScrollBarModel, OControlModel, FRM_SUN_COMPONENT_SCROLLBAR, BINDABLE_INTEGER_VALUE_RANGE )
        // note that we're passing OControlModel as "base class". This is because
        // OBoundControlModel, our real base class, claims to support the DataAwareControlModel
        // service, which isn't really true for us. We only derive from this class
        // to benefit from the functionality for binding to spreadsheet cells

    //------------------------------------------------------------------------------
    IMPLEMENT_DEFAULT_CLONING( OScrollBarModel )

    //------------------------------------------------------------------------------
    void SAL_CALL OScrollBarModel::disposing()
    {
	    OBoundControlModel::disposing();
    }

    //--------------------------------------------------------------------
    void OScrollBarModel::describeFixedProperties( Sequence< Property >& _rProps ) const
    {
	    BEGIN_DESCRIBE_PROPERTIES( 3, OControlModel )
            DECL_PROP1( DEFAULT_SCROLL_VALUE, sal_Int32,       BOUND );
            DECL_PROP1( TABINDEX,             sal_Int16,       BOUND );
            DECL_PROP2( CONTROLSOURCEPROPERTY,::rtl::OUString, READONLY, TRANSIENT );
	    END_DESCRIBE_PROPERTIES();
    }

    //------------------------------------------------------------------------------
    void OScrollBarModel::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
    {
	    switch ( _nHandle )
	    {
		    case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
                _rValue <<= m_nDefaultScrollValue;
                break;

            default:
			    OBoundControlModel::getFastPropertyValue( _rValue, _nHandle );
	    }
    }

    //------------------------------------------------------------------------------
    void OScrollBarModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
    {
	    switch ( _nHandle )
	    {
		    case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
                OSL_VERIFY( _rValue >>= m_nDefaultScrollValue );
    			resetNoBroadcast();
			    break;

		    default:
			    OBoundControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
	    }
    }

    //------------------------------------------------------------------------------
    sal_Bool OScrollBarModel::convertFastPropertyValue(
			    Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue )
			    throw ( IllegalArgumentException )
    {
	    sal_Bool bModified( sal_False );
	    switch ( _nHandle )
	    {
		    case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
			    bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, m_nDefaultScrollValue );
			    break;

            default:
			    bModified = OBoundControlModel::convertFastPropertyValue( _rConvertedValue, _rOldValue, _nHandle, _rValue );
			    break;
	    }
	    return bModified;
    }

    //--------------------------------------------------------------------
    Any OScrollBarModel::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const
    {
        Any aReturn;

        switch ( _nHandle )
        {
        case PROPERTY_ID_DEFAULT_SCROLL_VALUE:
            aReturn <<= (sal_Int32)0;
            break;

        default:
            aReturn = OBoundControlModel::getPropertyDefaultByHandle( _nHandle );
            break;
        }

        return aReturn;
    }

    //------------------------------------------------------------------------------
    Any OScrollBarModel::translateDbColumnToControlValue( )
    {
        OSL_ENSURE( sal_False, "OScrollBarModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
        return Any();
    }

    //------------------------------------------------------------------------------
    sal_Bool OScrollBarModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
    {
        OSL_ENSURE( sal_False, "OScrollBarModel::commitControlValueToDbColumn: never to be called (we're not bound)!" );
        return sal_True;
    }

    //------------------------------------------------------------------------------
    Any OScrollBarModel::getDefaultForReset() const
    {
        return makeAny( (sal_Int32)m_nDefaultScrollValue );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SAL_CALL OScrollBarModel::getServiceName() throw( RuntimeException )
    {
	    return FRM_SUN_COMPONENT_SCROLLBAR;
    }

    //--------------------------------------------------------------------
    void SAL_CALL OScrollBarModel::write( const Reference< XObjectOutputStream >& _rxOutStream )
	    throw( IOException, RuntimeException )
    {
	    OBoundControlModel::write( _rxOutStream );
        ::osl::MutexGuard aGuard( m_aMutex );

        OStreamSection aSection( Reference< XDataOutputStream >( _rxOutStream, UNO_QUERY ) );

        // version
	    _rxOutStream->writeShort( 0x0001 );

        // properties
	    _rxOutStream << m_nDefaultScrollValue;
	    writeHelpTextCompatibly( _rxOutStream );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OScrollBarModel::read( const Reference< XObjectInputStream>& _rxInStream ) throw( IOException, RuntimeException )
    {
	    OBoundControlModel::read( _rxInStream );
	    ::osl::MutexGuard aGuard( m_aMutex );

	    // version
        {
            OStreamSection aSection( Reference< XDataInputStream >( _rxInStream, UNO_QUERY ) );

            sal_uInt16 nVersion = _rxInStream->readShort();
            if ( nVersion == 0x0001 )
            {
	            _rxInStream >> m_nDefaultScrollValue;
	            readHelpTextCompatibly( _rxInStream );
            }
            else
			    defaultCommonProperties();

            // here, everything in the stream section which is left will be skipped
        }
    }

    //--------------------------------------------------------------------
    Any OScrollBarModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
    {
        return translateExternalDoubleToControlIntValue( _rExternalValue, m_xAggregateSet, 
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollValueMin" ) ),
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScrollValueMax" ) ) );
    }

    //--------------------------------------------------------------------
    Any OScrollBarModel::translateControlValueToExternalValue( ) const
    {
        // by definition, the base class simply obtains the property value
        return translateControlIntToExternalDoubleValue( OBoundControlModel::translateControlValueToExternalValue() );
    }

    //--------------------------------------------------------------------
    Sequence< Type > OScrollBarModel::getSupportedBindingTypes()
    {
        return Sequence< Type >( &::getCppuType( static_cast< double* >( NULL ) ), 1 );
    }

//........................................................................
}   // namespace frm
//........................................................................
