/*
* NativeVideoDeviceInfo.h
*
*  Created on: Jun 15, 2020
*      Author: zhangjianshi@yeecall.com
*/

#pragma once

#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <sstream>
#ifdef SDK_SIMPLE_INCLUDE
#include "common.h"
#include "YCKGlobalDefs.h"
#include "NVVideoImageBuffer.h"
#include "YCKDeviceID.h"
#else
#include "YCKSdwan/common.h"
#include "YCKit/YCKGlobalDefs.h"
#include "YCKit/Video/NVVideoImageBuffer.h"
#include "YCKit/YCKDeviceID.h"
#endif

/**
  音频输入设备（麦克风）信息。
*/
class DLL_DECL NativeMicrophoneInfo
{
public:
	int m_index;
	YCKDeviceId m_id;
	std::vector<int> m_avaliable_channle_list;
	std::vector<int> m_avaliable_sample_rate_list;
    bool bluetooth = false;
public:
	std::string testToString() { return "MIC Name: " + m_id.m_device_name + ", ID: " + m_id.m_device_id; }
};

/**
  管理音频输入设备（麦克风）信息，通过读取系统硬件配置更新设备列表和设备支持的参数。
*/
class DLL_DECL NativeMicrophoneManager
{
public:
    NativeMicrophoneManager();
	~NativeMicrophoneManager() { stopNotification(); }

	static std::shared_ptr<NativeMicrophoneManager> getInstance();

	/** 更新设备列表 */
	void updateDeviceInfoList();
	/** 取得设备列表 */
	std::vector<std::shared_ptr<NativeMicrophoneInfo> > getDeviceInfoList();
	/** 开始设备插拔通知（是否自动更新） */
	void startNotification(bool auto_update = false);
	/** 停止设备插拔通知 */
	void stopNotification();
	/** 设置选择的麦克风 */
	void selectDevice(std::shared_ptr<NativeMicrophoneInfo> selected);
	/** 取得当前选择的麦克风 */
	std::shared_ptr<NativeMicrophoneInfo> getSelectedDevice(bool api = false);
	/** 取得麦克风音量 */
	float getVolume(const YCKDeviceId & devId);
	/** 设置麦克风音量 */
	void setVolume(const YCKDeviceId & devId, float volume);

    bool defaultMode() { return default_mode; }
	/** 设置是否在日志中输出详细信息
	
	    用于测试，能查看程序中列出的全部视频输入设备和它们的全部参数
	*/
	void testSetLogDetail(bool log_detail = false);
private:
	std::vector<std::shared_ptr<NativeMicrophoneInfo> > m_mic_device_list;
	bool m_log_detail = false;
    uint64_t m_update_timestamp = 0;
    bool default_mode = true;
};

/**
音频输入设备（麦克风）信息。
*/
class DLL_DECL NativeSpeakerInfo
{
public:
	int m_index;
	YCKDeviceId m_id;
	std::vector<int> m_avaliable_channle_list;
	std::vector<int> m_avaliable_sample_rate_list;
    bool bluetooth = false;
public:
	std::string testToString() { return "SPK Name: " + m_id.m_device_name + ", ID: " + m_id.m_device_id; }
};

/**
  管理音频输出设备（扬声器）信息，通过读取系统硬件配置更新设备列表和设备支持的参数。
*/
class DLL_DECL NativeSpeakerManager
{
public:
    NativeSpeakerManager();
	~NativeSpeakerManager() { stopNotification(); }

	static std::shared_ptr<NativeSpeakerManager> getInstance();

	/** 更新设备列表 */
	void updateDeviceInfoList();
	/** 取得设备列表 */
	std::vector<std::shared_ptr<NativeSpeakerInfo> > getDeviceInfoList();
	/** 开始设备插拔通知（是否自动更新） */
	void startNotification(bool auto_update = false);
	/** 停止设备插拔通知 */
	void stopNotification();
	/** 设置选择的扬声器 */
	void selectDevice(std::shared_ptr<NativeSpeakerInfo> selected);
	/** 取得当前选择的扬声器 */
	std::shared_ptr<NativeSpeakerInfo> getSelectedDevice(bool api = false);
	/** 取得扬声器音量 */
	float getVolume(const YCKDeviceId & devId);
	/** 设置扬声器音量 */
	void setVolume(const YCKDeviceId & devId, float volume);

    bool defaultMode() { return default_mode; }
	/** 设置是否在日志中输出详细信息

	用于测试，能查看程序中列出的全部视频输入设备和它们的全部参数
	*/
	void testSetLogDetail(bool log_detail = false);
private:
	std::vector<std::shared_ptr<NativeSpeakerInfo> > m_speaker_device_list;
	bool m_log_detail = false;
    uint64_t m_update_timestamp = 0;
    bool default_mode = true;
};
