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

#ifndef _TOOLKIT_ROADMAP_CONTROL_HXX
#include <toolkit/controls/roadmapcontrol.hxx>
#endif
#include <toolkit/helper/unopropertyarrayhelper.hxx>
#include <toolkit/helper/property.hxx>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#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::container;

//	----------------------------------------------------
//  helper
//	----------------------------------------------------

static void lcl_throwIllegalArgumentException( )
{	// throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
	throw IllegalArgumentException();
}

static void lcl_throwIndexOutOfBoundsException( )
{	// throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
	throw IndexOutOfBoundsException();
}

	// ===================================================================
	// = UnoControlRoadmapModel
	// ===================================================================
	// -------------------------------------------------------------------
	UnoControlRoadmapModel::UnoControlRoadmapModel( const Reference< XMultiServiceFactory >& i_factory )
        :UnoControlRoadmapModel_Base( i_factory )
        ,maContainerListeners( *this )
	{
		ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
		ImplRegisterProperty( BASEPROPERTY_BORDER );
		ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
		ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
		ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
		ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
		ImplRegisterProperty( BASEPROPERTY_HELPURL );
		ImplRegisterProperty( BASEPROPERTY_IMAGEURL );
		ImplRegisterProperty( BASEPROPERTY_GRAPHIC );
        ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
		ImplRegisterProperty( BASEPROPERTY_COMPLETE );
		ImplRegisterProperty( BASEPROPERTY_ACTIVATED );
		ImplRegisterProperty( BASEPROPERTY_CURRENTITEMID );
        ImplRegisterProperty( BASEPROPERTY_TABSTOP );
        ImplRegisterProperty( BASEPROPERTY_TEXT );
	}

	// -------------------------------------------------------------------
	::rtl::OUString UnoControlRoadmapModel::getServiceName() throw(RuntimeException)
	{
		return ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmapModel );
	}


	// -------------------------------------------------------------------
	Any UnoControlRoadmapModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
	{
		Any aReturn;
		switch (nPropId)
		{
                case BASEPROPERTY_COMPLETE:
                    aReturn <<= (sal_Bool) sal_True;
                    break;
                case BASEPROPERTY_ACTIVATED:
                    aReturn <<= (sal_Bool) sal_True;
                    break;
                case BASEPROPERTY_CURRENTITEMID:
                    aReturn <<= (sal_Int16) -1;
                    break;
                case BASEPROPERTY_TEXT:
                   break;
                case BASEPROPERTY_BORDER:
                    aReturn <<= (sal_Int16) 2;              // No Border
                    break;
			    case BASEPROPERTY_DEFAULTCONTROL:
                    aReturn <<= ::rtl::OUString( ::rtl::OUString::createFromAscii( szServiceName_UnoControlRoadmap ) );
                    break;
			default : aReturn = UnoControlRoadmapModel_Base::ImplGetDefaultValue( nPropId ); break;
		}

		return aReturn;
	}


    Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstance(  ) throw (Exception, ::com::sun::star::uno::RuntimeException)
    {
		ORoadmapEntry* pRoadmapItem = new ORoadmapEntry();
	    Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem;
	    return xNewRoadmapItem;
    }


    Reference< XInterface > SAL_CALL UnoControlRoadmapModel::createInstanceWithArguments( const Sequence< Any >& /*aArguments*/ ) throw (Exception, RuntimeException)
    {
        // Todo: implementation of the arguments handling
		ORoadmapEntry* pRoadmapItem = new ORoadmapEntry();
	    Reference< XInterface > xNewRoadmapItem = (::cppu::OWeakObject*)pRoadmapItem;
	    return xNewRoadmapItem;
    }


 IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlRoadmapModel, UnoControlRoadmapModel_Base, UnoControlRoadmapModel_IBase )


	// -------------------------------------------------------------------
    ::com::sun::star::uno::Any	SAL_CALL UnoControlRoadmapModel::queryAggregation( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
    {
        Any aRet = UnoControlRoadmapModel_Base::queryAggregation( rType );
        if ( !aRet.hasValue() )
            aRet = UnoControlRoadmapModel_IBase::queryInterface( rType );
 	    return aRet;
    }


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


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


    sal_Int32 SAL_CALL UnoControlRoadmapModel::getCount() throw(RuntimeException)
    {
        return maRoadmapItems.size();
    }

    Any SAL_CALL UnoControlRoadmapModel::getByIndex( sal_Int32 Index ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
    {
        if (( Index >= (sal_Int32)maRoadmapItems.size()) || (Index < 0))
            lcl_throwIndexOutOfBoundsException( );
        Any aAny;
        aAny = makeAny( maRoadmapItems.at( Index ));
        return aAny;
    }



    void UnoControlRoadmapModel::MakeRMItemValidation( sal_Int32 Index, Reference< XInterface > xRoadmapItem )
    {
        if ((Index > (sal_Int32)maRoadmapItems.size()) || ( Index < 0 ) )
            lcl_throwIndexOutOfBoundsException( );
        if ( !xRoadmapItem.is() )
		    lcl_throwIllegalArgumentException();
        Reference< XServiceInfo > xServiceInfo( xRoadmapItem, UNO_QUERY );
        sal_Bool bIsRoadmapItem = xServiceInfo->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.RoadmapItem" ) );
        if ( !bIsRoadmapItem )
    	    lcl_throwIllegalArgumentException();
    }


    void UnoControlRoadmapModel::SetRMItemDefaultProperties( const sal_Int32 , Reference< XInterface > xRoadmapItem)
    {
		Any	aAny;
        Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY );
        Reference< XPropertySet > xProps( xRoadmapItem, UNO_QUERY );
	    if ( xProps.is() )
        {
            sal_Int32 LocID = 0;
            Any aValue = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) );
            aValue >>= LocID;
            if (LocID < 0)              // index may not be smaller than zero
            {
                aAny <<= GetUniqueID();
                xPropertySet->setPropertyValue( ::rtl::OUString::createFromAscii( "ID" ), aAny );
            }
        }
    }


