#pragma once

#ifndef		NZ_API
#	define	NZ_API __declspec(dllexport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

#pragma region "NZ_SDK"

typedef enum
{
	NZ_MODEL_UNKNOWN = 0,
	NZ_MODEL_RHINO,
	NZ_MODEL_LEOPARD,
}NZ_MODEL;

typedef enum{ NZ_SESSION_TYPE_LIVE, NZ_SESSION_TYPE_PB }NZ_SESSION_TYPE;
NZ_API HANDLE __stdcall NZ_Create	( NZ_SESSION_TYPE session_type );
NZ_API HANDLE __stdcall NZ_CreateEx	( NZ_SESSION_TYPE session_type, NZ_MODEL model );
NZ_API void   __stdcall NZ_Delete	( HANDLE handle );

typedef enum{ NZ_STREAM_TYPE_VIDEO, NZ_STREAM_TYPE_AUDIO, NZ_STREAM_TYPE_EVENT, NZ_STREAM_TYPE_CAMERA_DISCONNECTED, NZ_STREAM_TYPE_SERVER_DISCONNECTED }NZ_STREAM_TYPE;
typedef enum{ NZ_CODEC_H264, NZ_CODEC_MPEG4, NZ_CODEC_JPEG, NZ_CODEC_YUV420P, NZ_CODEC_PCM, NZ_CODEC_G711A, NZ_CODEC_G711U, NZ_CODEC_G726 }NZ_CODEC;
typedef enum{ NZ_EVT_TYPE_RECORD, NZ_EVT_TYPE_ALARM, NZ_EVT_TYPE_MOTION, NZ_EVT_TYPE_VLOSS_H, NZ_EVT_TYPE_VLOSS_L, NZ_EVT_TYPE_TEXTIN, NZ_EVT_TYPE_DISK_TEMP, NZ_EVT_TYPE_SMART, NZ_EVT_TYPE_DISK_BAD, NZ_EVT_TYPE_TRIPWIRE }NZ_EVT_TYPE;
typedef enum{ NZ_STATUS_TYPE_CAMERA_CONNECTED, NZ_STATUS_TYPE_CAMERA_VIDEO_LOSS, NZ_STATUS_TYPE_SERVER_CONNECTED, NZ_STATUS_TYPE_SERVER_VIDEO_LOSS }NZ_STATUS_TYPE;

typedef struct
{
	NZ_CODEC						codec;
	DWORD64							stream;
	int								stream_length;
	BOOL							key_frame;
	DWORD							width;
	DWORD							height;
	BOOL							recording_status;
}NZ_STREAM_VIDEO;

typedef struct
{
	NZ_CODEC						codec;
	DWORD64							stream;
	int								stream_length;
	int								bitrate;
	int								sampling_rate;
	int								channels;
	int								bits_per_sample;
}NZ_STREAM_AUDIO;

typedef struct
{
	NZ_EVT_TYPE						type;
	BOOL							triggered;
	int								data_size;
	DWORD64							extra_data;
}NZ_STREAM_EVENT;

typedef struct
{
	NZ_STATUS_TYPE					type;
	BOOL							triggered;
	int								data_size;
	DWORD64							extra_data;
}NZ_STREAM_STATUS;

typedef struct
{
	NZ_STREAM_TYPE					type;
	int								channel;
	int								stream_no;
	SYSTEMTIME						time;
	DWORD							t;
	WORD							ms;
	union
	{
		NZ_STREAM_VIDEO				video;
		NZ_STREAM_AUDIO				audio;
		NZ_STREAM_EVENT				evt;
		NZ_STREAM_STATUS			status;
	}DATA;
}NZ_STREAM;

