/************************************************************************
*                                                                       *
*   NuiTools.h -- This module aggregates all the Natural User           *
*                Interface(NUI) API structures and definitions          *
*                needed by Windows based NUI tools.                     *
*                                                                       *
*   Copyright (c) Microsoft Corp. All rights reserved.                  *
*                                                                       *
************************************************************************/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif
//
// Define NUI error codes derived from win32 errors
//

#define E_NUI_DEVICE_NOT_CONNECTED  __HRESULT_FROM_WIN32(ERROR_DEVICE_NOT_CONNECTED)
#define E_NUI_DEVICE_NOT_READY      __HRESULT_FROM_WIN32(ERROR_NOT_READY)
#define E_NUI_ALREADY_INITIALIZED   __HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED)
#define E_NUI_IDENTITY_BUSY         __HRESULT_FROM_WIN32(ERROR_BUSY)
#define E_NUI_NO_MORE_ITEMS         __HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)
#define E_NUI_NOACCESS              __HRESULT_FROM_WIN32(ERROR_NOACCESS)
#define E_NUI_NOT_FOUND             __HRESULT_FROM_WIN32(ERROR_NOT_FOUND)

//
// Define NUI specific error codes
//

#define FACILITY_NUI 0x301
#define E_NUI_FRAME_NO_DATA                     MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 1)
#define E_NUI_STREAM_NOT_ENABLED                MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 2)
#define E_NUI_IMAGE_STREAM_IN_USE               MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 3)
#define E_NUI_FRAME_LIMIT_EXCEEDED              MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 4)
#define E_NUI_FEATURE_NOT_INITIALIZED           MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 5)
#define E_NUI_IDENTITY_ENROLLMENT_LIMIT         MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 6)
#define E_NUI_IDENTITY_UI_REQUIRED              MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 7)
#define E_NUI_IDENTITY_LOST_TRACK               MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 8)
#define E_NUI_IDENTITY_QUALITY_ISSUE            MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 9)
#define E_NUI_IDENTITY_NO_UNENROLL_SIGN_IN      MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 10)
#define E_NUI_SYSTEM_UI_PRESENT                 MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 11)
#define E_NUI_MUST_CALL_IDENTIFY                MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 12)
#define E_NUI_DATABASE_NOT_FOUND                MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 13)
#define E_NUI_DATABASE_VERSION_MISMATCH         MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 14)
#define E_NUI_DATABASE_CORRUPTED                MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 15)
#define E_NUI_TRACKED_PLAYER_LIMIT_EXCEEDED     MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 16)
#define E_NUI_TRACKING_ID_IN_USE                MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 17)
#define E_NUI_LOST_TRACKING                     MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 18)
#define E_NUI_GESTURE_NOT_INITIALIZED           MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 19)
#define E_NUI_GESTURE_ALREADY_INITIALIZED       MAKE_HRESULT(SEVERITY_ERROR, FACILITY_NUI, 20)

// NOTE: Error codes in the range 100-199 associated with FACILITY_NUI are
// assigned to the NUI Handles API subsystem of NUI. See NuiHandles.h for
// details on those error codes.

typedef enum _NUI_IMAGE_TYPE
{
  NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX = 0,
  NUI_IMAGE_TYPE_COLOR,
  NUI_IMAGE_TYPE_COLOR_YUV,
  NUI_IMAGE_TYPE_DEPTH,
  NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX_IN_COLOR_SPACE,
  NUI_IMAGE_TYPE_DEPTH_IN_COLOR_SPACE,
  NUI_IMAGE_TYPE_COLOR_IN_DEPTH_SPACE,
  NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX_80x60,
  NUI_IMAGE_TYPE_DEPTH_80x60,
} NUI_IMAGE_TYPE;

typedef enum _NUI_IMAGE_RESOLUTION
{
  NUI_IMAGE_RESOLUTION_80x60,
  NUI_IMAGE_RESOLUTION_320x240,
  NUI_IMAGE_RESOLUTION_640x480
} NUI_IMAGE_RESOLUTION;