// The performance of this method could certainly be improved.
// As long as only vectors with up to 10 elements are
// involved it should be sufficient
       sal_Int32 UnoControlRoadmapModel::GetUniqueID()
      {
          Any aAny;
          sal_Bool bIncrement = sal_True;
          sal_Int32 CurID = 0;
          sal_Int32 n_CurItemID = 0;
          Reference< XInterface > CurRoadmapItem;
          while ( bIncrement )
          {
 	      bIncrement = sal_False;
              for ( RoadmapItemHolderList::iterator i = maRoadmapItems.begin(); i < maRoadmapItems.end(); i++ )
              {
                CurRoadmapItem = *i;
                Reference< XPropertySet > xPropertySet( CurRoadmapItem, UNO_QUERY );
                aAny = xPropertySet->getPropertyValue( ::rtl::OUString::createFromAscii( "ID" ) );
                aAny >>= n_CurItemID;
                if (n_CurItemID == CurID)
                {
                    bIncrement = sal_True;
                    CurID++;
                    break;
                }
            }
        }
        return CurID;
    }


    ContainerEvent UnoControlRoadmapModel::GetContainerEvent(sal_Int32 Index, Reference< XInterface > xRoadmapItem)
    {
	    ContainerEvent aEvent;
	    aEvent.Source = *this;
	    aEvent.Element <<= xRoadmapItem;
        aEvent.Accessor = makeAny(Index);
        return aEvent;
    }


    sal_Int16 UnoControlRoadmapModel::GetCurrentItemID( Reference< XPropertySet > xPropertySet )
    {
        Any aAny = xPropertySet->getPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ) );
        sal_Int16 n_CurrentItemID = 0;
        aAny >>= n_CurrentItemID;
        return n_CurrentItemID;
    }


    void SAL_CALL UnoControlRoadmapModel::insertByIndex( const sal_Int32 Index, const Any& _Element)
                                    throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
    {
        if ( ( Index >= ( (sal_Int32)maRoadmapItems.size() + 1 ) ) || (Index < 0))
            lcl_throwIndexOutOfBoundsException( );
        Reference< XInterface > xRoadmapItem;
        _Element >>= xRoadmapItem;
        MakeRMItemValidation( Index, xRoadmapItem);
        SetRMItemDefaultProperties( Index, xRoadmapItem );
        maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem);
	    ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
	    maContainerListeners.elementInserted( aEvent );
        Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY );
        sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet );
        if ( Index <= n_CurrentItemID )
        {
            Any aAny;
            aAny <<= ( sal_Int16 ) ( n_CurrentItemID + 1 );
            xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
        }
    }



    void SAL_CALL UnoControlRoadmapModel::removeByIndex( sal_Int32 Index)
                                                throw	 (IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
    {
        if (( Index > (sal_Int32)maRoadmapItems.size()) || (Index < 0))
            lcl_throwIndexOutOfBoundsException( );
        Reference< XInterface > xRoadmapItem;
        maRoadmapItems.erase( maRoadmapItems.begin() + Index );
	    ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
	    maContainerListeners.elementRemoved( aEvent );
        Reference< XPropertySet > xPropertySet( (XAggregation*) (::cppu::OWeakAggObject*)this, UNO_QUERY );
        sal_Int16 n_CurrentItemID = GetCurrentItemID( xPropertySet );
        Any aAny;
        if ( Index <= n_CurrentItemID )
        {
            if ( n_CurrentItemID >= (sal_Int32)maRoadmapItems.size() )
            {
                n_CurrentItemID = sal::static_int_cast< sal_Int16 >(
                    maRoadmapItems.size()-1);
                if ( n_CurrentItemID < 0 )
                    return;
                aAny <<= n_CurrentItemID;
            }
            else if (Index == n_CurrentItemID)
                aAny <<= ( sal_Int16 ) -1;
            else if( Index < n_CurrentItemID)
                aAny <<= ( sal_Int16 ) ( n_CurrentItemID - 1 );
            xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
        }
    }


	void SAL_CALL UnoControlRoadmapModel::replaceByIndex( const sal_Int32 Index, const Any& _Element)
                                throw (IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
    {
        Reference< XInterface > xRoadmapItem;
        _Element >>= xRoadmapItem;
        MakeRMItemValidation( Index, xRoadmapItem);
        SetRMItemDefaultProperties( Index, xRoadmapItem );
        maRoadmapItems.erase( maRoadmapItems.begin() + Index );
        maRoadmapItems.insert( maRoadmapItems.begin() + Index, xRoadmapItem);        //push_back( xRoadmapItem );
	    ContainerEvent aEvent = GetContainerEvent(Index, xRoadmapItem);
	    maContainerListeners.elementReplaced( aEvent );
    }


	Type SAL_CALL UnoControlRoadmapModel::getElementType() throw(RuntimeException)
    {
	    Type aType = getCppuType( ( Reference< XPropertySet>* ) NULL );
	    return aType;
    }


    sal_Bool SAL_CALL UnoControlRoadmapModel::hasElements() throw(RuntimeException)
    {
        return !maRoadmapItems.empty();
    }


    void SAL_CALL UnoControlRoadmapModel::addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
    {
	    maContainerListeners.addInterface( xListener );
    }

    void SAL_CALL UnoControlRoadmapModel::removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException)
    {
	    maContainerListeners.removeInterface( xListener );
    }

    // ===================================================================
	// = UnoRoadmapControl
	// ===================================================================
	// -------------------------------------------------------------------
    UnoRoadmapControl::UnoRoadmapControl( const Reference< XMultiServiceFactory >& i_factory )
        :UnoControlRoadmap_Base( i_factory )
        ,maItemListeners( *this )
	{
	}

IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase )
IMPLEMENT_FORWARD_XINTERFACE2( UnoRoadmapControl, UnoControlRoadmap_Base, UnoControlRoadmap_IBase )