typedef struct  
{
	// Pan / Tilt 좌표 정보 지원유무
	BOOL bSupportPanTiltPosition;
	// Zoom 좌표 정보 지원유무
	BOOL bSupportZoomPosition;
	// Pan 좌표 최소값
	double dMinPanPosition;
	// Pan 좌표 최대값
	double dMaxPanPosition;
	// Tilt 좌표 최소값
	double dMinTiltPosition;
	// tilt 좌표 최대값
	double dMaxTiltPosition;
	// Zoom 좌표 최소값
	double dMinZoomPosition;
	// Zoom 좌표 최대값
	double dMaxZoomPosition;
}NZ_PTZ_POSITION_SPECIFICATION;

typedef struct  
{
	// 최대 소수점 9자리 실수
	double dPanPosition;
	// 최대 소수점 9자리 실수
	double dTiltPosition;
	// 최대 소수점 9자리 실수
	double dZoomPosition;
}NZ_PTZ_POSITION;

typedef struct 
{
	// 폰트명
	char szFontName[32];
	// 폰트 높이
	// (5~100, default:15)
	int nHeight;
}NZ_VIEW_FONT;

#define NZ_CMD_BASEA					0x00000000
#define NZ_CMD_BASEW					0x10000000

#define IS_UNICODE_COMMAND(x)			((x & NZ_CMD_BASEW) != 0)

#ifdef _UNICODE
#define NZ_CMD_BASE						NZ_CMD_BASEW
#else
#define NZ_CMD_BASE						NZ_CMD_BASEA
#endif

