/**
{file:
	{name: VidyoVirtualRendererStream.h}
	{description: Virtual renderer stream API.}
	{copyright:
		(c) 2013-2021 Vidyo, Inc.,
		433 Hackensack Avenue,
		Hackensack, NJ  07601.
		All rights reserved.
		The information contained herein is proprietary to Vidyo, Inc.
		and shall not be reproduced, copied (in whole or in part), adapted,
		modified, disseminated, transmitted, transcribed, stored in a retrieval
		system, or translated into any language in any form by any means
		without the express written consent of Vidyo, Inc.}
}
*/
#ifndef VIDYO_VIRTUAL_RENDERER_STREAM_H
#define VIDYO_VIRTUAL_RENDERER_STREAM_H

#include <Lmi/Utils/LmiString.h>
#include <Lmi/Utils/LmiUnordered.h>
#include <Lmi/Os/LmiTime.h>
#include <Lmi/Os/LmiSharedPtr.h>

LMI_BEGIN_EXTERN_C

#pragma mark - VidyoVirtualRendererStream type declaration

struct VidyoVirtualRendererStreamImpl_;
typedef struct VidyoVirtualRendererStreamImpl_ VidyoVirtualRendererStreamImpl;
Declare_LmiSharedPtr(VidyoVirtualRendererStreamImpl)
Declare_LmiSharedPtrWrapper(VidyoVirtualRendererStream, VidyoVirtualRendererStreamImpl)
Declare_LmiWeakPtrWrapper(VidyoVirtualRendererStreamHandle, VidyoVirtualRendererStream, VidyoVirtualRendererStreamImpl)

/**
{type apigroup="connector,simple"  reference-counted="yes":
	{name: VidyoVirtualRendererStream}
	{parent: VidyoVirtualRenderer}
	{description: The stream information needed for renderer.}
	{member:
		{name: id}
		{type: LmiUint64}
		{description: The stream unique id.}
	}
	{member:
		{name: participantId}
		{type: LmiUint64}
		{description: The participant unique id.}
	}
}
*/

/**
{type visibility="private":
	{name: VidyoVirtualRendererStreamHandle}
	{parent: VidyoVirtualRenderer}
	{description: Weak reference to VidyoVirtualRendererStream object.}
}
*/

#pragma mark - VidyoVirtualRendererStream map definition

Declare_LmiUnorderedMap(LmiUint64, VidyoVirtualRendererStream)

#pragma mark - VidyoVirtualRendererStream vector definition

Declare_LmiVector(VidyoVirtualRendererStream)

LMI_END_EXTERN_C

#pragma mark - includes

#include "VidyoDevice.h"
#include "VidyoVirtualRenderer.h"

LMI_BEGIN_EXTERN_C

#pragma mark - VidyoVirtualRendererStreamType type declaration

/**
{type apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamType}
	{parent: VidyoVirtualRenderer}
	{description: The video stream type.}
	{value:
		{name: VIDYO_VIRTUALRENDERERSTREAMTYPE_Video}
		{description: The source is a participant's video.}
	}
	{value:
		{name: VIDYO_VIRTUALRENDERERSTREAMTYPE_ContentShare}
		{description: The source is a content share video.}
	}
	{value:
		{name: VIDYO_VIRTUALRENDERERSTREAMTYPE_Unknown}
		{description: The source type is unknown.}
	}
}
*/
typedef enum {
	VIDYO_VIRTUALRENDERERSTREAMTYPE_Video,
	VIDYO_VIRTUALRENDERERSTREAMTYPE_ContentShare,
	VIDYO_VIRTUALRENDERERSTREAMTYPE_Unknown
} VidyoVirtualRendererStreamType;

#pragma mark - VidyoVirtualRendererStreamParameters types declaration

typedef enum {
	VIDYO_VIRTUALRENDERERSTREAMSTATE_OFF,
	VIDYO_VIRTUALRENDERERSTREAMSTATE_ON,
	VIDYO_VIRTUALRENDERERSTREAMSTATE_AUTO,
} VidyoVirtualRendererStreamState;

typedef struct {
	LmiUint width;
	LmiUint height;
	LmiTime frameInterval;
	VidyoVirtualRendererStreamState state;
	LmiUint generation;
} VidyoVirtualRendererStreamParameters;

#pragma mark - VidyoVirtualRendererStreamParameters private APIs declaration

