/**************************************************************
 * 
 * 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 "GroupManager.hxx"
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <comphelper/property.hxx>
#include <comphelper/uno3.hxx>
#include <tools/solar.h>
#include <tools/debug.hxx>

#include "property.hrc"

#include <algorithm>

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

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::form;

namespace
{
    bool isRadioButton( const Reference< XPropertySet >& _rxComponent )
    {
        bool bIs = false;
	    if ( hasProperty( PROPERTY_CLASSID, _rxComponent ) )
        {
            sal_Int16 nClassId = FormComponentType::CONTROL;
            _rxComponent->getPropertyValue( PROPERTY_CLASSID ) >>= nClassId;
            if ( nClassId == FormComponentType::RADIOBUTTON )
                bIs = true;
        }
        return bIs;
    }
}

//========================================================================
// class OGroupCompAcc
//========================================================================
//------------------------------------------------------------------
OGroupCompAcc::OGroupCompAcc(const Reference<XPropertySet>& rxElement, const OGroupComp& _rGroupComp )
			   :m_xComponent( rxElement )
			   ,m_aGroupComp( _rGroupComp )
{
}

//------------------------------------------------------------------
sal_Bool OGroupCompAcc::operator==( const OGroupCompAcc& rCompAcc ) const
{
	return (m_xComponent == rCompAcc.GetComponent());
}

//------------------------------------------------------------------
class OGroupCompAccLess : public ::std::binary_function<OGroupCompAcc, OGroupCompAcc, sal_Bool>
{
public:
	sal_Bool operator() (const OGroupCompAcc& lhs, const OGroupCompAcc& rhs) const
	{
		return
			reinterpret_cast<sal_Int64>(lhs.m_xComponent.get())
		<	reinterpret_cast<sal_Int64>(rhs.m_xComponent.get());
	}
};

//========================================================================
// class OGroupComp
//========================================================================

//------------------------------------------------------------------
OGroupComp::OGroupComp()
    :m_nPos( -1 )
    ,m_nTabIndex( 0 )
{
}

//------------------------------------------------------------------
OGroupComp::OGroupComp(const OGroupComp& _rSource)
    :m_aName( _rSource.m_aName )
    ,m_xComponent( _rSource.m_xComponent )
    ,m_xControlModel(_rSource.m_xControlModel)
    ,m_nPos( _rSource.m_nPos )
    ,m_nTabIndex( _rSource.m_nTabIndex )
{
}

//------------------------------------------------------------------
OGroupComp::OGroupComp(const Reference<XPropertySet>& rxSet, sal_Int32 nInsertPos )
    :m_xComponent( rxSet )
    ,m_xControlModel(rxSet,UNO_QUERY)
    ,m_nPos( nInsertPos )
    ,m_nTabIndex(0)
{
	if (m_xComponent.is())
	{
		if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) )
			// Indices kleiner 0 werden wie 0 behandelt
			m_nTabIndex = Max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0));

		m_xComponent->getPropertyValue( PROPERTY_NAME ) >>= m_aName;
	}
}

//------------------------------------------------------------------
sal_Bool OGroupComp::operator==( const OGroupComp& rComp ) const
{
	return m_nTabIndex == rComp.GetTabIndex() && m_nPos == rComp.GetPos();
}

//------------------------------------------------------------------
class OGroupCompLess : public ::std::binary_function<OGroupComp, OGroupComp, sal_Bool>
{
public:
	sal_Bool operator() (const OGroupComp& lhs, const OGroupComp& rhs) const
	{
		sal_Bool bResult;
		// TabIndex von 0 wird hinten einsortiert
		if (lhs.m_nTabIndex == rhs.GetTabIndex())
			bResult = lhs.m_nPos < rhs.GetPos();
		else if (lhs.m_nTabIndex && rhs.GetTabIndex())
			bResult = lhs.m_nTabIndex < rhs.GetTabIndex();
		else
			bResult = lhs.m_nTabIndex != 0;
		return bResult;
	}
};

//========================================================================
// class OGroup
//========================================================================

DBG_NAME(OGroup)
//------------------------------------------------------------------
OGroup::OGroup( const ::rtl::OUString& rGroupName )
		:m_aGroupName( rGroupName )
		,m_nInsertPos(0)
{
	DBG_CTOR(OGroup,NULL);
}

#ifdef DBG_UTIL
//------------------------------------------------------------------
OGroup::OGroup( const OGroup& _rSource )
:m_aCompArray(_rSource.m_aCompArray)
	,m_aCompAccArray(_rSource.m_aCompAccArray)
	,m_aGroupName(_rSource.m_aGroupName)
	,m_nInsertPos(_rSource.m_nInsertPos)
{
	DBG_CTOR(OGroup,NULL);
}
#endif

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

//------------------------------------------------------------------
void OGroup::InsertComponent( const Reference<XPropertySet>& xSet )
{
	OGroupComp aNewGroupComp( xSet, m_nInsertPos );
	sal_Int32 nPosInserted = insert_sorted(m_aCompArray, aNewGroupComp, OGroupCompLess());

	OGroupCompAcc aNewGroupCompAcc( xSet, m_aCompArray[nPosInserted] );
	insert_sorted(m_aCompAccArray, aNewGroupCompAcc, OGroupCompAccLess());
	m_nInsertPos++;
}

//------------------------------------------------------------------
void OGroup::RemoveComponent( const Reference<XPropertySet>& rxElement )
{
	sal_Int32 nGroupCompAccPos;
	OGroupCompAcc aSearchCompAcc( rxElement, OGroupComp() );
	if ( seek_entry(m_aCompAccArray, aSearchCompAcc, nGroupCompAccPos, OGroupCompAccLess()) )
	{
		OGroupCompAcc& aGroupCompAcc = m_aCompAccArray[nGroupCompAccPos];
		const OGroupComp& aGroupComp = aGroupCompAcc.GetGroupComponent();

		sal_Int32 nGroupCompPos;
		if ( seek_entry(m_aCompArray, aGroupComp, nGroupCompPos, OGroupCompLess()) )
		{
			m_aCompAccArray.erase( m_aCompAccArray.begin() + nGroupCompAccPos );
			m_aCompArray.erase( m_aCompArray.begin() + nGroupCompPos );

			/*============================================================
			Durch das Entfernen der GroupComp ist die Einfuegeposition
			ungueltig geworden. Sie braucht hier aber nicht angepasst werden,
			da sie fortlaufend vergeben wird und damit immer
			aufsteigend eindeutig ist.
			============================================================*/
		}
		else
		{
			DBG_ERROR( "OGroup::RemoveComponent: Component nicht in Gruppe" );
		}
	}
	else
	{
		DBG_ERROR( "OGroup::RemoveComponent: Component nicht in Gruppe" );
	}
}