/*
	주석에 대한 정보
	[NRS/Rhino] : NRS / Rhino SDK 로 이용할 때의 정보
	[VMS/NVR] : VMS / NVR SDK 로 이용할 때의 정보
*/
typedef enum
{
	NZ_CMD_UNKNOWN					= (NZ_CMD_BASE | 0x00000000),
	/*
	// 대상 서버와 연결
	// arg1: LPCSTR 
	//    addr
	// arg2: LPCSTR 
	//    port : (http=80&rtsp=554)
	// arg3: LPCSTR 
	//    id
	// arg4: LPCSTR 
	//    password
	// arg5: [NRS/Rhino] BOOL 
	//    bAsync
	//       TRUE : 비동기로 서버와 연결 상태 확인 (서버와 연결할 수 없는 상태이더라도 TRUE 값을 리턴)
	//       FALSE : 동기로 서버와 연결 상태 확인하여 결과를 넘김
	*/
	NZ_CMD_CONNECT					= (NZ_CMD_BASE | 0x00000001),
	NZ_CMD_DISCONNECT				= (NZ_CMD_BASE | 0x00000002),
	/*
	// arg1: BOOL 
	//	 use secure socket
	// arg2: BOOL 
	//	 use digest auth
	// arg3: int
	//   connection type: 0=DB (default),  1=NVR/VMS http)
	*/
	NZ_CMD_SET_SETTINGS				= (NZ_CMD_BASE | 0x00000003),
	/*
	// arg1 : LPCSTR
	//		setting name
	//		CAPTURE_AVSTREAM (Value : Boolean) : 비디오 / 오디오 스트림 캡쳐 유무
	//		DISPLAY_NORMAL_IMAGE (Value : FilePath) : 영상 출력 타일의 일반 배경 이미지
	//		DISPLAY_VIDEOLOSS_IMAGE (Value : FilePath) : 영상 출력 타일의 비디오 로스 발생 시 배경 이미지
	// arg2 : LPCSTR
	//		setting value
	*/
	NZ_CMD_SET_SETTING_EX			= (NZ_CMD_BASE | 0x00000004),

	/*
	// 라이브 영상 스트림 시작 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: BOOL 
	//    auto_play
	//       TRUE : target_window 에 대하여 영상을 디코딩하여 재생 시작
	//       FALSE : 영상 디코딩 재생하지 않음
	// arg4: DWORD_PTR
	//	  pPlayParam (auto_play 값에 따른 정보)
	//	  auto_play 가 true 일때
	//		target_window : 영상 출력을 위한 대상 윈도우 핸들 정보
	//	  auto_play 가 false 일때
	//		0 : 디코딩
	//		1 : 디코딩하지 않음
	// arg5: LPCSTR 
	//    lpstrPlayName
	//    NULL or Not
	//       하나의 SDK 인스턴스로 동일한 영상 서버의 채널에 대하여 스트림 요청을 하는 경우 구분하기 위한
	//       키값 (내부적으로 참조 카운터를 이용하여 더이상 라이브 영상 스트림을 이용하지 않는 경우 스트림 종료)
	*/
	NZ_CMD_OPEN_VIDEO				= (NZ_CMD_BASE | 0x00010001),
	/*
	// 라이브 영상 스트림 종료 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: LPCSTR
	//    lpstrPlayName : NULL or Not
	//    NULL or Not
	//       NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_CLOSE_VIDEO				= (NZ_CMD_BASE | 0x00010002),
	/*
	// [NRS] 라이브 영상 스트림 시작 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	// arg2: LPCSTR
	//    lpstrStreamUrl
	// arg3: BOOL 
	//    auto_play
	//       TRUE : target_window 에 대하여 영상을 디코딩하여 재생 시작
	//       FALSE : 영상 디코딩 재생하지 않음
	// arg4: DWORD_PTR
	//	  pPlayParam (auto_play 값에 따른 정보)
	//	  auto_play 가 true 일때
	//		target_window : 영상 출력을 위한 대상 윈도우 핸들 정보
	//	  auto_play 가 false 일때
	//		0 : 디코딩
	//		1 : 디코딩하지 않음
	// arg5: LPCSTR 
	//    lpstrPlayName
	//    NULL or Not
	//       하나의 SDK 인스턴스로 동일한 영상 서버의 채널에 대하여 스트림 요청을 하는 경우 구분하기 위한
	//       키값 (내부적으로 참조 카운터를 이용하여 더이상 라이브 영상 스트림을 이용하지 않는 경우 스트림 종료)
	*/
	NZ_CMD_OPEN_VIDEO_EX			= (NZ_CMD_BASE | 0x00010003),
	/*
	// 오디오 스트림 시작 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: BOOL
	//    auto_play
	//    TRUE : 자동 재생
	//    FALSE : 재생하지 않음
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_OPEN_AUDIO				= (NZ_CMD_BASE | 0x00010011),
	/*
	// 오디오 스트림 종료 요청 
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_CLOSE_AUDIO				= (NZ_CMD_BASE | 0x00010012),
	/*
	// 이벤트 스트림 요청
	// arg1: LPCSTR 
	//    [NRS/Rhino] channel_list : 1,2,4,5,...
	//    [VMS/NVR] device_list : 1,2,3,...
	*/
	NZ_CMD_OPEN_EVENT				= (NZ_CMD_BASE | 0x00010021),
	NZ_CMD_CLOSE_EVENT				= (NZ_CMD_BASE | 0x00010022),
	/*
	// [NotImplemented]
	// 녹화 상태 정보 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: SYSTEMTIME*
	//    from
	// arg3: SYSTEMTIME*
	//    to
	*/
	NZ_CMD_GET_RECORDED_DATA		= (NZ_CMD_BASE | 0x00011001),
	/*
	// 스트림 데이터 가져오기
	// NRS/Rhino 는 라이브 스트림만 연동되어 있음으로 라이브 스트림에 대한 데이터를 가져올 수 있으나,
	// VMS/NVR 은 검색 스트림도 연동되어 있음으로 세션 타입(NZ_SESSION_TYPE)으로 가져오고자 하는 스트림 데이터를
	// 선택한다.
	// 가져온 스트림 데이터 사용이 끝나면 NZ_CMD_GET_STREAM 을 이용하여 리소스를 해제해야 한다.
	// arg1: 
	//    [NRS/Rhino] NZ_STREAM* 
	//    [VMS/NVR] int NrsID (저장서버ID) : > 0
	// arg2 : [VMS/NVR] NZ_SESSION_TYPE 
	//    session_type
	// arg3 : [VMS/NVR] NZ_STREAM* 
	//    stream
	*/
	NZ_CMD_GET_STREAM				= (NZ_CMD_BASE | 0x00012001),
	/*
	// 스트림 데이터 리소스 해제
	// arg1: NZ_STREAM* 
	//    stream
	*/
	NZ_CMD_RELEASE_STREAM			= (NZ_CMD_BASE | 0x00012002),

	/*
	// arg1: int
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int 
	//    speed  : 1 ~ 10
	// arg4: int 
	//    stop  : 0 or 1
	*/
	NZ_CMD_PTZ_MOVE_LEFT			= (NZ_CMD_BASE | 0x00020001),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_RIGHT			= (NZ_CMD_BASE | 0x00020002),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_UP				= (NZ_CMD_BASE | 0x00020003),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_DOWN			= (NZ_CMD_BASE | 0x00020004),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_LEFTUP			= (NZ_CMD_BASE | 0x00020005),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_LEFTDOWN		= (NZ_CMD_BASE | 0x00020006),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_RIGHTUP			= (NZ_CMD_BASE | 0x00020007),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_MOVE_RIGHTDOWN		= (NZ_CMD_BASE | 0x00020008),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_ZOOM_TELE			= (NZ_CMD_BASE | 0x00020011),
	/*
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_ZOOM_WIDE			= (NZ_CMD_BASE | 0x00020012),
	/*
	// [NotImplemented]
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_FOCUSIN				= (NZ_CMD_BASE | 0x00020013),
	/*
	// [NotImplemented]
	// NZ_CMD_PTZ_MOVE_LEFT 참고
	*/
	NZ_CMD_PTZ_FOCUSOUT				= (NZ_CMD_BASE | 0x00020014),
	/*
	// [NotImplemented]
	// 서버에 저장된 Preset 목록 수 요청
	// arg1: int
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int*
	//    list_count
	*/
	NZ_CMD_PTZ_PRESET_GetListCount	= (NZ_CMD_BASE | 0x00020021),
	/*
	// [NotImplemented]
	// 서버에 저장된 Preset 목록 요청
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int 
	//    list_count
	// arg4: NZ_PRESET_LIST*
	//    list
	*/
	NZ_CMD_PTZ_PRESET_GetListData	= (NZ_CMD_BASE | 0x00020022),
	/*
	// 프리셋 설정
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int 
	//    preset_no
	*/
	NZ_CMD_PTZ_PRESET_SET			= (NZ_CMD_BASE | 0x00020023),
	/*
	// 프리셋 이동
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int 
	//    preset_no
	*/
	NZ_CMD_PTZ_PRESET_MOVE			= (NZ_CMD_BASE | 0x00020024),
	/*
	// 서버에 저장된 프리셋 순차투어 시작
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//   stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	*/
	NZ_CMD_PTZ_TOUR_START			= (NZ_CMD_BASE | 0x00020031),
	/*
	// 서버에서 진행중인 프리셋 순차투어 종료
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	*/
	NZ_CMD_PTZ_TOUR_STOP			= (NZ_CMD_BASE | 0x00020032),
	/*
	// [NRS/VMS/NVR] 카메라 Aux 제어
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: int 
	//    aux_number : 1 or 2
	// arg4: int
	//	onoff : 0 or 1
	//    0 : Off
	//    1 : On
	*/
	NZ_CMD_PTZ_AUX					= (NZ_CMD_BASE | 0x00020033),
	/*
	// [NRS/VMS/NVR] 카메라 PTZ 절대위치 지원 정보 요청
	// arg1: int
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: NZ_PTZ_POSITION_SPECIFICATION*
	*/
	NZ_CMD_GET_PTZ_POSITION_SPECIFICATION	= (NZ_CMD_BASE | 0x00020034),

	/*
	// [NRS/VMS/NVR] 카메라 PTZ 위치 정보 요청
	// arg1: int
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: NZ_PTZ_POSITION*
	*/
	NZ_CMD_GET_PTZ_POSITION			= (NZ_CMD_BASE | 0x00020035),
	/*
	// [NRS/VMS/NVR] 카메라 PTZ 위치로 이동
	// arg1: int
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare] int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	// arg3: NZ_PTZ_POSITION*
	*/
	NZ_CMD_SET_PTZ_POSITION			= (NZ_CMD_BASE | 0x00020036),
	/*
	// 오디오 출력 시작 (Client -> Device)
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	//    stream_number : 1 or 2
	//    1 : High Resolution
	//    2 : Low Resolution
	*/
	NZ_CMD_START_TALK				= (NZ_CMD_BASE | 0x00030001),
	/*
	// 오디오 출력 종료 (Client -> Device)
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	*/
	NZ_CMD_STOP_TALK				= (NZ_CMD_BASE | 0x00030002),
	/*
	// 오디오 출력을 위한 오디오 캡쳐 시작 / 종료 (Client -> Device)
	// 오디오 캡쳐 동작은 지정된 오디오 파일로부터 데이터를 읽어들이는 동작임
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: LPCSTR 
	//    wav_path
	// arg4: BOOL 
	//    onoff : 0 or 1
	//    0 : 종료
	//    1 : 시작
	*/
	NZ_CMD_SEND_WAVE				= (NZ_CMD_BASE | 0x00030003),

	/*
	// 영상 출력을 위한 VIEW 사이즈가 변경되었을 때 업데이트하기 위한 명령
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_RESIZE				= (NZ_CMD_BASE | 0x00040001),
	//NZ_CMD_VIEW_SET_SPLIT			= (NZ_CMD_BASE | 0x00040002),	// arg1: int channel (1~), arg2: int stream_number (1 or 2), arg3: LPCSTR split_name (#Fixed#_1x1, #Fixed#_2x2, #Fixed#_3x3, #Fixed#_4x4), arg4: LPCSTR lpstrPlayName
	/*
	// 영상 출력 영역에 선택 보더를 보여줄 지 유무 설정
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: BOOL 
	//    show : 0 or 1
	//    0 : Show
	//    1 : Hide
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_SELECTION		= (NZ_CMD_BASE | 0x00040003),
	/*
	// 영상에 대한 존 영역을 설정하여 영상 출력 시 보여준다
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: POINT* 
	//    pt : Polygon 포인트 Array 에 대한 포인터
	// arg4: LPCSTR 
	// 	  detail : 키 값 구조의 세부정보 문자열 (구분문자 '&')
	//       ex) index=1&pt_count=4&image_width=1920&image_height=1080
	//       index : 존 ID, > 0
	//       pt_count : 포인트 수
	//          값이 0 일 경우 Zone 정보를 Reset
	//       image_width : Polygon 에 대한 Canvas 의 Width
	//       image_height : Polygon 에 대한 Canvas 의 Height
	// arg5: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_ZONE			= (NZ_CMD_BASE | 0x00040004),
	/*
	// 영상에 대한 사각형 영역을 설정하여 영상 출력 시 보여준다.
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: RECT*
	//    rc_detect : 사각형 영역 정보
	// arg4: LPCSTR 
	//    detail : 키 값 구조의 세부정보 문자열 (구분문자 '&')
	//       ex) show=1&image_width=1920&image_height=1080
	//       show : 보여줄지 여부 (0 or 1)
	//       image_width : 사각형 영역에 대한 Canvas 의 Width
	//       image_height : 사각형 영역에 대한 Canvas 의 Height
	// arg5: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_DETECT			= (NZ_CMD_BASE | 0x00040005),
	/*
	// 영상 출력 시 지정된 이름을 OSD 로 출력한다.
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: LPCSTR
	//    name
	// arg4: int 
	//    size : 폰트 사이즈 (5~100, default:15)
	// arg5: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_NAME			= (NZ_CMD_BASE | 0x00040006),
	/*
	// 영상 출력 시 지정된 만큼 회전시켜 보여준다.
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: int 
	//    degree
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_ROTATE				= (NZ_CMD_BASE | 0x00040007),
	/*
	// 영상 출력 시 지정된 이름을 OSD 로 출력한다.
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: LPCSTR
	//    name
	// arg4: NZ_VIEW_FONT* 
	//    폰트 정보
	// arg5: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_NAME_EX		= (NZ_CMD_BASE | 0x00040008),
	/*
	// 영상 출력 영역에 대한 외곽선을 보여줄 지 결정한다.
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: BOOL 
	//    show : 0 or 1
	//    0 : Show
	//    1 : Hide
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_SHOW_BORDER			= (NZ_CMD_BASE | 0x00040009),
	/*
	// 영상 출력 영역에 대한 DZoom 실행 여부
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: int 
	// 	  stream_number : 1 or 2
	// 	  1 : High Resolution
	// 	  2 : Low Resolution
	// arg3: BOOL 
	//    enable : 0 or 1
	//    0 : Disable
	//    1 : Enable
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_VIEW_ENABLE_DZOOM		= (NZ_CMD_BASE | 0x0004000A),

	/*
	// [NRS/VMS/NVR] 검색 스트림 시작
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare]
	// arg3: BOOL 
	//    auto_play
	//       TRUE : target_window 에 대하여 영상을 디코딩하여 재생 시작
	//       FALSE : 영상 디코딩 재생하지 않음
	// arg4: DWORD_PTR
	//	  pPlayParam (auto_play 값에 따른 정보)
	//	  auto_play 가 true 일때
	//		target_window : 영상 출력을 위한 대상 윈도우 핸들 정보
	//	  auto_play 가 false 일때
	//		0 : 디코딩
	//		1 : 디코딩하지 않음
	// arg5: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_PB_OPEN_VIDEO			= (NZ_CMD_BASE | 0x00050001),
	/*
	// [NRS/VMS/NVR] 검색 스트림 종료
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare]
	// arg3: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_PB_CLOSE_VIDEO			= (NZ_CMD_BASE | 0x00050002),
	/*
	// [NRS/VMS/NVR] 검색 스트림 재생 시작
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare]
	// arg3: LPCSTR 
	//    detail : 키 값 구조의 세부정보 문자열 (구분문자 '&')
	//       ex) refresh=0&speed=1&method=forward&date=2014-08-01&time=14-20-00
	//       refresh : 전송버퍼 갱신 유무 (0 or 1)
	//       speed : 재송 속도 (0 ~ 9)
	//          0 : 1/2
	//          1 ~ 3 : 모든 프레임 재생
	//          4 ~ 9 : 키 프레임 재생
	//       method : 재생 방향
	//          forward : 정방향
	//          backward : 역방향
	//       date : 검색 시작 날짜 (yyyy-MM-dd)
	//       time : 검색 시작 시간 (hh-mm-ss)
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_PB_PLAY					= (NZ_CMD_BASE | 0x00050003),
	/*
	// [NRS/VMS/NVR] 검색 스트림 재생 중지
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare]
	// arg3: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_PB_PAUSE					= (NZ_CMD_BASE | 0x00050004),
	/*
	// [NotImplemented]
	// [NRS/VMS/NVR] 검색 스트림 재생 속도 설정
	// arg1: int 
	//    [NRS/Rhino] channel : > 0
	//       저장서버에 할당된 채널 정보
	//    [VMS/NVR] DeviceID : > 0
	//       장치에 대한 ID 정보
	// arg2: [DontCare]
	// arg3: int 
	//    speed : 재생 속도
	//    NZ_CMD_PB_PLAY 참고
	// arg4: LPCSTR 
	//    lpstrPlayName : NULL or Not
	//    NZ_CMD_OPEN_VIDEO 참고
	*/
	NZ_CMD_PB_SPEED					= (NZ_CMD_BASE | 0x00050005),

	/*
	// 녹화된 영상을 동영상 파일로 저장
	// arg1: LPCTSTR 
	//    pstrOption : Xml 포맷의 문자열
	//    내용은 SDK 문서 참고
	// arg2: LPEXPORTMSGHANDLER 
	//    hander : 동작 메시지 처리를 위한 핸들러
	// arg3: LONG_PTR 
	//    pHandlerParam : 동작 메시지 핸들러에 대한 사용자 파라미터
	*/
	NZ_CMD_EXPORT_VIDEO				= (NZ_CMD_BASE | 0x00060001),
	NZ_CMD_CANCEL_EXPORT_VIDEO		= (NZ_CMD_BASE | 0x00060002),
	/*
	// 녹화된 영상을 이미지 파일로 저장
	// arg1: LPCTSTR 
	//    pstrOption : Xml 포맷의 문자열
	//    내용은 SDK 문서 참고
	// arg2: LPEXPORTMSGHANDLER 
	//    hander : 동작 메시지 처리를 위한 핸들러
	// arg3: LONG_PTR 
	//    pHandlerParam : 동작 메시지 핸들러에 대한 사용자 파라미터
	*/
	NZ_CMD_EXPORT_IMAGE				= (NZ_CMD_BASE | 0x00060003),

	NZ_CMD_GET_DATAS				= (NZ_CMD_BASE | 0x00100001),	// arg1: NZ_VMS_DATA_TYPE, arg2: LPSTR* ppOutBuffer, arg3: int* pnOutSize
	NZ_CMD_GET_DATA					= (NZ_CMD_BASE | 0x00100002),	// arg1: NZ_VMS_DATA_TYPE, arg2: id, arg3: LPSTR* ppOutBuffer, arg4: int* pnOutSize
	NZ_CMD_ADD_DATA					= (NZ_CMD_BASE | 0x00100003),	// arg1: NZ_VMS_DATA_TYPE, arg2: LPCTSTR pData
	NZ_CMD_UPDATE_DATA				= (NZ_CMD_BASE | 0x00100004),	// arg1: NZ_VMS_DATA_TYPE, arg2: LPCTSTR pData
	NZ_CMD_DELETE_DATA				= (NZ_CMD_BASE | 0x00100005),	// arg1: NZ_VMS_DATA_TYPE, arg2: int nID
	NZ_CMD_SEARCH_USER_LOG			= (NZ_CMD_BASE | 0x00100006),	// arg1: LPCTSTR pstrOption, arg2: LPLOGSEARCHHANDLER hander, arg3: LONG_PTR pHandlerParam
	NZ_CMD_IS_EXTENDED_SYSTEM_LOG	= (NZ_CMD_BASE | 0x00100007),
	NZ_CMD_SEARCH_SYSTEM_LOG		= (NZ_CMD_BASE | 0x00100008),	// arg1: LPCTSTR pstrOption, arg2: LPLOGSEARCHHANDLER hander, arg3: LONG_PTR pHandlerParam

	NZ_CMD_GET_DATAS_EX				= (NZ_CMD_BASE | 0x00101001),	// arg1: LPCTSTR pstrName, arg2: LPSTR* ppOutBuffer, arg3: int* pnOutSize
	NZ_CMD_GET_DATA_EX				= (NZ_CMD_BASE | 0x00101002),	// arg1: LPCTSTR pstrName, arg2: id, arg3: LPSTR* ppOutBuffer, arg4: int* pnOutSize
	NZ_CMD_ADD_DATA_EX				= (NZ_CMD_BASE | 0x00101003),	// arg1: LPCTSTR pstrName, arg2: LPCTSTR pData
	NZ_CMD_UPDATE_DATA_EX			= (NZ_CMD_BASE | 0x00101004),	// arg1: LPCTSTR pstrName, arg2: LPCTSTR pData
	NZ_CMD_DELETE_DATA_EX			= (NZ_CMD_BASE | 0x00101005)	// arg1: LPCTSTR pstrName, arg2: int nID

} NZ_CMD;

