/**************************************************************
 *
 * 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_sfx2.hxx"

#include <sfx2/linksrc.hxx>
#include <sfx2/lnkbase.hxx>
//#include <sot/exchange.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Sequence.hxx>

#include <tools/debug.hxx>
#include <vcl/timer.hxx>
#include <svl/svarray.hxx>


using namespace ::com::sun::star::uno;

namespace sfx2
{

TYPEINIT0( SvLinkSource )

/************** class SvLinkSourceTimer *********************************/
class SvLinkSourceTimer : public Timer
{
	SvLinkSource *  pOwner;
	virtual void    Timeout();
public:
			SvLinkSourceTimer( SvLinkSource * pOwn );
};

SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn )
	: pOwner( pOwn )
{
}

void SvLinkSourceTimer::Timeout()
{
	// sicher gegen zerstoeren im Handler
	SvLinkSourceRef aAdv( pOwner );
	pOwner->SendDataChanged();
}

static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner,
						sal_uIntPtr nTimeout )
{
	if( !*ppTimer )
	{
		*ppTimer = new SvLinkSourceTimer( pOwner );
		(*ppTimer)->SetTimeout( nTimeout );
		(*ppTimer)->Start();
	}
}


struct SvLinkSource_Entry_Impl
{
	SvBaseLinkRef		xSink;
	String				aDataMimeType;
	sal_uInt16				nAdviseModes;
	sal_Bool 				bIsDataSink;

	SvLinkSource_Entry_Impl( SvBaseLink* pLink, const String& rMimeType,
								sal_uInt16 nAdvMode )
		: xSink( pLink ), aDataMimeType( rMimeType ),
			nAdviseModes( nAdvMode ), bIsDataSink( sal_True )
	{}

	SvLinkSource_Entry_Impl( SvBaseLink* pLink )
		: xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( sal_False )
	{}

	~SvLinkSource_Entry_Impl();
};

SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl()
{
}

typedef SvLinkSource_Entry_Impl* SvLinkSource_Entry_ImplPtr;
SV_DECL_PTRARR_DEL( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr, 4, 4 )
SV_IMPL_PTRARR( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr );

class SvLinkSource_EntryIter_Impl
{
	SvLinkSource_Array_Impl aArr;
	const SvLinkSource_Array_Impl& rOrigArr;
	sal_uInt16 nPos;
public:
	SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr );
	~SvLinkSource_EntryIter_Impl();
	SvLinkSource_Entry_Impl* Curr()
							{ return nPos < aArr.Count() ? aArr[ nPos ] : 0; }
	SvLinkSource_Entry_Impl* Next();
	sal_Bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry );
};

SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
		const SvLinkSource_Array_Impl& rArr )
	: rOrigArr( rArr ), nPos( 0 )
{
	aArr.Insert( &rArr, 0 );
}
SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl()
{
	aArr.Remove( 0, aArr.Count() );
}

sal_Bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry )
{
	return ( nPos < aArr.Count() && aArr[nPos] == pEntry && USHRT_MAX != rOrigArr.GetPos( pEntry ) );
}

SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
{
	SvLinkSource_Entry_ImplPtr pRet = 0;
	if( nPos + 1 < aArr.Count() )
	{
		++nPos;
		if( rOrigArr.Count() == aArr.Count() &&
			rOrigArr[ nPos ] == aArr[ nPos ] )
			pRet = aArr[ nPos ];
		else
		{
			// then we must search the current (or the next) in the orig
			do {
				pRet = aArr[ nPos ];
				if( USHRT_MAX != rOrigArr.GetPos( pRet ))
					break;
				pRet = 0;
				++nPos;
			} while( nPos < aArr.Count() );

			if( nPos >= aArr.Count() )
				pRet = 0;
		}
	}
	return pRet;
}

struct SvLinkSource_Impl
{
	SvLinkSource_Array_Impl aArr;
	String				aDataMimeType;
	SvLinkSourceTimer *	pTimer;
	sal_uIntPtr				nTimeout;
    com::sun::star::uno::Reference<com::sun::star::io::XInputStream>
    m_xInputStreamToLoadFrom;
    sal_Bool m_bIsReadOnly;

	SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {}
	~SvLinkSource_Impl();

	void Closed();
};

SvLinkSource_Impl::~SvLinkSource_Impl()
{
	delete pTimer;
}

SvLinkSource::SvLinkSource()
 	: pImpl( new SvLinkSource_Impl )
{
}

SvLinkSource::~SvLinkSource()
{
	delete pImpl;
}


SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
{
    return StreamToLoadFrom(
        pImpl->m_xInputStreamToLoadFrom,
        pImpl->m_bIsReadOnly);
}

void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream,sal_Bool bIsReadOnly )
{
    pImpl->m_xInputStreamToLoadFrom = xInputStream;
    pImpl->m_bIsReadOnly = bIsReadOnly;
}

// --> OD 2008-06-18 #i88291#
void SvLinkSource::clearStreamToLoadFrom()
{
    pImpl->m_xInputStreamToLoadFrom.clear();
}
// <--

void  SvLinkSource::Closed()
{
	SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
	for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
		if( !p->bIsDataSink )
			p->xSink->Closed();
}