//------------------------------------------------------------------
sal_Bool OGroup::operator==( const OGroup& rGroup ) const
{
	return m_aGroupName.equals(rGroup.GetGroupName());
}

//------------------------------------------------------------------
class OGroupLess : public ::std::binary_function<OGroup, OGroup, sal_Bool>
{
public:
	sal_Bool operator() (const OGroup& lhs, const OGroup& rhs) const
	{
		return lhs.m_aGroupName < rhs.m_aGroupName;
	}
};

//------------------------------------------------------------------
Sequence< Reference<XControlModel>  > OGroup::GetControlModels() const
{
	sal_Int32 nLen = m_aCompArray.size();
	Sequence<Reference<XControlModel> > aControlModelSeq( nLen );
	Reference<XControlModel>* pModels = aControlModelSeq.getArray();

	ConstOGroupCompArrIterator aGroupComps = m_aCompArray.begin();
	for (sal_Int32 i = 0; i < nLen; ++i, ++pModels, ++aGroupComps)
	{
		*pModels = aGroupComps->GetControlModel();
	}
	return aControlModelSeq;
}

DBG_NAME(OGroupManager);
//------------------------------------------------------------------
OGroupManager::OGroupManager(const Reference< XContainer >& _rxContainer)
	:m_pCompGroup( new OGroup( ::rtl::OUString::createFromAscii( "AllComponentGroup" ) ) )
	,m_xContainer(_rxContainer)
{
	DBG_CTOR(OGroupManager,NULL);

	increment(m_refCount);
	{
		_rxContainer->addContainerListener(this);
	}
	decrement(m_refCount);
}

