// VoiceCtrl.cpp : 实现文件
//

#include "stdafx.h"
#include "NetSDKDemo.h"
#include "VoiceCtrl.h"
#include "NetSDKDLL.h"
#include "NetSDKDemoDlg.h"


// CVoiceCtrl 对话框

char *g_pAudioType[] =
{
	_T("G711"),
	_T("AAC"),
	NULL
};

char *g_pSampleRate[] = 
{
	_T("8000"),
	_T("16000"),
	_T("48000"),
	NULL
};

IMPLEMENT_DYNAMIC(CVoiceCtrl, CDialog)

CVoiceCtrl::CVoiceCtrl(CRect rcWnd, CWnd* pParent /*=NULL*/)
	: CDialog(CVoiceCtrl::IDD, pParent)
	,m_rcClient(0, 0, rcWnd.Width(), rcWnd.Height())
{
	m_bStartTalk = FALSE;
}

CVoiceCtrl::~CVoiceCtrl()
{
	DestroyWindow();
}

void CVoiceCtrl::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_GROUP, m_ctlGroup);
	DDX_Control(pDX, IDC_STATIC_IP, m_ctlIP);
	DDX_Control(pDX, IDC_LIST_MEMBER, m_ctlVoiceMem);
	DDX_Control(pDX, IDC_CK_STARTTALK, m_ctlCKStartTalk);
	DDX_Control(pDX, IDC_CB_TYPE, m_ctlCBType);
	DDX_Control(pDX, IDC_CB_SAMPLERATE, m_ctlCBSampleRate);
	DDX_Control(pDX, IDC_RADIO_STEREO, m_ctlRadioStereo);
	DDX_Control(pDX, IDC_RADIO_MONO, m_ctlRadioMono);
}


BEGIN_MESSAGE_MAP(CVoiceCtrl, CDialog)
	ON_BN_CLICKED(IDC_BTN_ADDTALK, &CVoiceCtrl::OnBnClickedBtnAddtalk)
	ON_BN_CLICKED(IDC_BTN_QUITTALK, &CVoiceCtrl::OnBnClickedBtnQuittalk)
	ON_NOTIFY(NM_CLICK, IDC_LIST_MEMBER, &CVoiceCtrl::OnNMClickListMember)
	ON_BN_CLICKED(IDC_CK_STARTTALK, &CVoiceCtrl::OnBnClickedCkStarttalk)
	ON_BN_CLICKED(IDC_RADIO_MONO, &CVoiceCtrl::OnBnClickedRadioMono)
	ON_BN_CLICKED(IDC_RADIO_STEREO, &CVoiceCtrl::OnBnClickedRadioStereo)
	ON_CBN_SELCHANGE(IDC_CB_TYPE, &CVoiceCtrl::OnCbnSelchangeCbType)
END_MESSAGE_MAP()


// CVoiceCtrl 消息处理程序

BOOL CVoiceCtrl::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	m_ctlGroup.MoveWindow(CRect(m_rcClient.left+2, m_rcClient.top,m_rcClient.Width()-2, m_rcClient.Height()-2));
	m_ctlIP.SetWindowText("");
	
	DWORD dwStyle = GetWindowLong(m_ctlVoiceMem.m_hWnd, GWL_STYLE);
	dwStyle &=~(LVS_TYPEMASK);
	dwStyle &=~(LVS_EDITLABELS);

	SetWindowLong(m_ctlVoiceMem.m_hWnd, GWL_STYLE, dwStyle|LVS_REPORT|LVS_NOLABELWRAP|LVS_SHOWSELALWAYS);
	DWORD dwStyles = LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES ;//| LVS_EX_CHECKBOXES
	m_ctlVoiceMem.SetExtendedStyle( m_ctlVoiceMem.GetExtendedStyle()|dwStyles);

	m_ctlVoiceMem.MoveWindow(CRect(m_rcClient.left+2, m_rcClient.top + 180, m_rcClient.Width()-2, m_rcClient.Height() -2 ));
	
 	m_ctlVoiceMem.InsertColumn(0, _T("IP 地址"), LVCFMT_LEFT, 200);
	
	m_ctlCBType.ResetContent();
	for (int i=0; g_pAudioType[i] != NULL; i++)
	{
		m_ctlCBType.InsertString(i, g_pAudioType[i]);
	}
	m_ctlCBType.SetCurSel(0);
	m_ctlCBSampleRate.ResetContent();
	for (int i=0; g_pSampleRate[i] != NULL; i++)
	{
		m_ctlCBSampleRate.InsertString(i, g_pSampleRate[i]);
	}
	m_ctlCBSampleRate.SetCurSel(0);

	m_ctlRadioMono.SetCheck(BST_CHECKED);


	m_ctlCBSampleRate.EnableWindow(0);
	m_ctlRadioStereo.EnableWindow(0);
	m_ctlRadioMono.EnableWindow(0);

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