sal_Bool SAL_CALL UnoRoadmapControl::setModel(const Reference< XControlModel >& _rModel) throw ( RuntimeException )
    {


   	    Reference< XContainer > xC( getModel(), UNO_QUERY );
	    if ( xC.is() )
		    xC->removeContainerListener( this );

        sal_Bool bReturn = UnoControlBase::setModel( _rModel );

	    xC = xC.query( getModel());
	    if ( xC.is() )
		    xC->addContainerListener( this );

        return bReturn;
    }


	// -------------------------------------------------------------------
	::rtl::OUString UnoRoadmapControl::GetComponentServiceName()
	{
		return ::rtl::OUString::createFromAscii( "Roadmap" );
	}



    void UnoRoadmapControl::dispose() throw(RuntimeException)
    {
	    EventObject aEvt;
	    aEvt.Source = (::cppu::OWeakObject*)this;
	    maItemListeners.disposeAndClear( aEvt );
	    UnoControl::dispose();
    }



void UnoRoadmapControl::elementInserted( const ContainerEvent& rEvent )throw(RuntimeException)
{
    Reference< XInterface > xRoadmapItem;
    rEvent.Element >>= xRoadmapItem;
    Reference< XPropertySet > xRoadmapPropertySet( xRoadmapItem, UNO_QUERY );
	if ( xRoadmapPropertySet.is() )
        xRoadmapPropertySet->addPropertyChangeListener( rtl::OUString(), this );

    Reference< XContainerListener >  xPeer(getPeer(), UNO_QUERY);
    if ( xPeer.is() )
    {
        xPeer->elementInserted( rEvent );
		Reference < XPropertySet > xPropertySet( xPeer, UNO_QUERY );
        if ( xPropertySet.is() )
		    xPropertySet->addPropertyChangeListener( rtl::OUString(), this );
    }
}


