/**************************************************************
 * 
 * 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 "EditBase.hxx"
#include "property.hxx"
#ifndef _FRM_PROPERTY_HRC_
#include "property.hrc"
#endif
#include "services.hxx"
#include <tools/debug.hxx>
#include <comphelper/basicio.hxx>
#include <cppuhelper/queryinterface.hxx>
#include "frm_resource.hxx"
#ifndef _FRM_RESOURCE_HRC_
#include "frm_resource.hrc"
#endif

//.........................................................................
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;

const sal_uInt16 DEFAULT_LONG	 =	0x0001;
const sal_uInt16 DEFAULT_DOUBLE  =	0x0002;
const sal_uInt16 FILTERPROPOSAL  =	0x0004;

DBG_NAME( OEditBaseModel )
//------------------------------------------------------------------
OEditBaseModel::OEditBaseModel( const Reference< XMultiServiceFactory >& _rxFactory, const ::rtl::OUString& rUnoControlModelName,
		const ::rtl::OUString& rDefault, const sal_Bool _bSupportExternalBinding, const sal_Bool _bSupportsValidation )
	:OBoundControlModel( _rxFactory, rUnoControlModelName, rDefault, sal_True, _bSupportExternalBinding, _bSupportsValidation )
	,m_nLastReadVersion(0)
	,m_bEmptyIsNull(sal_True)
	,m_bFilterProposal(sal_False)
{
	DBG_CTOR( OEditBaseModel, NULL );
}

//------------------------------------------------------------------
OEditBaseModel::OEditBaseModel( const OEditBaseModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
	 :OBoundControlModel( _pOriginal, _rxFactory )
	 ,m_nLastReadVersion(0)
{
	DBG_CTOR( OEditBaseModel, NULL );

	m_bFilterProposal = _pOriginal->m_bFilterProposal;
	m_bEmptyIsNull = _pOriginal->m_bEmptyIsNull;
	m_aDefault = _pOriginal->m_aDefault;
	m_aDefaultText = _pOriginal->m_aDefaultText;
}

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

// XPersist
//------------------------------------------------------------------------------
void OEditBaseModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OBoundControlModel::write(_rxOutStream);

	// Version
	sal_uInt16 nVersionId = 0x0005;
	DBG_ASSERT((getPersistenceFlags() & ~PF_SPECIAL_FLAGS) == 0,
		"OEditBaseModel::write : invalid special version flags !");
		// please don't use other flags, older versions can't interpret them !

	nVersionId |= getPersistenceFlags();
	_rxOutStream->writeShort(nVersionId);

	// Name
	_rxOutStream->writeShort(0);	// obsolete
	_rxOutStream << m_aDefaultText;

	// Maskierung fuer any
	sal_uInt16 nAnyMask = 0;
	if (m_aDefault.getValueType().getTypeClass() == TypeClass_LONG)
		nAnyMask |= DEFAULT_LONG;
	else if (m_aDefault.getValueType().getTypeClass() == TypeClass_DOUBLE)
		nAnyMask |= DEFAULT_DOUBLE;

	if (m_bFilterProposal)	// da boolean, kein Wert speichern
		nAnyMask |= FILTERPROPOSAL;

	_rxOutStream->writeBoolean(m_bEmptyIsNull);
	_rxOutStream->writeShort(nAnyMask);

	if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
		_rxOutStream->writeLong(getINT32(m_aDefault));
	else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
		_rxOutStream->writeDouble(getDouble(m_aDefault));

	// since version 5 we write the help text
	writeHelpTextCompatibly(_rxOutStream);
	// (that's potentially bad : at the time I added the above line we had two derived classes : OEditModel and
	// OFormattedModel. The first one does not have an own version handling, so it can't write the help text itself,
	// the second one does it's own writing (reading) after calling our method, so normally we shouldn't write any
	// additional members as this is not compatible to older office versions.
	// We decided to place the writing of the help text here as it seems the less worse alternative. There is no delivered
	// office version including formatted controls (and thus the OFormattedModel), and the OFormattedModel::read seems
	// robust against this change (as it will read a wrong and unknown file version and thus set it's members to defaults).

	if ((nVersionId & PF_HANDLE_COMMON_PROPS) != 0)
		writeCommonEditProperties(_rxOutStream);

	// !!! properties common to all OEditBaseModel derived classes should be written in writeCommonEditProperties !!!
}

//------------------------------------------------------------------------------
sal_uInt16 OEditBaseModel::getPersistenceFlags() const
{
	return PF_HANDLE_COMMON_PROPS;
}

//------------------------------------------------------------------------------
void OEditBaseModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OBoundControlModel::read(_rxInStream);
	::osl::MutexGuard aGuard(m_aMutex);

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

	sal_Bool bHandleCommonProps = (nVersion & PF_HANDLE_COMMON_PROPS) != 0;
	nVersion = nVersion & ~PF_SPECIAL_FLAGS;

    // obsolete
	_rxInStream->readShort();

	_rxInStream >> m_aDefaultText;

	if (nVersion >= 0x0003)
	{
		m_bEmptyIsNull = _rxInStream->readBoolean();

		sal_uInt16 nAnyMask = _rxInStream->readShort();
		if ((nAnyMask & DEFAULT_LONG) == DEFAULT_LONG)
		{
			sal_Int32 nValue = _rxInStream->readLong();
			m_aDefault <<= (sal_Int32)nValue;
		}
		else if ((nAnyMask & DEFAULT_DOUBLE) == DEFAULT_DOUBLE)
		{
			double fValue = _rxInStream->readDouble();
			m_aDefault <<= (double)fValue;
		}

		if ((nAnyMask & FILTERPROPOSAL) == FILTERPROPOSAL)
			m_bFilterProposal = sal_True;
	}

	if (nVersion > 4)
		readHelpTextCompatibly(_rxInStream);

	if (bHandleCommonProps)
		readCommonEditProperties(_rxInStream);

	// 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 OEditBaseModel::defaultCommonEditProperties()
{
	OBoundControlModel::defaultCommonProperties();
	// no own common properties at the moment
}

//------------------------------------------------------------------------------
void OEditBaseModel::readCommonEditProperties(const Reference<XObjectInputStream>& _rxInStream)
{
	sal_Int32 nLen = _rxInStream->readLong();

	Reference<XMarkableStream>	xMark(_rxInStream, UNO_QUERY);
	DBG_ASSERT(xMark.is(), "OBoundControlModel::readCommonProperties : can only work with markable streams !");
	sal_Int32 nMark = xMark->createMark();

	// read properties common to all OBoundControlModels
	OBoundControlModel::readCommonProperties(_rxInStream);

	// read properties common to all OEditBaseModels

	// skip the remaining bytes
	xMark->jumpToMark(nMark);
	_rxInStream->skipBytes(nLen);
	xMark->deleteMark(nMark);
}

//------------------------------------------------------------------------------
void OEditBaseModel::writeCommonEditProperties(const Reference<XObjectOutputStream>& _rxOutStream)
{
	Reference<XMarkableStream>	xMark(_rxOutStream, UNO_QUERY);
	DBG_ASSERT(xMark.is(), "OEditBaseModel::writeCommonProperties : can only work with markable streams !");
	sal_Int32 nMark = xMark->createMark();

	// a placeholder where we will write the overall length (later in this method)
	sal_Int32 nLen = 0;
	_rxOutStream->writeLong(nLen);

	// write properties common to all OBoundControlModels
	OBoundControlModel::writeCommonProperties(_rxOutStream);

	// write properties common to all OEditBaseModels

	// close the block - write the correct length at the beginning
	nLen = xMark->offsetToMark(nMark) - sizeof(nLen);
	xMark->jumpToMark(nMark);
	_rxOutStream->writeLong(nLen);
	xMark->jumpToFurthest();
	xMark->deleteMark(nMark);
}

//------------------------------------------------------------------------------
void OEditBaseModel::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
	switch (nHandle)
	{
		case PROPERTY_ID_EMPTY_IS_NULL:
			rValue <<= (sal_Bool)m_bEmptyIsNull;
			break;
		case PROPERTY_ID_FILTERPROPOSAL:
			rValue <<= (sal_Bool)m_bFilterProposal;
			break;
		case PROPERTY_ID_DEFAULT_TEXT:
			rValue <<= m_aDefaultText;
			break;
		case PROPERTY_ID_DEFAULT_VALUE:
		case PROPERTY_ID_DEFAULT_DATE:
		case PROPERTY_ID_DEFAULT_TIME:
			rValue = m_aDefault;
			break;
		default:
			OBoundControlModel::getFastPropertyValue(rValue, nHandle);
	}
}

//------------------------------------------------------------------------------
sal_Bool OEditBaseModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
											sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException )
{
	sal_Bool bModified(sal_False);
	switch (nHandle)
	{
		case PROPERTY_ID_EMPTY_IS_NULL:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEmptyIsNull);
			break;
		case PROPERTY_ID_FILTERPROPOSAL:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bFilterProposal);
			break;
		case PROPERTY_ID_DEFAULT_TEXT:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultText);
			break;
		case PROPERTY_ID_DEFAULT_VALUE:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const double*)0));
			break;
		case PROPERTY_ID_DEFAULT_DATE:
		case PROPERTY_ID_DEFAULT_TIME:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefault, ::getCppuType((const sal_Int32*)0));
			break;
		default:
			bModified = OBoundControlModel::convertFastPropertyValue(
											rConvertedValue,
											rOldValue,
											nHandle,
											rValue);
	}
	return bModified;
}

//------------------------------------------------------------------------------
void OEditBaseModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception)
{
	switch (nHandle)
	{
		case PROPERTY_ID_EMPTY_IS_NULL:
			DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
			m_bEmptyIsNull = getBOOL(rValue);
			break;
		case PROPERTY_ID_FILTERPROPOSAL:
			DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, "invalid type" );
			m_bFilterProposal = getBOOL(rValue);
			break;
		// Aenderung der defaultwerte fuehrt zu reset
		case PROPERTY_ID_DEFAULT_TEXT:
			DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
			rValue >>= m_aDefaultText;
			resetNoBroadcast();
			break;
		case PROPERTY_ID_DEFAULT_VALUE:
		case PROPERTY_ID_DEFAULT_DATE:
		case PROPERTY_ID_DEFAULT_TIME:
			m_aDefault = rValue;
			resetNoBroadcast();
			break;
		default:
			OBoundControlModel::setFastPropertyValue_NoBroadcast(nHandle, rValue );
	}
}

//XPropertyState
//------------------------------------------------------------------------------
Any OEditBaseModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
{
	switch (nHandle)
	{
		case PROPERTY_ID_DEFAULT_TEXT:
			return makeAny(::rtl::OUString());
		case PROPERTY_ID_FILTERPROPOSAL:
			return Any(makeAny((sal_Bool)sal_False));
		case PROPERTY_ID_DEFAULT_VALUE:
		case PROPERTY_ID_DEFAULT_DATE:
		case PROPERTY_ID_DEFAULT_TIME:
			return Any();
		default:
			return OBoundControlModel::getPropertyDefaultByHandle(nHandle);
	}
}

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

