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

#define UNICODE
#include <string.h> // memset
#include "ddeimp.hxx"
#include <svl/svdde.hxx>

#include <osl/thread.h>
#include <tools/debug.hxx>
#include <tools/solarmutex.hxx>
#include <vos/mutex.hxx>

// static DWORD        hDdeInst  = NULL;
// static short        nInstance = 0;

// DdeConnections*     DdeConnection::pConnections = NULL;

DdeInstData* ImpInitInstData()
{
	DdeInstData* pData = new DdeInstData;
	memset( pData,0,sizeof(DdeInstData) );
	DdeInstData** ppInst = (DdeInstData**)GetAppData( SHL_SVDDE );
	*ppInst = pData;
	return pData;
}

void ImpDeinitInstData()
{
	DdeInstData** ppInst = (DdeInstData**)GetAppData( SHL_SVDDE );
	delete (*ppInst);
	*ppInst = 0;
}


struct DdeImp
{
	HCONV   hConv;
	long    nStatus;
};

// --- DdeInternat::CliCallback() ----------------------------------

HDDEDATA CALLBACK DdeInternal::CliCallback(
			WORD nCode, WORD nCbType, HCONV hConv, HSZ, HSZ hText2,
			HDDEDATA hData, DWORD nInfo1, DWORD )
{
	HDDEDATA nRet = DDE_FNOTPROCESSED;
	DdeConnections&     rAll = (DdeConnections&)DdeConnection::GetConnections();
	DdeConnection*      self = 0;

	DdeInstData* pInst = ImpGetInstData();
	DBG_ASSERT(pInst,"SVDDE:No instance data");

	for ( self = rAll.First(); self; self = rAll.Next() )
		if ( self->pImp->hConv == hConv )
			break;

	if( self )
	{
		DdeTransaction* t;
		sal_Bool bFound = sal_False;
		for( t = self->aTransactions.First(); t; t = self->aTransactions.Next() )
		{
			switch( nCode )
			{
				case XTYP_XACT_COMPLETE:
					if( (DWORD)t->nId == nInfo1 )
					{
						nCode = t->nType & (XCLASS_MASK | XTYP_MASK);
						t->bBusy = sal_False;
						t->Done( 0 != hData );
						bFound = sal_True;
					}
					break;

				case XTYP_DISCONNECT:
					self->pImp->hConv = DdeReconnect( hConv );
					self->pImp->nStatus = self->pImp->hConv
									? DMLERR_NO_ERROR
									: DdeGetLastError( pInst->hDdeInstCli );
					t = 0;
					nRet = 0;
					bFound = sal_True;
					break;

				case XTYP_ADVDATA:
					bFound = sal_Bool( *t->pName == hText2 );
					break;
			}
			if( bFound )
				break;
		}

		if( t )
		{
			switch( nCode )
			{
			case XTYP_ADVDATA:
				if( !hData )
				{
					((DdeLink*) t)->Notify();
					nRet = (HDDEDATA)DDE_FACK;
					break;
				}
				// kein break;

			case XTYP_REQUEST:
				if( !hData && XTYP_REQUEST == nCode )
				{

				}

				DdeData d;
				d.pImp->hData = hData;
				d.pImp->nFmt  = DdeData::GetInternalFormat( nCbType );
				d.Lock();
				t->Data( &d );
				nRet = (HDDEDATA)DDE_FACK;
				break;
			}
		}
	}
	return nRet;
}

// --- DdeConnection::DdeConnection() ------------------------------

DdeConnection::DdeConnection( const String& rService, const String& rTopic )
{
	pImp = new DdeImp;
	pImp->nStatus  = DMLERR_NO_ERROR;
	pImp->hConv    = NULL;

	DdeInstData* pInst = ImpGetInstData();
	if( !pInst )
		pInst = ImpInitInstData();
	pInst->nRefCount++;
	pInst->nInstanceCli++;
	if ( !pInst->hDdeInstCli )
	{
		pImp->nStatus = DdeInitialize( &pInst->hDdeInstCli,
									   (PFNCALLBACK)DdeInternal::CliCallback,
									   APPCLASS_STANDARD | APPCMD_CLIENTONLY |
									   CBF_FAIL_ALLSVRXACTIONS |
									   CBF_SKIP_REGISTRATIONS  |
									   CBF_SKIP_UNREGISTRATIONS, 0L );
		pInst->pConnections = new DdeConnections;
	}

	pService = new DdeString( pInst->hDdeInstCli, rService );
	pTopic   = new DdeString( pInst->hDdeInstCli, rTopic );

	if ( pImp->nStatus == DMLERR_NO_ERROR )
	{
		pImp->hConv = DdeConnect( pInst->hDdeInstCli,*pService,*pTopic, NULL);
		if( !pImp->hConv )
			pImp->nStatus = DdeGetLastError( pInst->hDdeInstCli );
	}

	if ( pInst->pConnections )
		pInst->pConnections->Insert( this );
}