NZ_API BOOL __stdcall NZ_Command	( HANDLE handle, NZ_CMD cmd, DWORD_PTR arg1, DWORD_PTR arg2, DWORD_PTR arg3, DWORD_PTR arg4, DWORD_PTR arg5 );

#pragma endregion "NZ_SDK"

#pragma region "NZ_VMS_SDK"


// Create Resource
NZ_API HANDLE __stdcall NZ_VMS_Create();

// Delete Resource
NZ_API void   __stdcall NZ_VMS_Delete(HANDLE handle);


// Error Codes
#define NZ_ERROR_OK					0

// 인자 정보등이 유효하지 않는 경우
#define NZ_ERROR_INVALID			1
// 연결 실패한 경우 / 서버와 연결되어 있지 않은 경우
#define NZ_ERROR_NOT_ONLINE			3
// 내부적으로 에러가 발생한 경우
#define NZ_ERROR_INTERNAL			4
// 이미 동작중인 경우
#define NZ_ERROR_ALREADY_RUNNING	5
// 여유 공간이 없는 경우
#define NZ_ERROR_DISK_FULL			6
// 시스템 에러 확인 (::GetLastError)
#define NZ_ERROR_SYSTEM_ERROR		7
// 데이터를 찾지 못한 경우
#define NZ_ERROR_NOT_FOUND			8

