/*************************************************************************
 *
 *  $RCSfile: svdde.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: dv $ $Date: 2001/07/26 13:24:30 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVDDE_HXX
#define _SVDDE_HXX

#ifndef _SOT_EXCHANGE_HXX
#include <sot/exchange.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif
#ifndef _LINK_HXX //autogen
#include <tools/link.hxx>
#endif

class DdeString;
class DdeData;
class DdeConnection;
class DdeTransaction;
class DdeLink;
class DdeRequest;
class DdeWarmLink;
class DdeHotLink;
class DdePoke;
class DdeExecute;
class DdeItem;
class DdeTopic;
class DdeService;
class ConvList;
struct DdeDataImp;
struct DdeImp;
class DdeItemImp;

#ifndef _SVDDE_NOLISTS
DECLARE_LIST( DdeConnections, DdeConnection* );
DECLARE_LIST( DdeServices, DdeService* );
DECLARE_LIST( DdeTopics, DdeTopic* );
DECLARE_LIST( DdeItems, DdeItem* );
#else
typedef List DdeConnections;
typedef List DdeServices;
typedef List DdeTopics;
typedef List DdeItems;
#endif

#if 0 // _SOLAR__PRIVATE
DECLARE_LIST( DdeTransactions, DdeTransaction* );
DECLARE_LIST( DdeFormats, long );
#else
typedef List DdeTransactions;
typedef List DdeFormats;
#endif

#ifndef STRING_LIST
#define STRING_LIST
DECLARE_LIST( StringList, String * )
#endif

// -----------
// - DdeData -
// -----------

class DdeData
{
	friend class    DdeInternal;
	friend class    DdeService;
	friend class    DdeConnection;
	friend class    DdeTransaction;
	DdeDataImp*     pImp;

#if 0 // _SOLAR__PRIVATE
	void            Lock();
#endif
	void			SetFormat( ULONG nFmt );
public:
					DdeData();
					DdeData( const void*, long, ULONG = FORMAT_STRING );
					DdeData( const String& );
					DdeData( const DdeData& );
					~DdeData();

	operator const  void*() const;
	operator        long() const;

	ULONG           GetFormat() const;

	DdeData&        operator = ( const DdeData& );

	static ULONG GetExternalFormat( ULONG nFmt );
	static ULONG GetInternalFormat( ULONG nFmt );
};
// ------------------
// - DdeServiceList -
// ------------------

class DdeServiceList
{
	StringList      aServices;

public:
					DdeServiceList( const String* = NULL );
					~DdeServiceList();

	StringList&     GetServices() { return aServices; }

private:
							DdeServiceList( const DdeServiceList& );
	const DdeServiceList&   operator= ( const DdeServiceList& );
};

// ----------------
// - DdeTopicList -
// ----------------

class DdeTopicList
{
	StringList      aTopics;

#if 0 // _SOLAR__PRIVATE
					DECL_LINK( Data, DdeData* );
#endif
public:
					DdeTopicList( const String& );
					~DdeTopicList();

	StringList&     GetTopics() { return aTopics; }
};

// ------------------
// - DdeTransaction -
// ------------------

class DdeTransaction
{
public:
	virtual void    Data( const DdeData* );
	virtual void    Done( BOOL bDataValid );
protected:
	DdeConnection&  rDde;
	DdeData         aDdeData;
	DdeString*      pName;
	short           nType;
	long            nId;
	long            nTime;
	Link            aData;
	Link            aDone;
	BOOL            bBusy;

					DdeTransaction( DdeConnection&, const String&, long = 0 );

public:
					~DdeTransaction();

	BOOL            IsBusy() { return bBusy; }
	const String&   GetName() const;

	void            Execute();

	void            SetDataHdl( const Link& rLink ) { aData = rLink; }
	const Link&     GetDataHdl() const { return aData; }

	void            SetDoneHdl( const Link& rLink ) { aDone = rLink; }
	const Link&     GetDoneHdl() const { return aDone; }

	void            SetFormat( ULONG nFmt ) { aDdeData.SetFormat( nFmt );  }
	ULONG           GetFormat() const       { return aDdeData.GetFormat(); }

	long            GetError();

private:
	friend class    DdeInternal;
	friend class    DdeConnection;

							DdeTransaction( const DdeTransaction& );
	const DdeTransaction&   operator= ( const DdeTransaction& );

};

// -----------
// - DdeLink -
// -----------

class DdeLink : public DdeTransaction
{
	Link            aNotify;

public:
					DdeLink( DdeConnection&, const String&, long = 0 );
					~DdeLink();

	void            SetNotifyHdl( const Link& rLink ) { aNotify = rLink; }
	const Link&     GetNotifyHdl() const { return aNotify; }
	virtual void    Notify();
};

// ---------------
// - DdeWarmLink -
// ---------------

class DdeWarmLink : public DdeLink
{
public:
			DdeWarmLink( DdeConnection&, const String&, long = 0 );
};

// --------------
// - DdeHotLink -
// --------------

class DdeHotLink : public DdeLink
{
public:
			DdeHotLink( DdeConnection&, const String&, long = 0 );
};

// --------------
// - DdeRequest -
// --------------

class DdeRequest : public DdeTransaction
{
public:
			DdeRequest( DdeConnection&, const String&, long = 0 );
};

// -----------
// - DdePoke -
// -----------

class DdePoke : public DdeTransaction
{
public:
			DdePoke( DdeConnection&, const String&, const char*, long,
					 ULONG = FORMAT_STRING, long = 0 );
			DdePoke( DdeConnection&, const String&, const DdeData&, long = 0 );
			DdePoke( DdeConnection&, const String&, const String&, long = 0 );
};

// --------------
// - DdeExecute -
// --------------

class DdeExecute : public DdeTransaction
{
public:
			DdeExecute( DdeConnection&, const String&, long = 0 );
};

// -----------------
// - DdeConnection -
// -----------------

class DdeConnection
{
	friend class    DdeInternal;
	friend class    DdeTransaction;
	DdeTransactions aTransactions;
	DdeString*      pService;
	DdeString*      pTopic;
	DdeImp*         pImp;

public:
					DdeConnection( const String&, const String& );
					~DdeConnection();

	long            GetError();
	long            GetConvId();

	static const DdeConnections& GetConnections();

	BOOL            IsConnected();

	const String&   GetServiceName();
	const String&   GetTopicName();

private:
							DdeConnection( const DdeConnection& );
	const DdeConnection&    operator= ( const DdeConnection& );
};

// -----------
// - DdeItem -
// -----------

class DdeItem
{
	friend class    DdeInternal;
	friend class    DdeTopic;
	DdeString*      pName;
	DdeTopic*       pMyTopic;
	DdeItemImp*     pImpData;

	void            IncMonitor( ULONG );
	void            DecMonitor( ULONG );

protected:
	BYTE            nType;

public:
					DdeItem( const sal_Unicode* );
					DdeItem( const String& );
					DdeItem( const DdeItem& );
					virtual ~DdeItem();

	const String&   GetName() const;
	short           GetLinks();
	void            NotifyClient();
};

// -----------
// - DdeItem -
// -----------

class DdeGetPutItem : public DdeItem
{
public:
					DdeGetPutItem( const sal_Unicode* p );
					DdeGetPutItem( const String& rStr );
					DdeGetPutItem( const DdeItem& rItem );

	virtual DdeData* Get( ULONG );
	virtual BOOL    Put( const DdeData* );
	virtual void    AdviseLoop( BOOL );     // AdviseLoop starten/stoppen
};

// ------------
// - DdeTopic -
// ------------

class DdeTopic
{
	void _Disconnect( long );

public:
	virtual void    Connect( long );
	virtual void    Disconnect( long );
	virtual DdeData* Get( ULONG );
	virtual BOOL    Put( const DdeData* );
	virtual BOOL    Execute( const String* );
		// evt. ein neues anlegen; return 0 -> es konnte nicht angelegt werden
	virtual BOOL MakeItem( const String& rItem );

		// es wird ein Warm-/Hot-Link eingerichtet. Return-Wert
		// besagt ob es geklappt hat
	virtual BOOL    StartAdviseLoop();
	virtual BOOL    StopAdviseLoop();

private:
	friend class    DdeInternal;
	friend class    DdeService;
	friend class    DdeItem;

private:
	DdeString*      pName;
	String          aItem;
	DdeItems        aItems;
	Link            aConnectLink;
	Link            aDisconnectLink;
	Link            aGetLink;
	Link            aPutLink;
	Link            aExecLink;

public:
					DdeTopic( const String& );
					~DdeTopic();

	const String&   GetName() const;
	long            GetConvId();

	void            SetConnectHdl( const Link& rLink ) { aConnectLink = rLink; }
	const Link&     GetConnectHdl() const { return aConnectLink;  }
	void            SetDisconnectHdl( const Link& rLink ) { aDisconnectLink = rLink; }
	const Link&     GetDisconnectHdl() const { return aDisconnectLink;  }
	void            SetGetHdl( const Link& rLink ) { aGetLink = rLink; }
	const Link&     GetGetHdl() const { return aGetLink;  }
	void            SetPutHdl( const Link& rLink ) { aPutLink = rLink; }
	const Link&     GetPutHdl() const { return aPutLink;  }
	void            SetExecuteHdl( const Link& rLink ) { aExecLink = rLink; }
	const Link&     GetExecuteHdl() const { return aExecLink; }

	void            NotifyClient( const String& );
	BOOL            IsSystemTopic();

	void            InsertItem( DdeItem* );     // fuer eigene Ableitungen!
	DdeItem*        AddItem( const DdeItem& );  // werden kopiert !
	void            RemoveItem( const DdeItem& );
	const String&   GetCurItem() { return aItem;  }
	const DdeItems& GetItems()   { return aItems; }

private:
					DdeTopic( const DdeTopic& );
	const DdeTopic& operator= ( const DdeTopic& );
};

// --------------
// - DdeService -
// --------------

class DdeService
{
	friend class    DdeInternal;

public:
	virtual BOOL    IsBusy();
	virtual String  GetHelp();
		// evt. ein neues anlegen; return 0 -> es konnte nicht angelegt werden
	virtual BOOL    MakeTopic( const String& rItem );

protected:
	virtual String  Topics();
	virtual String  Formats();
	virtual String  SysItems();
	virtual String  Status();
	virtual String  SysTopicGet( const String& );
	virtual BOOL    SysTopicExecute( const String* );

	const DdeTopic* GetSysTopic() const { return pSysTopic; }
private:
	DdeTopics       aTopics;
	DdeFormats      aFormats;
	DdeTopic*       pSysTopic;
	DdeString*      pName;
	ConvList*       pConv;
	short           nStatus;

	BOOL            HasCbFormat( USHORT );

public:
					DdeService( const String& );
					~DdeService();

	const String&   GetName() const;
	short           GetError()              { return nStatus; }

	static DdeServices& GetServices();
	DdeTopics&      GetTopics()             { return aTopics; }

	void            AddTopic( const DdeTopic& );
	void            RemoveTopic( const DdeTopic& );

	void            AddFormat( ULONG );
	void            RemoveFormat( ULONG );
	BOOL            HasFormat( ULONG );

private:
	  //              DdeService( const DdeService& );
	//int             operator= ( const DdeService& );
};

// ------------------
// - DdeTransaction -
// ------------------

inline long DdeTransaction::GetError()
{
	return rDde.GetError();
}
#endif // _SVDDE_HXX