//------------------------------------------------------------------
OGroupManager::~OGroupManager()
{
	DBG_DTOR(OGroupManager,NULL);
	// Alle Components und CompGroup loeschen
	delete m_pCompGroup;
}

// XPropertyChangeListener
//------------------------------------------------------------------
void OGroupManager::disposing(const EventObject& evt) throw( RuntimeException )
{
	Reference<XContainer>  xContainer(evt.Source, UNO_QUERY);
	if (xContainer.get() == m_xContainer.get())
	{
		DELETEZ(m_pCompGroup);

		////////////////////////////////////////////////////////////////
		// Gruppen loeschen
		m_aGroupArr.clear();
		m_xContainer.clear();
	}
}
// -----------------------------------------------------------------------------
void OGroupManager::removeFromGroupMap(const ::rtl::OUString& _sGroupName,const Reference<XPropertySet>& _xSet)
{
	// Component aus CompGroup entfernen
	m_pCompGroup->RemoveComponent( _xSet );

	OGroupArr::iterator aFind = m_aGroupArr.find(_sGroupName);

	if ( aFind != m_aGroupArr.end() )
	{
		// Gruppe vorhanden
		aFind->second.RemoveComponent( _xSet );

		// Wenn Anzahl der Gruppenelemente == 1 ist, Gruppe deaktivieren
		if ( aFind->second.Count() == 1 )
		{
			OActiveGroups::iterator aActiveFind = ::std::find(
                m_aActiveGroupMap.begin(),
                m_aActiveGroupMap.end(),
                aFind
            );
			if ( aActiveFind != m_aActiveGroupMap.end() )
            {
                // the group is active. Deactivate it if the remaining component
                // is *no* radio button
                if ( !isRadioButton( aFind->second.GetObject( 0 ) ) )
				    m_aActiveGroupMap.erase( aActiveFind );
            }
		}
	}


	// Bei Component als PropertyChangeListener abmelden
	_xSet->removePropertyChangeListener( PROPERTY_NAME, this );
	if (hasProperty(PROPERTY_TABINDEX, _xSet))
		_xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this );
}
//------------------------------------------------------------------
void SAL_CALL OGroupManager::propertyChange(const PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference<XPropertySet>  xSet(evt.Source, UNO_QUERY);

	// Component aus Gruppe entfernen
	::rtl::OUString		sGroupName;
	if (evt.PropertyName == PROPERTY_NAME)
		evt.OldValue >>= sGroupName;
	else
		xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;

	removeFromGroupMap(sGroupName,xSet);

	// Component neu einordnen
	InsertElement( xSet );
}

// XContainerListener
//------------------------------------------------------------------
void SAL_CALL OGroupManager::elementInserted(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference< XPropertySet > xProps;
	Event.Element >>= xProps;
	if ( xProps.is() )
		InsertElement( xProps );
}

//------------------------------------------------------------------
void SAL_CALL OGroupManager::elementRemoved(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference<XPropertySet> xProps;
	Event.Element >>= xProps;
	if ( xProps.is() )
		RemoveElement( xProps );
}