#define NUI_IMAGE_PLAYER_INDEX_SHIFT          3
#define NUI_IMAGE_PLAYER_INDEX_MASK           ((1 << NUI_IMAGE_PLAYER_INDEX_SHIFT)-1)
#define NUI_IMAGE_DEPTH_MAXIMUM               ((4000 << NUI_IMAGE_PLAYER_INDEX_SHIFT) | NUI_IMAGE_PLAYER_INDEX_MASK)
#define NUI_IMAGE_DEPTH_MINIMUM               (800 << NUI_IMAGE_PLAYER_INDEX_SHIFT)
#define NUI_IMAGE_DEPTH_NO_VALUE              0
#define NUI_IMAGE_DEPTH_BUFFER_SIZE           (384*240*2)
#define NUI_IMAGE_DEPTH_80x60_BUFFER_SIZE     (128*60*2)
#define NUI_IMAGE_COLOR_640x480_BUFFER_SIZE   (640*480*4)
#define NUI_IMAGE_COLOR_YUV_640x480_BUFFER_SIZE   (640*480*2)

#define NUI_CAMERA_DEPTH_NOMINAL_FOCAL_LENGTH_IN_PIXELS         (285.63f)   // Based on 320x240 pixel size.
#define NUI_CAMERA_DEPTH_NOMINAL_INVERSE_FOCAL_LENGTH_IN_PIXELS (3.501e-3f) // (1/NUI_CAMERA_DEPTH_NOMINAL_FOCAL_LENGTH_IN_PIXELS)
#define NUI_CAMERA_DEPTH_NOMINAL_DIAGONAL_FOV                   (70.0f)
#define NUI_CAMERA_DEPTH_NOMINAL_HORIZONTAL_FOV                 (58.5f)
#define NUI_CAMERA_DEPTH_NOMINAL_VERTICAL_FOV                   (45.6f)

#define NUI_CAMERA_COLOR_NOMINAL_FOCAL_LENGTH_IN_PIXELS         (531.15f)   // Based on 640x480 pixel size.
#define NUI_CAMERA_COLOR_NOMINAL_INVERSE_FOCAL_LENGTH_IN_PIXELS (1.83e-3f)  // (1/NUI_CAMERA_COLOR_NOMINAL_FOCAL_LENGTH_IN_PIXELS)
#define NUI_CAMERA_COLOR_NOMINAL_DIAGONAL_FOV                   ( 73.9f)
#define NUI_CAMERA_COLOR_NOMINAL_HORIZONTAL_FOV                 ( 62.0f)
#define NUI_CAMERA_COLOR_NOMINAL_VERTICAL_FOV                   ( 48.6f)

typedef enum _NUI_IMAGE_DIGITALZOOM
{
    NUI_IMAGE_DIGITAL_ZOOM_1X = 0,
    NUI_IMAGE_DIGITAL_ZOOM_2X = 1
} NUI_IMAGE_DIGITALZOOM;
typedef struct _NUI_IMAGE_VIEW_AREA
{
    NUI_IMAGE_DIGITALZOOM  eDigitalZoom;
    LONG                   lCenterX;
    LONG                   lCenterY;
} NUI_IMAGE_VIEW_AREA;
typedef enum _NUI_SKELETON_POSITION_INDEX
{
    NUI_SKELETON_POSITION_HIP_CENTER = 0,
    NUI_SKELETON_POSITION_SPINE,
    NUI_SKELETON_POSITION_SHOULDER_CENTER,
    NUI_SKELETON_POSITION_HEAD,
    NUI_SKELETON_POSITION_SHOULDER_LEFT,
    NUI_SKELETON_POSITION_ELBOW_LEFT,
    NUI_SKELETON_POSITION_WRIST_LEFT,
    NUI_SKELETON_POSITION_HAND_LEFT,
    NUI_SKELETON_POSITION_SHOULDER_RIGHT,
    NUI_SKELETON_POSITION_ELBOW_RIGHT,
    NUI_SKELETON_POSITION_WRIST_RIGHT,
    NUI_SKELETON_POSITION_HAND_RIGHT,
    NUI_SKELETON_POSITION_HIP_LEFT,
    NUI_SKELETON_POSITION_KNEE_LEFT,
    NUI_SKELETON_POSITION_ANKLE_LEFT,
    NUI_SKELETON_POSITION_FOOT_LEFT,
    NUI_SKELETON_POSITION_HIP_RIGHT,
    NUI_SKELETON_POSITION_KNEE_RIGHT,
    NUI_SKELETON_POSITION_ANKLE_RIGHT,
    NUI_SKELETON_POSITION_FOOT_RIGHT,
    NUI_SKELETON_POSITION_COUNT
} NUI_SKELETON_POSITION_INDEX;