void CVoiceCtrl::OnBnClickedBtnAddtalk()
{
	// TODO: 在此添加控件通知处理程序代码
	if (!m_bStartTalk) 
	{
		AfxMessageBox("没有初始化对讲");
		return ;
	}

	CString strIP;
	m_ctlIP.GetWindowText(strIP);

	int iItemCount = m_ctlVoiceMem.GetItemCount();
	for (int i=0; i<iItemCount; i++)
	{
		CString str = m_ctlVoiceMem.GetItemText(i, 1);
		if (str.Compare(strIP) == 0)
		{
			AfxMessageBox("设备已在对讲列表中！！");
			return ;
		}
	}

	{
		CMapAutoLock Lock;
		CDevInfo * pDevInfo = NULL;
		POSITION pos = theApp.m_DevList.GetStartPosition();
		while (pos)
		{
			CString strKey;
			CDevInfo *pDevInfo = NULL;
			theApp.m_DevList.GetNextAssoc(pos, strKey, pDevInfo);
			if (pDevInfo && pDevInfo->iOpenAudio > 0)
			{
				//pDevInfo->iOpenAudio = 0;
				char szTmp[128] = {0};
				sprintf(szTmp, "%s正在开启语音， 请先关闭语音再对讲!", strKey.GetBuffer());
				MessageBox(szTmp, NULL, MB_OK);
				return;
			}
		}
	}
	


	int iUserID = 0;
	{
		CMapAutoLock Lock;	
		CDevInfo *pDevInfo = NULL;
		BOOL bFound = theApp.m_DevList.Lookup(strIP, pDevInfo);
		if (bFound)
		{
			iUserID = pDevInfo->iUserID;
		}
	}

	if (iUserID != 0)
	{
		//开启对讲
		int iErr = IP_NET_DVR_StartVoiceCom(iUserID, 0, 1, NULL, NULL);
		if (iErr == 0)
		{
			((CNetSDKDemoDlg *)GetParent())->m_pMenuDlg->GetDlgItem(IDC_BTN_OPENAUDIO)->SetWindowText(_T("开启音频"));
			((CNetSDKDemoDlg *)GetParent())->m_pMenuDlg->GetDlgItem(IDC_BTN_OPENAUDIO)->EnableWindow(FALSE);
			TRACE("IP_NET_DVR_StartVoiceCom success!!!\n");
		}
		if (iErr == ERR_NOT_FIND_DEVICE)
		{
			AfxMessageBox("句柄错误");
			return ;
		}

		else if (iErr == ERR_IS_STARTAUDIO_ERROR)
		{
			AfxMessageBox("当前设备处于对讲状态");
			return ;
		}

		else if (iErr == ERR_DEV_NOT_CONNECTED)
		{
			AfxMessageBox("设备未连接");
			return ;
		}

		else if (iErr == ERR_DEV_NOT_LOGIN)
		{
			AfxMessageBox("设备未登录成功");
			return ;
		}
	}
	else
	{
		AfxMessageBox("设备没有登录!!!");
	}
}

void CVoiceCtrl::OnBnClickedBtnQuittalk()
{
	// TODO: 在此添加控件通知处理程序代码
	((CNetSDKDemoDlg *)GetParent())->m_pMenuDlg->GetDlgItem(IDC_BTN_OPENAUDIO)->EnableWindow(TRUE);

	if (!m_bStartTalk) 
	{
		AfxMessageBox("没有初始化对讲");
		return ;
	}

	CString strIP;
	m_ctlIP.GetWindowText(strIP);

	{
		CMapAutoLock Lock;
		CDevInfo *pDevInfo = NULL;
		BOOL bFound = theApp.m_DevList.Lookup(strIP,  pDevInfo);
		if (bFound)
		{
	//		if (pDevInfo->bAddTalk)
//			{
// 				if (pDevInfo->iUserID <= 0)
// 				{
// 					return;
// 				}

				int nMem = m_ctlVoiceMem.GetItemCount();
				for (int i=0; i<nMem; i++)
				{
					if (strIP.Compare(m_ctlVoiceMem.GetItemText(i, 0)) == 0)
					{
						m_ctlVoiceMem.DeleteItem(i);
						break;
					}
				}


				IP_NET_DVR_RemoveTalk(pDevInfo->iUserID);

				IP_NET_DVR_StopVoiceCom(pDevInfo->iUserID);

				pDevInfo->bAddTalk = FALSE;
				//m_ctlIP.SetWindowText(_T(""));
	//		}
		}
	}
}

