/*=============================================================================
	UnChan.h: Unreal datachannel class.
	Copyright 1997-1999 Epic Games, Inc. All Rights Reserved.

	Revision history:
		* Created by Tim Sweeney
=============================================================================*/

/*-----------------------------------------------------------------------------
	UChannel base class.
-----------------------------------------------------------------------------*/

//
// Base class of communication channels.
//
class ENGINE_API UChannel : public UObject
{
	DECLARE_ABSTRACT_CLASS(UChannel,UObject,CLASS_Transient);

	// Variables.
	UNetConnection*	Connection;		// Owner connection.
	UBOOL			OpenAcked;		// Whether open has been acknowledged.
	UBOOL			Closing;		// State of the channel.
	INT             ChIndex;		// Index of this channel.
	INT				OpenedLocally;	// Whether channel was opened locally or by remote.
	INT				OpenPacketId;	// Packet the spawn message was sent in.
	UBOOL			OpenTemporary;	// Opened temporarily.
	UBOOL			RecentNak;		// Recently received a Nak.
	EChannelType	ChType;			// Type of this channel.
	INT				NumInRec;		// Number of packets in InRec.
	INT				NumOutRec;		// Number of packets in OutRec.
	INT				NegotiatedVer;	// Negotiated version of engine = Min(client version, server version).
	FInBunch*		InRec;			// Incoming data with queued dependencies.
	FOutBunch*		OutRec;			// Outgoing reliable unacked data.

	// Statics.
	static UClass* ChannelClasses[CHTYPE_MAX];
	static UBOOL IsKnownChannelType( INT Type );

	// Constructor.
	UChannel();
	void Destroy();

	// UChannel interface.
	virtual void Init( UNetConnection* InConnection, INT InChIndex, UBOOL InOpenedLocally );
	virtual void SetClosingFlag();
	virtual void Close();
	virtual FString Describe();
	virtual void ReceivedBunch( FInBunch& Bunch )=0;
	virtual void Tick();

	// General channel functions.
	INT RouteDestroy();
	void ReceivedAcks();
	UBOOL ReceivedSequencedBunch( FInBunch& Bunch );
	void ReceivedRawBunch( FInBunch& Bunch );
	INT SendBunch( FOutBunch* Bunch, UBOOL Merge );
	INT IsNetReady( UBOOL Saturate );
	void AssertInSequenced();
	INT MaxSendBytes();
};

/*-----------------------------------------------------------------------------
	UControlChannel base class.
-----------------------------------------------------------------------------*/

//
// A channel for exchanging text.
//
class ENGINE_API UControlChannel : public UChannel, public FOutputDevice
{
	DECLARE_CLASS(UControlChannel,UChannel,CLASS_Transient);

	// Constructor.
	void StaticConstructor()
	{
		guard(UControlChannel::StaticConstructor);
		ChannelClasses[CHTYPE_Control]        = GetClass();
		GetDefault<UControlChannel>()->ChType = CHTYPE_Control;
		unguard;
	}
	UControlChannel();
	void Init( UNetConnection* InConnection, INT InChIndex, UBOOL InOpenedLocally );
	void Destroy();

	// UChannel interface.
	void ReceivedBunch( FInBunch& Bunch );

	// FArchive interface.
	void Serialize( const TCHAR* Data, EName Event );

	// UControlChannel interface.
	FString Describe();
};

/*-----------------------------------------------------------------------------
	UActorChannel.
-----------------------------------------------------------------------------*/

//
// Information for tracking retirement and retransmission of a property.
//
struct FPropertyRetirement
{
	INT    InPacketId;		// Packet received on, INDEX_NONE=none.
	INT    OutPacketId;		// Packet sent on, INDEX_NONE=none.
	BYTE   Dirty;			// Whether it needs to be resent.
	BYTE   Reliable;		// Whether it was sent reliably.
	FPropertyRetirement()
	:	OutPacketId	( INDEX_NONE )
	,	InPacketId	( INDEX_NONE )
	,	Dirty		( 0 )
	{}
};

//
// A channel for exchanging actor properties.
//
class ENGINE_API UActorChannel : public UChannel
{
	DECLARE_CLASS(UActorChannel,UChannel,CLASS_Transient);

	// Variables.
	ULevel*	Level;			// Level this actor channel is associated with.
	AActor* Actor;			// Actor this corresponds to.
	UClass* ActorClass;		// Class of the actor.
	DOUBLE	RelevantTime;	// Last time this actor was relevant to client.
	DOUBLE	LastUpdateTime;	// Last time this actor was replicated.
	UBOOL   SpawnAcked;	    // Whether spawn has been acknowledged.
	TArray<BYTE> Recent;	// Most recently sent values.
	TArray<BYTE> RepEval;	// Evaluated replication conditions.
	TArray<FPropertyRetirement> Retirement; // Property retransmission.

	// Constructor.
	void StaticConstructor()
	{
		guard(UActorChannel::StaticConstructor);
		ChannelClasses[CHTYPE_Actor]        = GetClass();
		GetDefault<UActorChannel>()->ChType = CHTYPE_Actor;
		unguard;
	}
	UActorChannel();
	void Init( UNetConnection* InConnection, INT InChIndex, UBOOL InOpenedLocally );
	void Destroy();

	// UChannel interface.
	void SetClosingFlag();
	void ReceivedBunch( FInBunch& Bunch );
	void Close();
	void Tick();

	// UActorChannel interface and accessors.
	AActor* GetActor() {return Actor;}
	FString Describe();
	void ReplicateActor();
	void SetChannelActor( AActor* InActor );
};

/*-----------------------------------------------------------------------------
	File transfer channel.
-----------------------------------------------------------------------------*/

//
// A channel for exchanging binary files.
//
class ENGINE_API UFileChannel : public UChannel
{
	DECLARE_CLASS(UFileChannel,UChannel,CLASS_Transient);

	// Variables.
	TCHAR		Filename[256];	 // Filename being transfered.
	TCHAR		PrettyName[256]; // Pretty name of file.
	TCHAR		Error[256];		 // Error.
	FArchive*	FileAr;			 // File being transfered.
	INT			Transfered;		 // Bytes transfered.
	INT			PackageIndex;	 // Index of package in Map.

	// Constructor.
	void StaticConstructor()
	{
		guard(UFileChannel::StaticConstructor);
		ChannelClasses[CHTYPE_File]        = GetClass();
		GetDefault<UFileChannel>()->ChType = CHTYPE_File;
		unguard;
	}
	UFileChannel();
	void Init( UNetConnection* InConnection, INT InChIndex, UBOOL InOpenedLocally );
	void Destroy();

	// UChannel interface.
	void ReceivedBunch( FInBunch& Bunch );

	// UFileChannel interface.
	FString Describe();
	void Tick();
};

/*-----------------------------------------------------------------------------
	The End.
-----------------------------------------------------------------------------*/