// 인증 실패한 경우
#define NZ_ERROR_SERVER_AUTH		500
// 서버로부터 받은 정보가 유효하지 않는 경우
#define NZ_ERROR_SERVER_INVALID		501

#define NZ_ERROR_EXCEPTION			1000


// Get last error
NZ_API DWORD __stdcall NZ_VMS_GetLastError(HANDLE handle);

NZ_API void __stdcall NZ_VMS_ReleaseData(LPCSTR pBuffer);

typedef enum
{
	NZ_DATA_TYPE_UNKNOWN = 0,
	NZ_DATA_TYPE_CAMERA = 1,
	NZ_DATA_TYPE_NRS = 2,
	NZ_DATA_TYPE_RECORD_SCHEDULE = 3,
	NZ_DATA_TYPE_USER = 4,
	NZ_DATA_TYPE_CLIENT = 5,
	NZ_DATA_TYPE_FACILITY = 6
} NZ_VMS_DATA_TYPE;

typedef enum
{
	NZ_EXPORT_MESSAGE_STARTED = 0,		// param1 : camera id
	NZ_EXPORT_MESSAGE_FINISHED,			// param1 : camera id, param2 : 0 (Success) / 1 (Fail) / 2 (Cancel)
	NZ_EXPORT_MESSAGE_UPDATED,			// param1 : progress percent (total)
	NZ_EXPORT_MESSAGE_ENCRYPTING,		// param1 : filename
	NZ_EXPORT_MESSAGE_EACH_UPDATED		// param1 : camera id, param2 :progress percent
} NZ_EXPORT_MESSAGE;

typedef void (__stdcall *LPEXPORTMSGHANDLER)(NZ_EXPORT_MESSAGE eMessage, LONG_PTR pParam1, LONG_PTR pParam2, LONG_PTR pUserParam);

typedef enum
{
	NZ_LOG_SEARCH_MESSAGE_DATA = 0,		// param1 : LPCTSTR data, param2 : LPBOOL (IsCancel)
	NZ_LOG_SEARCH_MESSAGE_FINISHED		// param1 : 0 (No more data) / 1 (More Data)
} NZ_LOG_SEARCH_MESSAGE;

typedef void (__stdcall *LPLOGSEARCHHANDLER)(NZ_LOG_SEARCH_MESSAGE eMessage, LONG_PTR pParam1, LONG_PTR pParam2, LONG_PTR pUserParam);

NZ_API BOOL __stdcall NZ_VMS_Command( HANDLE handle, NZ_CMD cmd, DWORD_PTR arg1, DWORD_PTR arg2, DWORD_PTR arg3, DWORD_PTR arg4, DWORD_PTR arg5 );

#pragma endregion "NZ_VMS_SDK"

#ifdef __cplusplus
}
#endif