void UnoRoadmapControl::elementRemoved( const ContainerEvent& rEvent )throw(RuntimeException)
{
    Reference< XContainerListener >  xPeer(getPeer(), UNO_QUERY);
    if ( xPeer.is() )
        xPeer->elementRemoved( rEvent );
    Reference< XInterface > xRoadmapItem;
    rEvent.Element >>= xRoadmapItem;
    Reference< XPropertySet > xPropertySet( xRoadmapItem, UNO_QUERY );
	if ( xPropertySet.is() )
        xPropertySet->removePropertyChangeListener( rtl::OUString(), this );
}


void UnoRoadmapControl::elementReplaced( const ContainerEvent& rEvent )throw(RuntimeException)
{
    Reference< XContainerListener >  xPeer(getPeer(), UNO_QUERY);
    if ( xPeer.is() )
        xPeer->elementReplaced( rEvent );
}


void SAL_CALL UnoRoadmapControl::itemStateChanged( const ItemEvent& rEvent ) throw (RuntimeException)
{
    sal_Int16 CurItemIndex = sal::static_int_cast< sal_Int16 >(rEvent.ItemId);
    Any aAny;
    aAny <<= CurItemIndex;
    Reference< XControlModel > xModel( getModel( ), UNO_QUERY );
    Reference< XPropertySet > xPropertySet( xModel, UNO_QUERY );
    xPropertySet->setPropertyValue( GetPropertyName( BASEPROPERTY_CURRENTITEMID ), aAny );
    if ( maItemListeners.getLength() )
		maItemListeners.itemStateChanged( rEvent );
}


void SAL_CALL UnoRoadmapControl::addItemListener( const Reference< XItemListener >& l ) throw (RuntimeException)
{
    maItemListeners.addInterface( l );
	if( getPeer().is() && maItemListeners.getLength() == 1 )
	{
		Reference < XItemEventBroadcaster > xRoadmap( getPeer(), UNO_QUERY );
		xRoadmap->addItemListener( this );
	}
}


void SAL_CALL UnoRoadmapControl::removeItemListener( const Reference< XItemListener >& l ) throw (RuntimeException)
{
	if( getPeer().is() && maItemListeners.getLength() == 1 )
	{
		Reference < XItemEventBroadcaster >  xRoadmap( getPeer(), UNO_QUERY );
		xRoadmap->removeItemListener( this );
	}

    maItemListeners.removeInterface( l );
}


void SAL_CALL UnoRoadmapControl::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException)
{
    Reference< XPropertyChangeListener >  xPeer(getPeer(), UNO_QUERY);
    if ( xPeer.is() )
        xPeer->propertyChange( evt );
}

}