//------------------------------------------------------------------
void SAL_CALL OGroupManager::elementReplaced(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference<XPropertySet> xProps;
	Event.ReplacedElement >>= xProps;
	if ( xProps.is() )
		RemoveElement( xProps );

	xProps.clear();
	Event.Element >>= xProps;
	if ( xProps.is() )
		InsertElement( xProps );
}

// Other functions
//------------------------------------------------------------------
Sequence<Reference<XControlModel> > OGroupManager::getControlModels()
{
	return m_pCompGroup->GetControlModels();
}

//------------------------------------------------------------------
sal_Int32 OGroupManager::getGroupCount()
{
	return m_aActiveGroupMap.size();
}

//------------------------------------------------------------------
void OGroupManager::getGroup(sal_Int32 nGroup, Sequence< Reference<XControlModel> >& _rGroup, ::rtl::OUString& _rName)
{
	OSL_ENSURE(nGroup >= 0 && (size_t)nGroup < m_aActiveGroupMap.size(),"OGroupManager::getGroup: Invalid group index!");
	OGroupArr::iterator aGroupPos	= m_aActiveGroupMap[nGroup];
	_rName							= aGroupPos->second.GetGroupName();
	_rGroup							= aGroupPos->second.GetControlModels();
}

//------------------------------------------------------------------
void OGroupManager::getGroupByName(const ::rtl::OUString& _rName, Sequence< Reference<XControlModel>  >& _rGroup)
{
	OGroupArr::iterator aFind = m_aGroupArr.find(_rName);
	if ( aFind != m_aGroupArr.end() )
		_rGroup = aFind->second.GetControlModels();
}

//------------------------------------------------------------------
void OGroupManager::InsertElement( const Reference<XPropertySet>& xSet )
{
	// Nur ControlModels
	Reference<XControlModel>  xControl(xSet, UNO_QUERY);
	if (!xControl.is() )
		return;

	// Component in CompGroup aufnehmen
	m_pCompGroup->InsertComponent( xSet );

	// Component in Gruppe aufnehmen
	::rtl::OUString sGroupName;
	xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;

	OGroupArr::iterator aFind = m_aGroupArr.find(sGroupName);

	if ( aFind == m_aGroupArr.end() )
	{
		aFind = m_aGroupArr.insert(OGroupArr::value_type(sGroupName,OGroup(sGroupName))).first;
	}

	aFind->second.InsertComponent( xSet );

	// if we have at least 2 elements in the group, then this is an "active group"
    bool bActivateGroup = aFind->second.Count() == 2;

    // Additionally, if the component is a radio button, then it's group becomes active,
    // too. With this, we ensure that in a container with n radio buttons which all are
    // in different groups the selection still works reliably (means that all radios can be
    // clicked independently)
    if ( aFind->second.Count() == 1 )
    {
        if ( isRadioButton( xSet ) )
            bActivateGroup = true;
    }

	if ( bActivateGroup )
	{
		OActiveGroups::iterator aAlreadyExistent = ::std::find(
            m_aActiveGroupMap.begin(),
            m_aActiveGroupMap.end(),
            aFind
        );
        if ( aAlreadyExistent == m_aActiveGroupMap.end() )
    		m_aActiveGroupMap.push_back(  aFind );
	}


	// Bei Component als PropertyChangeListener anmelden
	xSet->addPropertyChangeListener( PROPERTY_NAME, this );

    // Tabindex muss nicht jeder unterstuetzen
	if (hasProperty(PROPERTY_TABINDEX, xSet))
		xSet->addPropertyChangeListener( PROPERTY_TABINDEX, this );

}

//------------------------------------------------------------------
void OGroupManager::RemoveElement( const Reference<XPropertySet>& xSet )
{
	// Nur ControlModels
	Reference<XControlModel>  xControl(xSet, UNO_QUERY);
	if (!xControl.is() )
		return;

	// Component aus Gruppe entfernen
	::rtl::OUString		sGroupName;
	xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;

	removeFromGroupMap(sGroupName,xSet);
}

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