// --- DdeConnection::~DdeConnection() -----------------------------

DdeConnection::~DdeConnection()
{
	if ( pImp->hConv )
		DdeDisconnect( pImp->hConv );

	delete pService;
	delete pTopic;

	DdeInstData* pInst = ImpGetInstData();
	DBG_ASSERT(pInst,"SVDDE:No instance data");
	if ( pInst->pConnections )
		pInst->pConnections->Remove( this );

	pInst->nInstanceCli--;
	pInst->nRefCount--;
	if ( !pInst->nInstanceCli && pInst->hDdeInstCli )
	{
		if( DdeUninitialize( pInst->hDdeInstCli ) )
		{
			pInst->hDdeInstCli = NULL;
			delete pInst->pConnections;
			pInst->pConnections = NULL;
			if( pInst->nRefCount == 0 )
				ImpDeinitInstData();
		}
	}
	delete pImp;
}

// --- DdeConnection::IsConnected() --------------------------------

sal_Bool DdeConnection::IsConnected()
{
	CONVINFO c;
#ifdef OS2
	c.nSize = sizeof( c );
#else
	c.cb = sizeof( c );
#endif
	if ( DdeQueryConvInfo( pImp->hConv, QID_SYNC, &c ) )
		return sal_True;
	else
	{
		DdeInstData* pInst = ImpGetInstData();
		pImp->hConv = DdeReconnect( pImp->hConv );
		pImp->nStatus = pImp->hConv ? DMLERR_NO_ERROR : DdeGetLastError( pInst->hDdeInstCli );
		return sal_Bool( pImp->nStatus == DMLERR_NO_ERROR );
	}
}

// --- DdeConnection::GetServiceName() -----------------------------

const String& DdeConnection::GetServiceName()
{
	return (const String&)*pService;
}

// --- DdeConnection::GetTopicName() -------------------------------

const String& DdeConnection::GetTopicName()
{
	return (const String&)*pTopic;
}

// --- DdeConnection::GetConvId() ----------------------------------

long DdeConnection::GetConvId()
{
	return (long)pImp->hConv;
}

const DdeConnections& DdeConnection::GetConnections()
{
	DdeInstData* pInst = ImpGetInstData();
	DBG_ASSERT(pInst,"SVDDE:No instance data");
	return *(pInst->pConnections);
}

// --- DdeTransaction::DdeTransaction() ----------------------------

DdeTransaction::DdeTransaction( DdeConnection& d, const String& rItemName,
								long n ) :
					rDde( d )
{
	DdeInstData* pInst = ImpGetInstData();
	pName = new DdeString( pInst->hDdeInstCli, rItemName );
	nTime = n;
	nId   = 0;
	nType = 0;
	bBusy = sal_False;

	rDde.aTransactions.Insert( this );
}

// --- DdeTransaction::~DdeTransaction() ---------------------------

DdeTransaction::~DdeTransaction()
{
	if ( nId && rDde.pImp->hConv )
	{
		DdeInstData* pInst = ImpGetInstData();
		DdeAbandonTransaction( pInst->hDdeInstCli, rDde.pImp->hConv, nId );
	}

	delete pName;
	rDde.aTransactions.Remove( this );
}

// --- DdeTransaction::Execute() -----------------------------------