void CVoiceCtrl::OnNMClickListMember(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	
	NMLISTVIEW*   pp = (NMLISTVIEW*)pNMHDR; 

	if (pp->iItem >= 0)
	{
		CString strIP = m_ctlVoiceMem.GetItemText(pp->iItem, 0);
		m_ctlIP.SetWindowText(strIP);
	}	
}


void CVoiceCtrl::SetSelIP(CString &strIP)
{
	m_ctlIP.SetWindowText(strIP);
}

BOOL CVoiceCtrl::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (pMsg->message == WM_DEV_STATUS)
	{
		CString strIP;
		BOOL bOpenVoice = FALSE;
		CSDKEvent *pSDKEvent = theApp.m_MSGVoice.Event_RemoveHead();
		if (pSDKEvent->nStateCode == EVENT_STARTAUDIOOK)
		{
			
			int iADD = IP_NET_DVR_AddTalk(pSDKEvent->lUser);
			TRACE("nStateCode = %d\n", iADD);
			if(iADD == 0)
			{
				TRACE("IP_NET_DVR_AddTalk ==> success\n");
			}
			else
			{
				if (ERR_NOT_FIND_DEVICE == iADD)
				{
					AfxMessageBox("句柄错误，加入广播列表失败!");
				}
				else if (ERR_NOT_STARTTALK_MODE_ERROR == iADD)
				{
					AfxMessageBox("未初始化广播参数，加入广播列表失败!");
				}
				else if (ERR_AUDIO_PARAM_ERROR == iADD)
				{
					AfxMessageBox("当前设备未启动对讲，或参数不相同，加入广播列表失败!");
				}
				else if (ERR_NOT_STARTTALK_MODE_ERROR == iADD)
				{
					AfxMessageBox("当前未初始化音频广播参数，加入广播列表失败!");
				}
				else
				{
					AfxMessageBox("加入广播列表失败!");
				}

				IP_NET_DVR_RemoveTalk(pSDKEvent->lUser);
				IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
				
				goto _RETURN;
			}

			bOpenVoice = TRUE;
		}
		else
		{
			AfxMessageBox("开启对讲失败，请确认设备支持对讲!!!");
			((CNetSDKDemoDlg *)GetParent())->m_pMenuDlg->GetDlgItem(IDC_BTN_OPENAUDIO)->EnableWindow(TRUE);
			IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
			goto _RETURN;
		}
#if 0
		else if (pSDKEvent->nStateCode == EVENT_STARTAUDIOFAILED)
		{
			AfxMessageBox(" 启动对讲失败");
			bOpenVoice = FALSE;
	
			IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
			
			goto _RETURN;
		}

		else if (pSDKEvent->nStateCode == EVENT_STARTAUDIO_ISBUSY)
		{
			AfxMessageBox(" 设备对讲被占用");
			bOpenVoice = FALSE;
			IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
			goto _RETURN;
		}

		else if (pSDKEvent->nStateCode == EVENT_STARTAUDIO_PARAMERROR)
		{
			AfxMessageBox(" 不支持此音频参数对讲");
			bOpenVoice = FALSE;
			IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
			goto _RETURN;
		}

		else if (pSDKEvent->nStateCode == EVENT_STARTAUDIO_AUDIODDISABLED)
		{
			AfxMessageBox(" 不支持对讲");
			bOpenVoice = FALSE;
			IP_NET_DVR_StopVoiceCom(pSDKEvent->lUser);
			goto _RETURN;
		}
#endif
		int iUserID = 0;
		{
			CMapAutoLock Lock;
			POSITION pos = theApp.m_DevList.GetStartPosition();
			while (pos)
			{
				CString strKey;
				CDevInfo *pDevInfo = NULL;
				theApp.m_DevList.GetNextAssoc(pos, strKey, pDevInfo);
				if (pDevInfo->iUserID == pSDKEvent->lUser)
				{
					strIP.Format("%s", pDevInfo->m_IPCEntry.lanCfg.IPAddress);
					pDevInfo->bAddTalk = bOpenVoice;
					iUserID = pDevInfo->iUserID;
					break;
				}
			}
		}

		if (bOpenVoice)
		{	
			int iItemCount = m_ctlVoiceMem.GetItemCount();
			int iItemAdd = m_ctlVoiceMem.InsertItem(iItemCount, strIP.GetBuffer());
		}
		else
		{
			int iItemCount = m_ctlVoiceMem.GetItemCount();
			for (int i=0; i<iItemCount; i++)
			{
				CString strItemText = m_ctlVoiceMem.GetItemText(i, 0);
				if (strIP.Compare(strItemText) == 0)
				{
					m_ctlVoiceMem.DeleteItem(i);
					break;
				}
			}
		}
_RETURN:
		SAFE_DELETE(pSDKEvent);
		return TRUE;
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CVoiceCtrl::OnBnClickedCkStarttalk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData();
	int iCheck = m_ctlCKStartTalk.GetCheck();
	if (iCheck)
	{
		if (!m_bStartTalk)
		{
			int audiotype = m_ctlCBType.GetCurSel();			//:表示音频类型，1表示AAC，0表示G711
			int iSel = m_ctlCBSampleRate.GetCurSel();
			int samplerate = 8000;		//:采样率，一般为16000
			if (iSel == 0)
				samplerate = 8000;
			else if (iSel == 1)
				samplerate = 16000;
			else if (iSel == 2)
				samplerate = 48000;
			int bitspersample = 16;		// ：一般为16
			int iCheck = m_ctlRadioMono.GetCheck();
			int channels = 1;			//：声音数，一般为2
			if (iCheck>0)
				channels = 1;
			else channels = 2;

			int bStartTalk = IP_NET_DVR_StartTalk(audiotype, samplerate, bitspersample, channels);

			if (bStartTalk == 0)
			{
				EnableParamWnd(FALSE);
				m_bStartTalk = 1;
				return ;
			}

			else if (bStartTalk == ERR_OPEN_AUDIOCAPTURE_FAIL)
			{
				AfxMessageBox("打开音频采集设备失败，可能是声卡采集被占用");
				return ;
			}

			else if (bStartTalk == ERR_START_AUDIOCAPTURE_FAIL)
			{
				AfxMessageBox("启动音频采集失败，可能是参数错误.");
				return ;
			}

		}
	}
	else
	{
		if (m_bStartTalk)
		{
			IP_NET_DVR_StopTalk();

			m_ctlVoiceMem.DeleteAllItems();

			{
				CMapAutoLock Lock;
				POSITION pos = theApp.m_DevList.GetStartPosition();
				while (pos)
				{
					CDevInfo *pDevInfo = NULL;
					CString strKey;
					theApp.m_DevList.GetNextAssoc(pos, strKey, pDevInfo);
					pDevInfo->bAddTalk = FALSE;
				}
			}
			m_bStartTalk = FALSE;
		}
		EnableParamWnd(TRUE);
	}

}

