/**************************************************************
 *
 * 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 "commoncontrol.hxx"
#include "pcrcommon.hxx"
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/combobox.hxx>
#include <toolkit/helper/vclunohelper.hxx>

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

    /** === begin UNO using === **/
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::inspection::XPropertyControlContext;
    using ::com::sun::star::awt::XWindow;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::inspection::XPropertyControl;
    /** === end UNO using === **/

	//==================================================================
	//= ControlHelper
	//==================================================================
	//------------------------------------------------------------------
	ControlHelper::ControlHelper( Window* _pControlWindow, sal_Int16 _nControlType, XPropertyControl& _rAntiImpl, IModifyListener* _pModifyListener )
        :m_pControlWindow( _pControlWindow )
        ,m_nControlType( _nControlType )
        ,m_rAntiImpl( _rAntiImpl )
        ,m_pModifyListener( _pModifyListener )
        ,m_bModified( sal_False )
	{
		DBG_ASSERT( m_pControlWindow != NULL, "ControlHelper::ControlHelper: invalid window!" );
	}

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

    //--------------------------------------------------------------------
    ::sal_Int16 SAL_CALL ControlHelper::getControlType() throw (RuntimeException)
    {
        return m_nControlType;
    }

    //--------------------------------------------------------------------
    Reference< XPropertyControlContext > SAL_CALL ControlHelper::getControlContext() throw (RuntimeException)
    {
        return m_xContext;
    }

    //--------------------------------------------------------------------
    void SAL_CALL ControlHelper::setControlContext( const Reference< XPropertyControlContext >& _controlcontext ) throw (RuntimeException)
    {
        m_xContext = _controlcontext;
    }

    //--------------------------------------------------------------------
    Reference< XWindow > SAL_CALL ControlHelper::getControlWindow() throw (RuntimeException)
    {
        return VCLUnoHelper::GetInterface( m_pControlWindow );
    }

    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL ControlHelper::isModified(  ) throw (RuntimeException)
    {
        return m_bModified;
    }

    //--------------------------------------------------------------------
    void SAL_CALL ControlHelper::notifyModifiedValue(  ) throw (RuntimeException)
    {
		if ( isModified() && m_xContext.is() )
        {
            try
            {
			    m_xContext->valueChanged( &m_rAntiImpl );
		        m_bModified = sal_False;
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

    //------------------------------------------------------------------
    void SAL_CALL ControlHelper::dispose()
    {
        DELETEZ( m_pControlWindow );
    }

    //------------------------------------------------------------------
	void ControlHelper::autoSizeWindow()
	{
        OSL_PRECOND( m_pControlWindow, "ControlHelper::autoSizeWindow: no window!" );
        if ( !m_pControlWindow )
            return;

		ComboBox aComboBox(m_pControlWindow, WB_DROPDOWN);
		aComboBox.SetPosSizePixel(Point(0,0), Size(100,100));
		m_pControlWindow->SetSizePixel(aComboBox.GetSizePixel());

        // TODO/UNOize: why do the controls this themselves? Shouldn't this be the task
        // of the browser listbox/line?
	}

	//------------------------------------------------------------------
    void ControlHelper::impl_activateNextControl_nothrow() const
    {
        try
        {
            if ( m_xContext.is() )
                m_xContext->activateNextControl( const_cast< XPropertyControl* >( &m_rAntiImpl ) );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

	//------------------------------------------------------------------
	bool ControlHelper::handlePreNotify(NotifyEvent& rNEvt)
	{
		if (EVENT_KEYINPUT == rNEvt.GetType())
		{
			const KeyCode& aKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
			sal_uInt16 nKey = aKeyCode.GetCode();

			if (nKey == KEY_RETURN && !aKeyCode.IsShift())
			{
				LoseFocusHdl(m_pControlWindow);
                impl_activateNextControl_nothrow();
				return true;
			}
		}
        return false;
	}

	//------------------------------------------------------------------
	IMPL_LINK( ControlHelper, ModifiedHdl, Window*, /*_pWin*/ )
	{
        if ( m_pModifyListener )
            m_pModifyListener->modified();
		return 0;
	}

	//------------------------------------------------------------------
	IMPL_LINK( ControlHelper, GetFocusHdl, Window*, /*_pWin*/ )
	{
        try
        {
            if ( m_xContext.is() )
                m_xContext->focusGained( &m_rAntiImpl );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
		return 0;
	}

	//------------------------------------------------------------------
	IMPL_LINK( ControlHelper, LoseFocusHdl, Window*, /*_pWin*/ )
	{
        // TODO/UNOize: should this be outside the default control's implementations? If somebody
        // has an own control implementation, which does *not* do this - would this be allowed?
        // If not, then we must move this logic out of here.
		notifyModifiedValue();
		return 0;
	}

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