//
//  Number of NUI_SKELETON_DATA elements in NUI_SKELETON_FRAME
//

#define NUI_SKELETON_COUNT 6

//
//  Number of NUI_SKELETON_DATA elements that can be in the NUI_SKELETON_TRACKED state
//

#define NUI_SKELETON_MAX_TRACKED_COUNT 2

//
//  Tracking IDs start at 1
//

#define NUI_SKELETON_INVALID_TRACKING_ID 0

typedef enum _NUI_SKELETON_POSITION_TRACKING_STATE
{
    NUI_SKELETON_POSITION_NOT_TRACKED = 0,
    NUI_SKELETON_POSITION_INFERRED,
    NUI_SKELETON_POSITION_TRACKED
} NUI_SKELETON_POSITION_TRACKING_STATE;

typedef enum _NUI_SKELETON_TRACKING_STATE
{
    NUI_SKELETON_NOT_TRACKED = 0,
    NUI_SKELETON_POSITION_ONLY,
    NUI_SKELETON_TRACKED
} NUI_SKELETON_TRACKING_STATE;

typedef struct _NUI_SKELETON_DATA
{
  NUI_SKELETON_TRACKING_STATE eTrackingState;
  DWORD dwTrackingID;
  DWORD dwEnrollmentIndex;
  DWORD dwUserIndex;
  XMVECTOR Position;
  XMVECTOR SkeletonPositions[NUI_SKELETON_POSITION_COUNT];
  NUI_SKELETON_POSITION_TRACKING_STATE eSkeletonPositionTrackingState[NUI_SKELETON_POSITION_COUNT];
  DWORD dwQualityFlags;
} NUI_SKELETON_DATA;


#define NUI_SKELETON_QUALITY_CLIPPED_RIGHT  0x00000001
#define NUI_SKELETON_QUALITY_CLIPPED_LEFT   0x00000002
#define NUI_SKELETON_QUALITY_CLIPPED_TOP    0x00000004
#define NUI_SKELETON_QUALITY_CLIPPED_BOTTOM 0x00000008

//#pragma pack(push, 16)
typedef struct _NUI_SKELETON_FRAME
{
  LARGE_INTEGER         liTimeStamp;
  DWORD                 dwFrameNumber;
  DWORD                 dwFlags;
  XMVECTOR              vFloorClipPlane;
  XMVECTOR              vNormalToGravity;
  NUI_SKELETON_DATA     SkeletonData[NUI_SKELETON_COUNT];
} NUI_SKELETON_FRAME;
//#pragma pack(pop)


#define NUI_SKELETON_FRAME_FLAG_CAMERA_MOTION           0x00000001
#define NUI_SKELETON_FRAME_FLAG_EXTRAPOLATED_FLOOR      0x00000002
#define NUI_SKELETON_FRAME_FLAG_UPPER_BODY_SKELETON     0x00000004
#define NUI_SKELETON_FRAME_FLAG_SEATED_SUPPORT_ENABLED  0x00000008

