/**************************************************************
 *
 * 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_extensions.hxx"
#include "pushbuttonnavigation.hxx"
#include <com/sun/star/form/FormButtonType.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include "formstrings.hxx"
#include <comphelper/extract.hxx>
#include <comphelper/property.hxx>
#include <osl/diagnose.h>
#include <tools/diagnose_ex.h>

//............................................................................
namespace pcr
{
//............................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::form;

    //------------------------------------------------------------------------
    namespace
    {
        static const sal_Int32 s_nFirstVirtualButtonType = 1 + (sal_Int32)FormButtonType_URL;

        static const sal_Char* pNavigationURLs[] =
        {
	        ".uno:FormController/moveToFirst",
	        ".uno:FormController/moveToPrev",
	        ".uno:FormController/moveToNext",
	        ".uno:FormController/moveToLast",
	        ".uno:FormController/saveRecord",
	        ".uno:FormController/undoRecord",
	        ".uno:FormController/moveToNew",
	        ".uno:FormController/deleteRecord",
	        ".uno:FormController/refreshForm",
            NULL
        };

        static sal_Int32 lcl_getNavigationURLIndex( const ::rtl::OUString& _rNavURL )
        {
            const sal_Char** pLookup = pNavigationURLs;
            while ( *pLookup )
            {
                if ( _rNavURL.equalsAscii( *pLookup ) )
                    return pLookup - pNavigationURLs;
                ++pLookup;
            }
            return -1;
        }

        static const sal_Char* lcl_getNavigationURL( sal_Int32 _nButtonTypeIndex )
        {
            const sal_Char** pLookup = pNavigationURLs;
            while ( _nButtonTypeIndex-- && *pLookup++ )
                ;
            OSL_ENSURE( *pLookup, "lcl_getNavigationURL: invalid index!" );
            return *pLookup;
        }
    }

    //========================================================================
    //= PushButtonNavigation
    //========================================================================
    //------------------------------------------------------------------------
    PushButtonNavigation::PushButtonNavigation( const Reference< XPropertySet >& _rxControlModel )
        :m_xControlModel( _rxControlModel )
        ,m_bIsPushButton( sal_False )
    {
        OSL_ENSURE( m_xControlModel.is(), "PushButtonNavigation::PushButtonNavigation: invalid control model!" );

        try
        {
			m_bIsPushButton = ::comphelper::hasProperty( PROPERTY_BUTTONTYPE, m_xControlModel );
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::PushButtonNavigation: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    sal_Int32 PushButtonNavigation::implGetCurrentButtonType() const SAL_THROW((Exception))
    {
        sal_Int32 nButtonType = FormButtonType_PUSH;
        if ( !m_xControlModel.is() )
            return nButtonType;
        OSL_VERIFY( ::cppu::enum2int( nButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) );

        if ( nButtonType == FormButtonType_URL )
        {
            // there's a chance that this is a "virtual" button type
            // (which are realized by special URLs)
            ::rtl::OUString sTargetURL;
            m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL ) >>= sTargetURL;

            sal_Int32 nNavigationURLIndex = lcl_getNavigationURLIndex( sTargetURL );
            if ( nNavigationURLIndex >= 0)
                // it actually *is* a virtual button type
                nButtonType = s_nFirstVirtualButtonType + nNavigationURLIndex;
        }
        return nButtonType;
    }

    //------------------------------------------------------------------------
    Any PushButtonNavigation::getCurrentButtonType() const SAL_THROW(())
    {
        OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonType: not expected to be called for forms!" );
        Any aReturn;

        try
        {
            aReturn <<= implGetCurrentButtonType();
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonType: caught an exception!" );
        }
        return aReturn;
    }

    //------------------------------------------------------------------------
    void PushButtonNavigation::setCurrentButtonType( const Any& _rValue ) const SAL_THROW(())
    {
        OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::setCurrentButtonType: not expected to be called for forms!" );
        if ( !m_xControlModel.is() )
            return;

        try
        {
            sal_Int32 nButtonType = FormButtonType_PUSH;
            OSL_VERIFY( ::cppu::enum2int( nButtonType, _rValue ) );
            ::rtl::OUString sTargetURL;

            bool bIsVirtualButtonType = nButtonType >= s_nFirstVirtualButtonType;
            if ( bIsVirtualButtonType )
            {
                const sal_Char* pURL = lcl_getNavigationURL( nButtonType - s_nFirstVirtualButtonType );
                sTargetURL = ::rtl::OUString::createFromAscii( pURL );

                nButtonType = FormButtonType_URL;
            }

            m_xControlModel->setPropertyValue( PROPERTY_BUTTONTYPE, makeAny( static_cast< FormButtonType >( nButtonType ) ) );
            m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, makeAny( sTargetURL ) );
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentButtonType: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    PropertyState PushButtonNavigation::getCurrentButtonTypeState( ) const SAL_THROW(())
    {
        OSL_ENSURE( m_bIsPushButton, "PushButtonNavigation::getCurrentButtonTypeState: not expected to be called for forms!" );
        PropertyState eState = PropertyState_DIRECT_VALUE;

        try
        {
            Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY );
            if ( xStateAccess.is() )
            {
                // let's see what the model says about the ButtonType property
                eState = xStateAccess->getPropertyState( PROPERTY_BUTTONTYPE );
                if ( eState == PropertyState_DIRECT_VALUE )
                {
                    sal_Int32 nRealButtonType = FormButtonType_PUSH;
                    OSL_VERIFY( ::cppu::enum2int( nRealButtonType, m_xControlModel->getPropertyValue( PROPERTY_BUTTONTYPE ) ) );
                    // perhaps it's one of the virtual button types?
                    if ( FormButtonType_URL == nRealButtonType )
                    {
                        // yes, it is -> rely on the state of the URL property
                        eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL );
                    }
                }
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentButtonTypeState: caught an exception!" );
        }

        return eState;
    }

    //------------------------------------------------------------------------
    Any PushButtonNavigation::getCurrentTargetURL() const SAL_THROW(())
    {
        Any aReturn;
        if ( !m_xControlModel.is() )
            return aReturn;

        try
        {
            aReturn = m_xControlModel->getPropertyValue( PROPERTY_TARGET_URL );
            if ( m_bIsPushButton )
            {
                sal_Int32 nCurrentButtonType = implGetCurrentButtonType();
                bool bIsVirtualButtonType = nCurrentButtonType >= s_nFirstVirtualButtonType;
                if ( bIsVirtualButtonType )
                {
                    // pretend (to the user) that there's no URL set - since
                    // virtual button types imply a special (technical) URL which
                    // the user should not see
                    aReturn <<= ::rtl::OUString();
                }
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::getCurrentTargetURL: caught an exception!" );
        }
        return aReturn;
    }

    //------------------------------------------------------------------------
    void PushButtonNavigation::setCurrentTargetURL( const Any& _rValue ) const SAL_THROW(())
    {
        if ( !m_xControlModel.is() )
            return;

        try
        {
            m_xControlModel->setPropertyValue( PROPERTY_TARGET_URL, _rValue );
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    PropertyState PushButtonNavigation::getCurrentTargetURLState( ) const SAL_THROW(())
    {
        PropertyState eState = PropertyState_DIRECT_VALUE;

        try
        {
            Reference< XPropertyState > xStateAccess( m_xControlModel, UNO_QUERY );
            if ( xStateAccess.is() )
            {
                eState = xStateAccess->getPropertyState( PROPERTY_TARGET_URL );
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "PushButtonNavigation::setCurrentTargetURL: caught an exception!" );
        }

        return eState;
    }

    //------------------------------------------------------------------------
    bool PushButtonNavigation::currentButtonTypeIsOpenURL() const
    {
        sal_Int32 nButtonType( FormButtonType_PUSH );
        try
        {
            nButtonType = implGetCurrentButtonType();
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return nButtonType == FormButtonType_URL;
    }

    //------------------------------------------------------------------------
    bool PushButtonNavigation::hasNonEmptyCurrentTargetURL() const
    {
        ::rtl::OUString sTargetURL;
        OSL_VERIFY( getCurrentTargetURL() >>= sTargetURL );
        return sTargetURL.getLength() != 0;
    }

//............................................................................
}   // namespace pcr
//............................................................................