void DdeTransaction::Execute()
{
	HSZ     hItem = *pName;
	void*   pData = (void*)(const void *)aDdeData;
	DWORD   nData = (DWORD)(long)aDdeData;
	sal_uLong  	nIntFmt = aDdeData.pImp->nFmt;
	UINT    nExtFmt  = DdeData::GetExternalFormat( nIntFmt );
	DdeInstData* pInst = ImpGetInstData();

	if ( nType == XTYP_EXECUTE )
		hItem = NULL;
	if ( nType != XTYP_EXECUTE && nType != XTYP_POKE )
	{
		pData = NULL;
		nData = 0L;
	}
	if ( nTime )
	{
		HDDEDATA hData = DdeClientTransaction( (unsigned char*)pData,
											   nData, rDde.pImp->hConv,
											   hItem, nExtFmt, (UINT)nType,
											   (DWORD)nTime, (DWORD FAR*)NULL );

		rDde.pImp->nStatus = DdeGetLastError( pInst->hDdeInstCli );
		if( hData && nType == XTYP_REQUEST )
		{
			{
				DdeData d;
				d.pImp->hData = hData;
				d.pImp->nFmt = nIntFmt;
				d.Lock();
				Data( &d );
			}
			DdeFreeDataHandle( hData );
		}
	}
	else
	{
		if ( nId && rDde.pImp->hConv )
			DdeAbandonTransaction( pInst->hDdeInstCli, rDde.pImp->hConv, nId);
		nId = 0;
		bBusy = sal_True;
		HDDEDATA hRet = DdeClientTransaction( (unsigned char*)pData, nData,
											rDde.pImp->hConv, hItem, nExtFmt,
											(UINT)nType, TIMEOUT_ASYNC,
											(DWORD FAR *) ((long*) &nId) );
		rDde.pImp->nStatus = hRet ? DMLERR_NO_ERROR
								  : DdeGetLastError( pInst->hDdeInstCli );
	}
}

// --- DdeTransaction::GetName() -----------------------------------

const String& DdeTransaction::GetName() const
{
	return *pName;
}

// --- DdeTransaction::Data() --------------------------------------


void __EXPORT DdeTransaction::Data( const DdeData* p )
{
	if ( ::tools::SolarMutex::Acquire() )
	{
		aData.Call( (void*)p );
		::tools::SolarMutex::Release();
	}
}

// --- DdeTransaction::Done() --------------------------------------

void __EXPORT DdeTransaction::Done( sal_Bool bDataValid )
{
	aDone.Call( (void*)bDataValid );
}

// --- DdeLink::DdeLink() ------------------------------------------

DdeLink::DdeLink( DdeConnection& d, const String& aItemName, long n ) :
			DdeTransaction (d, aItemName, n)
{
}

// --- DdeLink::~DdeLink() -----------------------------------------

DdeLink::~DdeLink()
{
	nType = (sal_uInt16)XTYP_ADVSTOP;
	nTime = 0;
}

// --- DdeLink::Notify() -----------------------------------------

void __EXPORT DdeLink::Notify()
{
	aNotify.Call( NULL );
}

// --- DdeRequest::DdeRequest() ------------------------------------

DdeRequest::DdeRequest( DdeConnection& d, const String& i, long n ) :
				DdeTransaction( d, i, n )
{
	nType = XTYP_REQUEST;
}

// --- DdeWarmLink::DdeWarmLink() ----------------------------------

DdeWarmLink::DdeWarmLink( DdeConnection& d, const String& i, long n ) :
				DdeLink( d, i, n )
{
	nType = XTYP_ADVSTART | XTYPF_NODATA;
}

// --- DdeHotLink::DdeHotLink() ------------------------------------

DdeHotLink::DdeHotLink( DdeConnection& d, const String& i, long n ) :
				DdeLink( d, i, n )
{
	nType = XTYP_ADVSTART;
}

// --- DdePoke::DdePoke() ------------------------------------------

DdePoke::DdePoke( DdeConnection& d, const String& i, const char* p,
				  long l, sal_uLong f, long n ) :
			DdeTransaction( d, i, n )
{
	aDdeData = DdeData( p, l, f );
	nType = XTYP_POKE;
}

// --- DdePoke::DdePoke() ------------------------------------------

DdePoke::DdePoke( DdeConnection& d, const String& i, const String& rData,
				  long n ) :
			DdeTransaction( d, i, n )
{
//	ByteString aByteStr( rData, osl_getThreadTextEncoding() );
	aDdeData = DdeData( (void*) rData.GetBuffer(), sizeof(sal_Unicode) * (rData.Len()), CF_TEXT );
	nType = XTYP_POKE;
}

// --- DdePoke::DdePoke() ------------------------------------------

DdePoke::DdePoke( DdeConnection& d, const String& i, const DdeData& rData,
				  long n ) :
			DdeTransaction( d, i, n )
{
	aDdeData = rData;
	nType = XTYP_POKE;
}

// --- DdeExecute::DdeExecute() ------------------------------------

DdeExecute::DdeExecute( DdeConnection& d, const String& rData, long n ) :
				DdeTransaction( d, String(), n )
{
//	ByteString aByteStr( rData, osl_getThreadTextEncoding() );
	aDdeData = DdeData( (void*)rData.GetBuffer(), sizeof(sal_Unicode) * (rData.Len() + 1), CF_TEXT );
	nType = XTYP_EXECUTE;
}

// --- DdeConnection::GetError() -----------------------------------

long DdeConnection::GetError()
{
	return pImp->nStatus;
}