sal_uIntPtr SvLinkSource::GetUpdateTimeout() const
{
	return pImpl->nTimeout;
}

void SvLinkSource::SetUpdateTimeout( sal_uIntPtr nTimeout )
{
	pImpl->nTimeout = nTimeout;
	if( pImpl->pTimer )
		pImpl->pTimer->SetTimeout( nTimeout );
}

void SvLinkSource::SendDataChanged()
{
	SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
	for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
	{
		if( p->bIsDataSink )
		{
			String sDataMimeType( pImpl->aDataMimeType );
			if( !sDataMimeType.Len() )
				sDataMimeType = p->aDataMimeType;

			Any aVal;
			if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
				GetData( aVal, sDataMimeType, sal_True ) )
			{
				p->xSink->DataChanged( sDataMimeType, aVal );

				if ( !aIter.IsValidCurrValue( p ) )
					continue;

				if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
				{
					sal_uInt16 nFndPos = pImpl->aArr.GetPos( p );
					if( USHRT_MAX != nFndPos )
						pImpl->aArr.DeleteAndDestroy( nFndPos );
				}

			}
		}
	}
	if( pImpl->pTimer )
	{
		delete pImpl->pTimer;
		pImpl->pTimer = NULL;
	}
	pImpl->aDataMimeType.Erase();
}

void SvLinkSource::NotifyDataChanged()
{
	if( pImpl->nTimeout )
		StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu
	else
	{
		SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
		for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
			if( p->bIsDataSink )
			{
				Any aVal;
				if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
					GetData( aVal, p->aDataMimeType, sal_True ) )
				{
					p->xSink->DataChanged( p->aDataMimeType, aVal );

					if ( !aIter.IsValidCurrValue( p ) )
						continue;

					if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
					{
						sal_uInt16 nFndPos = pImpl->aArr.GetPos( p );
						if( USHRT_MAX != nFndPos )
							pImpl->aArr.DeleteAndDestroy( nFndPos );
					}
				}
			}

			if( pImpl->pTimer )
			{
				delete pImpl->pTimer;
				pImpl->pTimer = NULL;
			}
	}
}

// notify the sink, the mime type is not
// a selection criterion
void SvLinkSource::DataChanged( const String & rMimeType,
								const ::com::sun::star::uno::Any & rVal )
{
	if( pImpl->nTimeout && !rVal.hasValue() )
	{   // nur wenn keine Daten mitgegeben wurden
		// fire all data to the sink, independent of the requested format
		pImpl->aDataMimeType = rMimeType;
		StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu
	}
	else
	{
		SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
		for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
		{
			if( p->bIsDataSink )
			{
				p->xSink->DataChanged( rMimeType, rVal );

				if ( !aIter.IsValidCurrValue( p ) )
					continue;

				if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
				{
					sal_uInt16 nFndPos = pImpl->aArr.GetPos( p );
					if( USHRT_MAX != nFndPos )
						pImpl->aArr.DeleteAndDestroy( nFndPos );
				}
			}
		}

		if( pImpl->pTimer )
		{
			delete pImpl->pTimer;
			pImpl->pTimer = NULL;
		}
	}
}


// only one link is correct
void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const String& rMimeType,
									sal_uInt16 nAdviseModes )
{
	SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl(
					pLink, rMimeType, nAdviseModes );
	pImpl->aArr.Insert( pNew, pImpl->aArr.Count() );
}

void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink )
{
	SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
	for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
		if( p->bIsDataSink && &p->xSink == pLink )
		{
			sal_uInt16 nFndPos = pImpl->aArr.GetPos( p );
			if( USHRT_MAX != nFndPos )
				pImpl->aArr.DeleteAndDestroy( nFndPos );
		}
}

// only one link is correct
void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
{
	SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( pLink );
	pImpl->aArr.Insert( pNew, pImpl->aArr.Count() );
}

void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink )
{
	SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
	for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
		if( !p->bIsDataSink && &p->xSink == pLink )
		{
			sal_uInt16 nFndPos = pImpl->aArr.GetPos( p );
			if( USHRT_MAX != nFndPos )
				pImpl->aArr.DeleteAndDestroy( nFndPos );
		}
}

sal_Bool SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const
{
	sal_Bool bRet = sal_False;
	const SvLinkSource_Entry_Impl* p;
	for( sal_uInt16 n = 0, nEnd = pImpl->aArr.Count(); n < nEnd; ++n )
		if( ( p = pImpl->aArr[ n ] )->bIsDataSink &&
			( !pLink || &p->xSink == pLink ) )
		{
			bRet = sal_True;
			break;
		}
	return bRet;
}

// sal_True => waitinmg for data
sal_Bool SvLinkSource::IsPending() const
{
	return sal_False;
}

// sal_True => data complete loaded
sal_Bool SvLinkSource::IsDataComplete() const
{
	return sal_True;
}

sal_Bool SvLinkSource::Connect( SvBaseLink* )
{
	return sal_True;
}

sal_Bool SvLinkSource::GetData( ::com::sun::star::uno::Any &, const String &, sal_Bool )
{
	return sal_False;
}

void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& )
{
}

}