#define NUI_IDENTITY_QUALITY_ENVIRONMENT_FACE_DETECT_FAILURE 0x00000001
#define NUI_IDENTITY_QUALITY_USER_BODY_TURNED                0x00000002
#define NUI_IDENTITY_QUALITY_USER_NOT_UPRIGHT                0x00000004
#define NUI_IDENTITY_QUALITY_USER_OCCLUDED_FACE              0x00000008
#define NUI_IDENTITY_QUALITY_USER_OCCLUDED_BODY              0x00000010
#define NUI_IDENTITY_QUALITY_USER_FAR_AWAY                   0x00000020
#define NUI_IDENTITY_QUALITY_USER_CLOSE                      0x00000040
#define NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_LEFT            0x00000080
#define NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_RIGHT           0x00000100
#define NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_TOP             0x00000200
#define NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_BOTTOM          0x00000400
#define NUI_IDENTITY_QUALITY_ENVIRONMENT_TOO_DARK            0x00000800
#define NUI_IDENTITY_QUALITY_ENVIRONMENT_TOO_BRIGHT          0x00001000

#define NUI_IDENTITY_QUALITY_ENVIRONMENT_MASK  \
        (NUI_IDENTITY_QUALITY_ENVIRONMENT_FACE_DETECT_FAILURE   | \
         NUI_IDENTITY_QUALITY_ENVIRONMENT_TOO_DARK              | \
         NUI_IDENTITY_QUALITY_ENVIRONMENT_TOO_BRIGHT)

#define NUI_IDENTITY_QUALITY_USER_MASK  \
        (NUI_IDENTITY_QUALITY_USER_BODY_TURNED                  | \
         NUI_IDENTITY_QUALITY_USER_NOT_UPRIGHT                  | \
         NUI_IDENTITY_QUALITY_USER_OCCLUDED_FACE                | \
         NUI_IDENTITY_QUALITY_USER_OCCLUDED_BODY                | \
         NUI_IDENTITY_QUALITY_USER_FAR_AWAY                     | \
         NUI_IDENTITY_QUALITY_USER_CLOSE                        | \
         NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_LEFT              | \
         NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_RIGHT             | \
         NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_TOP               | \
         NUI_IDENTITY_QUALITY_USER_CLIPPED_AT_BOTTOM)

typedef enum _NUI_IDENTITY_MESSAGE_ID
{
    NUI_IDENTITY_MESSAGE_ID_FRAME_PROCESSED,
    NUI_IDENTITY_MESSAGE_ID_COMPLETE,
}NUI_IDENTITY_MESSAGE_ID;

typedef enum _NUI_IDENTITY_OPERATION_ID
{
    NUI_IDENTITY_OPERATION_ID_NONE,
    NUI_IDENTITY_OPERATION_ID_IDENTIFY,
    NUI_IDENTITY_OPERATION_ID_ENROLL,
    NUI_IDENTITY_OPERATION_ID_TUNER,
}NUI_IDENTITY_OPERATION_ID;

typedef struct _NUI_IDENTITY_MESSAGE_FRAME_PROCESSED
{
    DWORD dwQualityFlags;
} NUI_IDENTITY_MESSAGE_FRAME_PROCESSED;

typedef struct _NUI_IDENTITY_MESSAGE_COMPLETE
{
    HRESULT   hrResult;
    DWORD     dwEnrollmentIndex;
    BOOL      bProfileMatched;
} NUI_IDENTITY_MESSAGE_COMPLETE;

typedef struct _NUI_IDENTITY_MESSAGE
{
    NUI_IDENTITY_MESSAGE_ID   MessageId;
    NUI_IDENTITY_OPERATION_ID OperationId;
    DWORD dwTrackingID;
    DWORD dwSkeletonFrameNumber;
    union
    {
        NUI_IDENTITY_MESSAGE_FRAME_PROCESSED   FrameProcessed;
        NUI_IDENTITY_MESSAGE_COMPLETE          Complete;
    } Data;
} NUI_IDENTITY_MESSAGE;
#ifdef __cplusplus
}       //end of extern "C"
#endif
#ifdef __cplusplus
extern "C" {
#endif

//
// Gesture preprocess flags for input skeletons
//
#define NUI_GESTURE_PREPROCESS_NONE                     0x00000000
#define NUI_GESTURE_PREPROCESS_MIRROR_LEFT_RIGHT        0x00000001
#define NUI_GESTURE_PREPROCESS_MAKE_SEATED              0x00000002

#ifdef __cplusplus
} //close extern "C"
#endif