VidyoVirtualRendererStreamParameters* VidyoVirtualRendererStreamParametersConstructDefault(VidyoVirtualRendererStreamParameters* sp);
VidyoVirtualRendererStreamParameters* VidyoVirtualRendererStreamParametersConstruct(VidyoVirtualRendererStreamParameters* sp, LmiUint width, LmiUint height, LmiTime frameInterval, VidyoVirtualRendererStreamState state, LmiUint generation);
VidyoVirtualRendererStreamParameters* VidyoVirtualRendererStreamParametersConstructCopy(VidyoVirtualRendererStreamParameters* d, const VidyoVirtualRendererStreamParameters* s);
VidyoVirtualRendererStreamParameters* VidyoVirtualRendererStreamParametersAssign(VidyoVirtualRendererStreamParameters* d, const VidyoVirtualRendererStreamParameters* s);
void VidyoVirtualRendererStreamParametersDestruct(VidyoVirtualRendererStreamParameters* sp);
void VidyoVirtualRendererStreamParametersSet(VidyoVirtualRendererStreamParameters* sp, LmiUint width, LmiUint height, LmiTime frameInterval, VidyoVirtualRendererStreamState state, LmiUint generation);
LmiBool VidyoVirtualRendererStreamParametersEqual(const VidyoVirtualRendererStreamParameters* x, const VidyoVirtualRendererStreamParameters* y);
const char* VidyoVirtualRendererStreamStateToCStr(VidyoVirtualRendererStreamState type);

#pragma mark - VidyoVirtualRendererStream public APIs declaration

/**
{function visibility="private":
	{name: VidyoVirtualRendererStreamConstruct}
	{parent: VidyoVirtualRendererStream}
	{description: Constructs VidyoVirtualRendererStream object.}
	{prototype: VidyoVirtualRendererStream* VidyoVirtualRendererStreamConstruct(VidyoVirtualRendererStream* s, LmiUint64 id, LmiUint64 participantId, const LmiString* label, VidyoVirtualRendererStreamType type, LmiBool isMirrored, LmiBool isLocal, const VidyoDevice* device, const VidyoLocalRendererStream* streamHandle, LmiAllocator* alloc)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{parameter:
		{name: id}
		{description: The stream id.}
	}
	{parameter:
		{name: participantId}
		{description: The participant id.}
	}
	{parameter:
		{name: label}
		{description: The stream label.}
	}
	{parameter:
		{name: type}
		{description: The stream type.}
	}
	{parameter:
		{name: isMirrored}
		{description: Identify if the stream must be mirrored.}
	}
	{parameter:
		{name: isLocal}
		{description: Identify if the stream is local.}
	}
	{parameter:
		{name: device}
		{description: The VidyoDevice object.}
	}
	{parameter:
		{name: streamHandle}
		{description: The local renderer stream handle.}
	}
	{parameter:
		{name: alloc}
		{description: The LmiAllocator object.}
	}
	{return: Returns constructed VidyoVirtualRendererStream object.}
}
*/
VidyoVirtualRendererStream* VidyoVirtualRendererStreamConstruct(VidyoVirtualRendererStream* s, LmiUint64 id, LmiUint64 participantId, const LmiString* label, VidyoVirtualRendererStreamType type, LmiBool isMirrored, LmiBool isLocal, const VidyoDevice* device, const VidyoLocalRendererStream* streamHandle, LmiAllocator* alloc);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamConstructCopy}
	{parent: VidyoVirtualRendererStream}
	{description: Constructs a VidyoVirtualRendererStream object as a copy of another.}
	{prototype: VidyoVirtualRendererStream *VidyoVirtualRendererStreamConstructCopy(VidyoVirtualRendererStream *obj, const VidyoVirtualRendererStream *other)}
	{parameter: {name: obj} {description: The VidyoVirtualRendererStream object to construct.}}
	{parameter: {name: other} {description: The call object to make a copy of.}}
	{return: A pointer to a constructed object on success, or NULL on failure.}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamDestruct}
	{parent: VidyoVirtualRendererStream}
	{description: Destructs an VidyoVirtualRendererStream object.}
	{prototype: void VidyoVirtualRendererStreamDestruct(VidyoVirtualRendererStream *obj)}
	{parameter: {name: obj} {description: The VidyoVirtualRendererStream object to destruct.}}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamAssign}
	{parent: VidyoVirtualRendererStream}
	{description: Assigns one VidyoVirtualRendererStream object the value of another. }
	{prototype: VidyoVirtualRendererStream *VidyoVirtualRendererStreamAssign(VidyoVirtualRendererStream *obj, const VidyoVirtualRendererStream *other)}
	{parameter: {name: obj} {description: The VidyoVirtualRendererStream object.}}
	{parameter: {name: other} {description: The call object to make a copy of.}}
	{return: A pointer to the destination object on success, or NULL on failure.}
}
*/

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamGetId}
	{parent: VidyoVirtualRendererStream}
	{description: Gets stream id.}
	{prototype: LmiUint64 VidyoVirtualRendererStreamGetId(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns a stream id.}
}
*/
LmiUint64 VidyoVirtualRendererStreamGetId(const VidyoVirtualRendererStream* s);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamGetParticipantId}
	{parent: VidyoVirtualRendererStream}
	{description: Gets streams participant unique id.}
	{prototype: LmiUint64 VidyoVirtualRendererStreamGetParticipantId(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns a streams participant unique id.}
}
*/
LmiUint64 VidyoVirtualRendererStreamGetParticipantId(const VidyoVirtualRendererStream* s);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamGetLabel}
	{parent: VidyoVirtualRendererStream}
	{description: Gets stream label.}
	{prototype: const LmiString* VidyoVirtualRendererStreamGetLabel(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns a stream label.}
}
*/
const LmiString* VidyoVirtualRendererStreamGetLabel(const VidyoVirtualRendererStream* s);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamIsMirrored}
	{parent: VidyoVirtualRendererStream}
	{description: Checks whether stream is mirrored.}
	{prototype: LmiBool VidyoVirtualRendererStreamIsMirrored(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns LMI_TRUE if stream is mirrored, LMI_FALSE otherwise.}
}
*/
LmiBool VidyoVirtualRendererStreamIsMirrored(const VidyoVirtualRendererStream* s);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamIsLocal}
	{parent: VidyoVirtualRendererStream}
	{description: Checks whether stream is local.}
	{prototype: LmiBool VidyoVirtualRendererStreamIsLocal(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns LMI_TRUE if stream is local, LMI_FALSE otherwise.}
}
*/
LmiBool VidyoVirtualRendererStreamIsLocal(const VidyoVirtualRendererStream* s);