void CVoiceCtrl::OnBnClickedRadioMono()
{
	// TODO: 在此添加控件通知处理程序代码
	m_ctlRadioMono.SetCheck(1);
	m_ctlRadioStereo.SetCheck(0);
}

void CVoiceCtrl::OnBnClickedRadioStereo()
{
	// TODO: 在此添加控件通知处理程序代码
	m_ctlRadioMono.SetCheck(0);
	m_ctlRadioStereo.SetCheck(1);
}


void CVoiceCtrl::EnableParamWnd(BOOL bEnable)
{
	m_ctlCBType.EnableWindow(bEnable);
	//m_ctlCBSampleRate.EnableWindow(bEnable);
 	//m_ctlRadioStereo.EnableWindow(bEnable);
 	//m_ctlRadioMono.EnableWindow(bEnable);
	UpdateData(FALSE);
}
void CVoiceCtrl::OnCbnSelchangeCbType()
{
	// TODO: 在此添加控件通知处理程序代码
	int iCurSel = m_ctlCBType.GetCurSel();
	if (0 == iCurSel)
	{
		m_ctlCBSampleRate.SetCurSel(0);
		m_ctlRadioStereo.SetCheck(0);
		m_ctlRadioMono.SetCheck(1);
		//CButton m_ctlRadioMono;
	}
	else if (1 == iCurSel)
	{
		m_ctlCBSampleRate.SetCurSel(1);
		m_ctlRadioStereo.SetCheck(1);
		m_ctlRadioMono.SetCheck(0);
	}
}
