/*************************************************************************
 *
 *  $RCSfile: communi.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2003/03/27 14:36:07 $
 *
 *  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 _COMMUNI_HXX
#define _COMMUNI_HXX

#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif
#ifndef _VOS_THREAD_HXX_ //autogen
#include <vos/thread.hxx>
#endif
#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif

#ifndef _SIMPLECM_HXX
#include <tools/simplecm.hxx>
#endif

class SvStream;
class SvMemoryStream;
//class Application;

class CommunicationManagerServerAcceptThread;
SV_DECL_PTRARR_SORT( CommunicationLinkList, CommunicationLink*, 1, 10);

class MultiCommunicationManager : public CommunicationManager
{
public:
	MultiCommunicationManager( BOOL bUseMultiChannel = FALSE );
	virtual ~MultiCommunicationManager();
	virtual BOOL StopCommunication();		// Hält alle CommunicationLinks an
	virtual BOOL IsLinkValid( CommunicationLink* pCL );
	virtual USHORT GetCommunicationLinkCount();
	virtual CommunicationLinkRef GetCommunicationLink( USHORT nNr );
protected:
	virtual void CallConnectionOpened( CommunicationLink* pCL );
	virtual void CallConnectionClosed( CommunicationLink* pCL );
	CommunicationLinkList *ActiveLinks;
	CommunicationLinkList *InactiveLinks;		/// Hier sind die CommunicationLinks drin, die sich noch nicht selbst abgemeldet haben.
												/// allerdings schon ein StopCommunication gekriegt haben, bzw ein ConnectionTerminated
	virtual void DestroyingLink( CommunicationLink *pCL );	// Link trägt sich im Destruktor aus
};

class CommunicationManagerServer : public MultiCommunicationManager
{
public:
	CommunicationManagerServer( BOOL bUseMultiChannel = FALSE ):MultiCommunicationManager( bUseMultiChannel ){;}
};

class CommunicationManagerClient : public MultiCommunicationManager, public ICommunicationManagerClient
{
public:
	CommunicationManagerClient( BOOL bUseMultiChannel = FALSE );
};

class CommunicationLinkViaSocket : public SimpleCommunicationLinkViaSocket, public NAMESPACE_VOS(OThread)
{
public:
	CommunicationLinkViaSocket( CommunicationManager *pMan, NAMESPACE_VOS(OStreamSocket) *pSocket );
	virtual ~CommunicationLinkViaSocket();

	virtual BOOL IsCommunicationError();
	virtual BOOL DoTransferDataStream( SvStream *pDataStream, CMProtocol nProtocol = CM_PROTOCOL_OLDSTYLE );

	// Diese sind Virtuelle Links!!!!
	virtual long ConnectionClosed( void* = NULL );
	virtual long DataReceived( void* = NULL );

protected:
	virtual void SAL_CALL run();

	virtual BOOL ShutdownCommunication();	
	ULONG nConnectionClosedEventId;
	ULONG nDataReceivedEventId;
	NAMESPACE_VOS(OMutex) aMConnectionClosed;	// Notwendig, da Event verarbeitet werden kann bevor Variable gesetzt ist
	NAMESPACE_VOS(OMutex) aMDataReceived;		// Notwendig, da Event verarbeitet werden kann bevor Variable gesetzt ist
	virtual void WaitForShutdown();
};

class CommunicationManagerServerViaSocket : public CommunicationManagerServer
{
	friend CommunicationManagerServerAcceptThread;
public:
	CommunicationManagerServerViaSocket( ULONG nPort, USHORT nMaxCon, BOOL bUseMultiChannel = FALSE );
	virtual ~CommunicationManagerServerViaSocket();

	virtual BOOL StartCommunication();
	virtual BOOL StopCommunication();

protected:
	ULONG nPortToListen;
	USHORT nMaxConnections;

private:
	CommunicationManagerServerAcceptThread *pAcceptThread;
	void AddConnection( CommunicationLink *pNewConnection );
};

class CommunicationManagerServerAcceptThread: public NAMESPACE_VOS(OThread)
{
public:
	CommunicationManagerServerAcceptThread( CommunicationManagerServerViaSocket* pServer, ULONG nPort, USHORT nMaxCon = CM_UNLIMITED_CONNECTIONS );
	virtual ~CommunicationManagerServerAcceptThread();
	CommunicationLinkRef GetNewConnection(){ CommunicationLinkRef xTemp = xNewConnection; xNewConnection.Clear(); return xTemp; }

protected:
	virtual void SAL_CALL run();

private:
	NAMESPACE_VOS(OAcceptorSocket) *pAcceptorSocket;
	ULONG nPortToListen;
	USHORT nMaxConnections;
	CommunicationManagerServerViaSocket* pMyServer;
	ULONG nAddConnectionEventId;
	NAMESPACE_VOS(OMutex) aMAddConnection;	// Notwendig, da Event verarbeitet werden kann bevor Variable gesetzt ist
	void CallInfoMsg( InfoString aMsg ){ pMyServer->CallInfoMsg( aMsg ); }
	CM_InfoType GetInfoType(){ return pMyServer->GetInfoType(); }

	// Diese beiden werden zum Transport der Connection vom Thread zum Mainthread verwendet.
	CommunicationLinkRef xNewConnection;
	DECL_LINK( AddConnection, void* );
};

class CommunicationManagerClientViaSocket : public CommunicationManagerClient, CommonSocketFunctions
{
public:
	CommunicationManagerClientViaSocket( ByteString aHost, ULONG nPort, BOOL bUseMultiChannel = FALSE );
	CommunicationManagerClientViaSocket( BOOL bUseMultiChannel = FALSE );
	virtual ~CommunicationManagerClientViaSocket();

	virtual BOOL StartCommunication(){ return StartCommunication( aHostToTalk, nPortToTalk );}
	virtual BOOL StartCommunication( ByteString aHost, ULONG nPort ){ return DoStartCommunication( this, (ICommunicationManagerClient*) this, aHost, nPort  );}

private:
	ByteString aHostToTalk;
	ULONG nPortToTalk;
protected:
	virtual CommunicationLink *CreateCommunicationLink( CommunicationManager *pCM, NAMESPACE_VOS(OConnectorSocket) *pCS ){ return new CommunicationLinkViaSocket( pCM, pCS ); }
};

#endif
