/**************************************************************
 * 
 * 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 "RadioButton.hxx"
#include "property.hxx"
#ifndef _FRM_PROPERTY_HRC_
#include "property.hrc"
#endif
#include "services.hxx"
#include <tools/debug.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/basicio.hxx>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>

//.........................................................................
namespace frm
{
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
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::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::form::binding;

//==================================================================
//------------------------------------------------------------------------------
InterfaceRef SAL_CALL ORadioButtonControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
{
	return *(new ORadioButtonControl(_rxFactory));
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL	ORadioButtonControl::getSupportedServiceNames() throw(RuntimeException)
{
	StringSequence aSupported = OBoundControl::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

	::rtl::OUString* pArray = aSupported.getArray();
	pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_RADIOBUTTON;
	return aSupported;
}


//------------------------------------------------------------------
ORadioButtonControl::ORadioButtonControl(const Reference<XMultiServiceFactory>& _rxFactory)
					  :OBoundControl(_rxFactory, VCL_CONTROL_RADIOBUTTON)
{
}

//------------------------------------------------------------------
void SAL_CALL ORadioButtonControl::createPeer(const Reference<starawt::XToolkit>& _rxToolkit, const Reference<starawt::XWindowPeer>& _rxParent) throw (RuntimeException)
{
	OBoundControl::createPeer(_rxToolkit, _rxParent);

	// switch off the auto-toggle, we do this ourself ....
	// (formerly this switch-off was done in the toolkit - but the correct place is here ...)
//	Reference< XVclWindowPeer >  xVclWindowPeer( getPeer(), UNO_QUERY );
//	if (xVclWindowPeer.is())
//		xVclWindowPeer->setProperty(::rtl::OUString::createFromAscii("AutoToggle"), ::cppu::bool2any(sal_False));
	// new order: do _not_ switch off the auto toggle because:
	// * today, it is not necessary anymore to handle the toggling ourself (everything works fine without it)
	// * without auto toggle, the AccessibleEvents as fired by the radio buttons are
	//     a. newly checked button: "unchecked"->"checked"
	//     b. previously checked button: "checked"->"unchecked"
	//   This is deadly for AT-tools, which then get the "unchecked" event _immediately_ after the "checked" event,
	//   and only read the latter. This makes radio buttons pretty unusable in form documents.
	//   So we switched AutoToggle _on_, again, because then VCL can handle the notifications, and will send
	//   them in the proper order.
}

//==================================================================
InterfaceRef SAL_CALL ORadioButtonModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
{
	return *(new ORadioButtonModel(_rxFactory));
}

//------------------------------------------------------------------
DBG_NAME( ORadioButtonModel )
//------------------------------------------------------------------
ORadioButtonModel::ORadioButtonModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OReferenceValueComponent( _rxFactory, VCL_CONTROLMODEL_RADIOBUTTON, FRM_SUN_CONTROL_RADIOBUTTON,sal_True )
					// use the old control name for compytibility reasons
{
	DBG_CTOR( ORadioButtonModel, NULL );

	m_nClassId = FormComponentType::RADIOBUTTON;
	m_aLabelServiceName = FRM_SUN_COMPONENT_GROUPBOX;
    initValueProperty( PROPERTY_STATE, PROPERTY_ID_STATE );
}

//------------------------------------------------------------------
ORadioButtonModel::ORadioButtonModel( const ORadioButtonModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
	:OReferenceValueComponent( _pOriginal, _rxFactory )
{
	DBG_CTOR( ORadioButtonModel, NULL );
}

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

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( ORadioButtonModel )

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL	ORadioButtonModel::getSupportedServiceNames() throw(RuntimeException)
{
	StringSequence aSupported = OReferenceValueComponent::getSupportedServiceNames();

    sal_Int32 nOldLen = aSupported.getLength();
	aSupported.realloc( nOldLen + 8 );
	::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;

    *pStoreTo++ = BINDABLE_CONTROL_MODEL;
    *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;

    *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;

    *pStoreTo++ = FRM_SUN_COMPONENT_RADIOBUTTON;
    *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_RADIOBUTTON;
    *pStoreTo++ = BINDABLE_DATABASE_RADIO_BUTTON;

	return aSupported;
}

//------------------------------------------------------------------------------
void ORadioButtonModel::SetSiblingPropsTo(const ::rtl::OUString& rPropName, const Any& rValue)
{
	// mein Name
	::rtl::OUString sMyName(m_aName);

	// meine Siblings durchiterieren
	Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
	if (xIndexAccess.is())
	{
		Reference<XPropertySet> xMyProps;
		query_interface(static_cast<XWeak*>(this), xMyProps);
		::rtl::OUString	sCurrentName;
		for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
		{
			Reference<XPropertySet>	xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
			if (!xSiblingProperties.is())
				continue;
			if (xMyProps == xSiblingProperties)
				continue;	// mich selber nicht umsetzen

			// nur wenn es ein Radio-Button ist
			if (!hasProperty(PROPERTY_CLASSID, xSiblingProperties))
				continue;
			sal_Int16 nType = 0;
			xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
			if (nType != FormComponentType::RADIOBUTTON)
				continue;

			// das 'zur selben Gruppe gehoeren' wird am Namen festgemacht
			xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sCurrentName;
			if (sCurrentName == sMyName)
				xSiblingProperties->setPropertyValue(rPropName, rValue);
		}
	}
}

//------------------------------------------------------------------------------
void ORadioButtonModel::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const Any& rValue) throw (Exception)
{
	OReferenceValueComponent::setFastPropertyValue_NoBroadcast( nHandle, rValue );

	// if the label control changed ...
	if (nHandle == PROPERTY_ID_CONTROLLABEL)
	{	// ... forward this to our siblings
		SetSiblingPropsTo(PROPERTY_CONTROLLABEL, rValue);
	}

	// wenn sich die ControlSource-Eigenschaft geaendert hat ...
	if (nHandle == PROPERTY_ID_CONTROLSOURCE)
	{	// ... muss ich allen meinen Siblings, die in der selben RadioButton-Gruppe sind wie ich, auch die
		// neue ControlSource mitgeben
		SetSiblingPropsTo(PROPERTY_CONTROLSOURCE, rValue);
	}

	// die andere Richtung : wenn sich mein Name aendert ...
	if (nHandle == PROPERTY_ID_NAME)
	{
		// ... muss ich testen, ob ich Siblings mit dem selben Namen habe, damit ich deren ControlSource uebernehmen kann
		Reference<XIndexAccess> xIndexAccess(getParent(), UNO_QUERY);
		if (xIndexAccess.is())
		{
			::rtl::OUString			sName;
			::rtl::OUString			sControlSource;

			Reference<XPropertySet> xMyProps;
			query_interface(static_cast<XWeak*>(this), xMyProps);
			for (sal_Int32 i=0; i<xIndexAccess->getCount(); ++i)
			{
				Reference<XPropertySet>	xSiblingProperties(*(InterfaceRef*)xIndexAccess->getByIndex(i).getValue(), UNO_QUERY);
				if (!xSiblingProperties.is())
					continue;

				if (xMyProps == xSiblingProperties)
					// nur wenn ich nicht mich selber gefunden habe
					continue;

				sal_Int16 nType = 0;
				xSiblingProperties->getPropertyValue(PROPERTY_CLASSID) >>= nType;
				if (nType != FormComponentType::RADIOBUTTON)
					// nur Radio-Buttons
					continue;

				xSiblingProperties->getPropertyValue(PROPERTY_NAME) >>= sName;
				// Control, das zur gleichen Gruppe gehoert ?
				if (rValue == sName)
				{
					setPropertyValue(PROPERTY_CONTROLSOURCE, xSiblingProperties->getPropertyValue(PROPERTY_CONTROLSOURCE));
					break;
				}
			}
		}
	}

	if (nHandle == PROPERTY_ID_DEFAULT_STATE)
	{
		sal_Int16 nValue;
		rValue >>= nValue;
		if (1 == nValue)
		{	// bei allen Radios der selben Gruppe das 'default checked' ruecksetzen, denn wie schon der highlander wusste :
			// es kann nur einen geben.
			Any aZero;
			nValue = 0;
			aZero <<= nValue;
			SetSiblingPropsTo(PROPERTY_DEFAULT_STATE, aZero);
		}
	}
}

//------------------------------------------------------------------------------
void ORadioButtonModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	BEGIN_DESCRIBE_PROPERTIES( 1, OReferenceValueComponent )
		DECL_PROP1(TABINDEX,			sal_Int16,					BOUND);
	END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL ORadioButtonModel::getServiceName() throw(RuntimeException)
{
	return FRM_COMPONENT_RADIOBUTTON;	// old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
void SAL_CALL ORadioButtonModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
	throw(IOException, RuntimeException)
{
	OReferenceValueComponent::write(_rxOutStream);

	// Version
	_rxOutStream->writeShort(0x0003);

	// Properties
	_rxOutStream << getReferenceValue();
	_rxOutStream << (sal_Int16)getDefaultChecked();
	writeHelpTextCompatibly(_rxOutStream);

	// from version 0x0003 : common properties
	writeCommonProperties(_rxOutStream);
}

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

	// Version
	sal_uInt16 nVersion = _rxInStream->readShort();

    ::rtl::OUString sReferenceValue;
    sal_Int16 nDefaultChecked( 0 );
	switch (nVersion)
	{
		case 0x0001 :
            _rxInStream >> sReferenceValue;
            _rxInStream >> nDefaultChecked;
            break;
		case 0x0002 :
			_rxInStream >> sReferenceValue;
			_rxInStream >> nDefaultChecked;
			readHelpTextCompatibly(_rxInStream);
			break;
		case 0x0003 :
			_rxInStream >> sReferenceValue;
			_rxInStream >> nDefaultChecked;
			readHelpTextCompatibly(_rxInStream);
			readCommonProperties(_rxInStream);
			break;
		default :
			DBG_ERROR("ORadioButtonModel::read : unknown version !");
			defaultCommonProperties();
			break;
	}

    setReferenceValue( sReferenceValue );
    setDefaultChecked( (ToggleState)nDefaultChecked );

	// Nach dem Lesen die Defaultwerte anzeigen
	if ( getControlSource().getLength() )
		// (not if we don't have a control source - the "State" property acts like it is persistent, then
		resetNoBroadcast();
}

//------------------------------------------------------------------------------
void ORadioButtonModel::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(RuntimeException)
{
	if ( _rEvent.PropertyName.equals( PROPERTY_STATE ) )
	{
		if ( _rEvent.NewValue == (sal_Int16)1 )
		{
			// wenn sich mein Status auf 'checked' geaendert hat, muss ich alle meine Siblings, die in der selben Gruppe
			// sind wie ich, entsprechend zuruecksetzen
			Any aZero;
			aZero <<= (sal_Int16)0;
			SetSiblingPropsTo( PROPERTY_STATE, aZero );
		}
	}

    OReferenceValueComponent::_propertyChanged( _rEvent );
}

//------------------------------------------------------------------------------
Any ORadioButtonModel::translateDbColumnToControlValue()
{
    return makeAny( (sal_Int16)
        ( ( m_xColumn->getString() == getReferenceValue() ) ? STATE_CHECK : STATE_NOCHECK )
    );
}

//------------------------------------------------------------------------------
Any ORadioButtonModel::translateExternalValueToControlValue( const Any& _rExternalValue ) const
{
    Any aControlValue = OReferenceValueComponent::translateExternalValueToControlValue( _rExternalValue );
    sal_Int16 nState = STATE_NOCHECK;
    if ( ( aControlValue >>= nState ) && ( nState == STATE_DONTKNOW ) )
        // radio buttons do not have the DONTKNOW state
        aControlValue <<= (sal_Int16)STATE_NOCHECK;
    return aControlValue;
}

//-----------------------------------------------------------------------------
sal_Bool ORadioButtonModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
{
    Reference< XPropertySet > xField( getField() );
	OSL_PRECOND( xField.is(), "ORadioButtonModel::commitControlValueToDbColumn: not bound!" );
	if ( xField.is() )
	{
		try
		{
			sal_Int16 nValue = 0;
			m_xAggregateSet->getPropertyValue( PROPERTY_STATE ) >>= nValue;
			if ( nValue == 1 )
				xField->setPropertyValue( PROPERTY_VALUE, makeAny( getReferenceValue() ) );
		}
		catch(Exception&)
		{
			DBG_ERROR("ORadioButtonModel::commitControlValueToDbColumn: could not commit !");
		}
	}
	return sal_True;
}

//.........................................................................
}
//.........................................................................