/**
{function apigroup="connector,simple":
	{name: VidyoVirtualRendererStreamGetType}
	{parent: VidyoVirtualRendererStream}
	{description: Gets stream type.}
	{prototype: VidyoVirtualRendererStreamType VidyoVirtualRendererStreamGetType(const VidyoVirtualRendererStream* s)}
	{parameter:
		{name: s}
		{description: The VidyoVirtualRendererStream object.}
	}
	{return: Returns stream type.}
}
*/
VidyoVirtualRendererStreamType VidyoVirtualRendererStreamGetType(const VidyoVirtualRendererStream* s);

#pragma mark - VidyoVirtualRendererStream private APIs declaration

void VidyoVirtualRendererStreamSetUserData(VidyoVirtualRendererStream* s, LmiVoidPtr userData);
LmiVoidPtr VidyoVirtualRendererStreamGetUserData(const VidyoVirtualRendererStream* s);
VidyoLocalRendererStream* VidyoVirtualRendererStreamGetLocalStreamHandle(VidyoVirtualRendererStream* s);
const VidyoVirtualRendererStreamParameters* VidyoVirtualRendererStreamGetParameters(const VidyoVirtualRendererStream* s);
const VidyoDeviceHandle* VidyoVirtualRendererStreamGetDeviceHandle(const VidyoVirtualRendererStream* s);
LmiBool VidyoVirtualRendererStreamSetLabel(VidyoVirtualRendererStream* s, const LmiString* label);
LmiBool VidyoVirtualRendererStreamSetParameters(VidyoVirtualRendererStream* s, const VidyoVirtualRendererStreamParameters* parameters);
const char* VidyoVirtualRendererStreamTypeToString(VidyoVirtualRendererStreamType type);

#ifdef LMI_USE_NGR_TEST
    /*
     *   This is for testing purpose.
     *   Need to remove this function
     */
void VidyoVirtualRendererStreamSetParticipantName(VidyoVirtualRendererStream* s, LmiString* name);
LmiString* VidyoVirtualRendererStreamGetParticipantName(VidyoVirtualRendererStream* s);
#endif

LMI_END_EXTERN_C

#if LMI_INLINE_NEED_HEADER_FILE_DEFINITIONS
Define_LmiSharedPtrWrapper_NoCompare(VidyoVirtualRendererStream, VidyoVirtualRendererStreamImpl)
Define_LmiWeakPtrWrapper(VidyoVirtualRendererStreamHandle, VidyoVirtualRendererStream, VidyoVirtualRendererStreamImpl)
#endif

#endif /* VIDYO_VIRTUAL_RENDERER_STREAM_H */

