#ifndef MY_KINECT
#define MY_KINECT

#include <Windows.h>
#include <NuiApi.h> // windows.hの後にinclude



#include <opencv2/opencv.hpp>

#include <pcl/point_types.h> 
#include <pcl/visualization/cloud_viewer.h> // opencvの後にinclude

#include <pcl/io/pcd_io.h>


#include <iostream>
#include <sstream>

#define ERROR_CHECK(ret) \
	if (ret != S_OK) { \
	std::stringstream ss; \
	ss << "failed " #ret " " << std::hex << ret << "\n"; \
	throw std::runtime_error(ss.str().c_str()); \
	}


const NUI_IMAGE_RESOLUTION COLOR_RESOLUTION = NUI_IMAGE_RESOLUTION_640x480;
const NUI_IMAGE_RESOLUTION DEPTH_RESOLUTION = NUI_IMAGE_RESOLUTION_640x480;

class MyKinect
{
public:
	MyKinect();
	~MyKinect();

	void showColorAndDepthImg();
	void showPointCloud();
	
	cv::Mat getColorImage();
	cv::Mat getDepthImage();
	cv::Mat getDepthImageShowed();

	void saveData();		//各データの保存

private:
	INuiSensor* kinect;
	HANDLE imageStreamHandle;
	HANDLE depthStreamHandle;
	HANDLE streamEvent;

	DWORD width, height;

	bool isInitialized;

	static const float MAX_DEPTH; // Kinectが取得できる最大のdepth

	void initInstance();
	static void CALLBACK StatusChanged(HRESULT hrStatus,
		const OLECHAR* instanceName,
		const OLECHAR* uniqueDeviceName,
		void* pUserData);
	void CALLBACK StatusChanged(HRESULT hrStatus,
		const OLECHAR* instanceName,
		const OLECHAR* uniqueDeviceName);
	void close();

	cv::Mat rgbImage;			// カラー画像

	cv::Mat rawDepthData;		// 距離カメラの画像座標系の距離データ(16bit, 下3bitはプレイヤーID)
	cv::Mat rawDepthImage;		// 距離カメラの画像座標系の距離画像	近いほど明るい色

	cv::Mat depthData_Mat;		// カラー画像座標系の距離データ(16bit, rawDepthDataの値を3bit左シフトしたもの)	今回は触れないでいいです
	cv::Mat depthImage;			// カラー画像座標系の距離画像	近いほど明るい色
	cv::Mat depthImage_double;

	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;	//PointCloud
	pcl::visualization::CloudViewer *viewer;		//PointCloudのビューワー

	//毎フレーム行う処理
	void setRgbImage();			//カラー画像のセット
	void setDepthImage();		//距離データ，距離画像のセット，PointCloudのセット
	void setPointCloud();		//(PointCloudのセット)

	void flipImgs();			//Matの左右反転

};


#endif // ! MY_KINECT