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

#include "stdafx.h"
#include "NetSDKDemo.h"
#include "SnapDlg.h"
#include "DllPlayer.h"

#include "NetSDKDemoDlg.h"
// CSnapDlg 对话框

IMPLEMENT_DYNAMIC(CSnapDlg, CDialog)

CSnapDlg::CSnapDlg(CRect rcWnd, CWnd* pParent /*=NULL*/)
	: CDialog(CSnapDlg::IDD, pParent)
	,m_rcClient(0, 0, rcWnd.Width(), rcWnd.Height())
{
	m_bYUVtoRGB = FALSE;
	m_nVideoWidth = 0;
	m_nVideoHeight = 0;
	m_nColorBit = 32;
}

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

void CSnapDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_GROUP, m_ctlGroup);
	DDX_Control(pDX, IDC_ED_PATH, m_ctlEDPath);
	DDX_Control(pDX, IDC_CK_DEFAULT, m_ctlCKDefault);
	DDX_Control(pDX, IDC_CK_CUSTOM, m_ctlCKCustom);
	DDX_Control(pDX, IDC_CB_PICTURE, m_ctlCBPictureType);
	DDX_Control(pDX, IDC_LIST2, m_ctlCallBack);
}


BEGIN_MESSAGE_MAP(CSnapDlg, CDialog)
	ON_BN_CLICKED(IDC_BTN_LOADING, &CSnapDlg::OnBnClickedBtnLoading)
	ON_BN_CLICKED(IDC_BTN_SNAP, &CSnapDlg::OnBnClickedBtnSnap)
	ON_BN_CLICKED(IDC_CK_DEFAULT, &CSnapDlg::OnBnClickedCkDefault)
	ON_BN_CLICKED(IDC_CK_CUSTOM, &CSnapDlg::OnBnClickedCkCustom)
	ON_BN_CLICKED(IDC_BUTTON4, &CSnapDlg::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &CSnapDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON6, &CSnapDlg::OnBnClickedButton6)
END_MESSAGE_MAP()


// CSnapDlg 消息处理程序

BOOL CSnapDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	
	if (pMsg->message == WM_KEYDOWN)
	{
		if(pMsg->wParam == 13)
			return TRUE;
		if (pMsg->wParam == 27)
		{
			::PostMessage(GetParent()->m_hWnd, WM_KEYDOWN, 27, 0);
			return TRUE;
		}
	}
	return CDialog::PreTranslateMessage(pMsg);
}

void CSnapDlg::OnBnClickedBtnLoading()
{
	// TODO: 在此添加控件通知处理程序代码
	BROWSEINFO bi;
	ZeroMemory(&bi,sizeof(BROWSEINFO));
	LPITEMIDLIST pidl = SHBrowseForFolder(&bi);

	TCHAR path[MAX_PATH] = {0};
	if(pidl != NULL)
	{
		SHGetPathFromIDList(pidl,path);

		m_ctlEDPath.SetWindowText(path);
	}
}

void CSnapDlg::OnBnClickedBtnSnap()
{
	// TODO: 在此添加控件通知处理程序代码
	int iCheck = m_ctlCKDefault.GetCheck();
	CString strPath;
	m_ctlEDPath.GetWindowText(strPath);
	
	TCHAR szDrive[_MAX_DRIVE] = {0};
	TCHAR szDir[_MAX_DIR] = {0};
	TCHAR szName[_MAX_DIR] = {0};

	_tsplitpath(strPath, szDrive, szDir, NULL, NULL);
	CString strOnlyPath;
	strOnlyPath.Format("%s%s", szDrive, szDir);

	DWORD dwFileAttr = GetFileAttributes(strOnlyPath);
	if (dwFileAttr == INVALID_FILE_ATTRIBUTES)
	{
		AfxMessageBox("路径不可用!!!");
		return;
	}
	CNetSDKDemoDlg *pNetSDKDemoDlg  = (CNetSDKDemoDlg *)GetParent();
	HWND hWnd = pNetSDKDemoDlg->GetCurSelWnd();
	CString StrKey = pNetSDKDemoDlg->GetWndUser(hWnd);

	
	int iPlayID = -1;
	{
		CMapAutoLock Lock;
		CDevInfo *pDevInfo = NULL;
		BOOL bFound = theApp.m_DevList.Lookup(StrKey, pDevInfo);
		if (bFound)
		{
			iPlayID = pDevInfo->lPlayerID;
		}
	}

	if (iPlayID <= 0)
	{
		AfxMessageBox("视频没有开启！！");
		return ;
	}

	if (iCheck)
	{
		if (iPlayID  > 0)
		{
			int iCatPic = IP_TPS_CatchPic(iPlayID, strPath.GetBuffer());
			if (iCatPic == ERR_PLY_VIDEOCHANNELID_ERROR)
			{
				AfxMessageBox("视频通道端口nPort错误");
				return ;
			}

			else if (iCatPic == ERR_PLAY_NOTPLAYMODE_ERROR)
			{
				AfxMessageBox("未处于播放模式，抓图失败");
				return ;
			}
			else if (iCatPic == ERR_PLY_DISPLAY_OFF_ERROR)
			{
				AfxMessageBox("当前视频不是播放状态");
				return ; 
			}
		}
	}
	else
	{	
		CString strFile;
		SYSTEMTIME time = {0};
		GetLocalTime(&time);
		int iSel = m_ctlCBPictureType.GetCurSel();
		if (iSel == 0)
		{
			strFile.Format("%s\\%04d%02d%02d%02d%02d%02d%03d.bmp", strPath, time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
		}
		else
		{
			strFile.Format("%s\\%04d%02d%02d%02d%02d%02d%03d.jpg", strPath, time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
		}
		
		if (iPlayID  > 0)
		{
			IP_TPS_CatchPicByFileName(iPlayID, strFile.GetBuffer(), iSel==0?0:1);
		}
	}

}


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

	// TODO:  在此添加额外的初始化
	m_ctlCKDefault.SetCheck(1);
	m_ctlCKCustom.SetCheck(0);
	m_ctlCBPictureType.SetCurSel(1);
	m_ctlEDPath.SetWindowText(_T("C:\\"));
	m_ctlCBPictureType.EnableWindow(FALSE);
	m_ctlGroup.MoveWindow(CRect(m_rcClient.left+2, m_rcClient.top,m_rcClient.Width()-2, m_rcClient.Height()-2)); 

	colorspace_init();
	GetDlgItem(IDC_BUTTON6)->EnableWindow(FALSE);

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

void CSnapDlg::OnBnClickedCkDefault()
{
	// TODO: 在此添加控件通知处理程序代码
	int iCheck = m_ctlCKDefault.GetCheck();
	if (iCheck == 1)
	{
		m_ctlCKCustom.SetCheck(0);
		m_ctlCBPictureType.SetCurSel(1);
		m_ctlCBPictureType.EnableWindow(FALSE);
	}
	else
	{
		m_ctlCKCustom.SetCheck(1);
		m_ctlCBPictureType.EnableWindow(TRUE);
	}
}

void CSnapDlg::OnBnClickedCkCustom()
{
	// TODO: 在此添加控件通知处理程序代码
	int iCheck = m_ctlCKCustom.GetCheck();
	if (iCheck == 1)
	{
		m_ctlCKDefault.SetCheck(0);
		m_ctlCBPictureType.EnableWindow(TRUE);
	}
	else
	{
		m_ctlCKDefault.SetCheck(1);
		m_ctlCBPictureType.EnableWindow(FALSE);
	}
}

void CSnapDlg::OnBnClickedButton4()
{
	// TODO: 在此添加控件通知处理程序代码
	CNetSDKDemoDlg *pNetSDKDemoDlg  = (CNetSDKDemoDlg *)GetParent();
	HWND hWnd = pNetSDKDemoDlg->GetCurSelWnd();
	CString StrKey = pNetSDKDemoDlg->GetWndUser(hWnd);

	int iPlayID = -1;
	{
		CMapAutoLock Lock;
		CDevInfo *pDevInfo = NULL;
		BOOL bFound = theApp.m_DevList.Lookup(StrKey, pDevInfo);
		if (bFound)
		{
			iPlayID = pDevInfo->lPlayerID;
			if (pDevInfo->pAVParam)
			{
				memset((void*)&m_oAVParm, 0, sizeof(STREAM_AV_PARAM));
				memcpy((void*)&m_oAVParm, pDevInfo->pAVParam,  sizeof(STREAM_AV_PARAM));
				m_nVideoWidth = m_oAVParm.videoParam.width;
				m_nVideoHeight = m_oAVParm.videoParam.height;				
			}
		}
	}
	if (iPlayID <= 0)
	{
		AfxMessageBox("视频没有开启！！");
		return ;
	}
	
	int iRet = IP_TPS_SetDecCallBack(iPlayID, OnMediaDataRecv, this);
	if (iRet != 0)
	{
		AfxMessageBox("开启视频回调失败！！");
		return ;
	}
	GetDlgItem(IDC_BUTTON6)->EnableWindow(TRUE);
}

void CSnapDlg::OnBnClickedButton5()
{
	// TODO: 在此添加控件通知处理程序代码
	GetDlgItem(IDC_BUTTON6)->EnableWindow(FALSE);

	CNetSDKDemoDlg *pNetSDKDemoDlg  = (CNetSDKDemoDlg *)GetParent();
	HWND hWnd = pNetSDKDemoDlg->GetCurSelWnd();
	CString StrKey = pNetSDKDemoDlg->GetWndUser(hWnd);

	int iPlayID = -1;
	{
		CMapAutoLock Lock;
		CDevInfo *pDevInfo = NULL;
		BOOL bFound = theApp.m_DevList.Lookup(StrKey, pDevInfo);
		if (bFound)
		{
			iPlayID = pDevInfo->lPlayerID;			
		}
	}
	if (iPlayID <= 0)
	{
		AfxMessageBox("视频没有开启！！");
		return ;
	}

	int iRet = IP_TPS_SetDecCallBack(iPlayID, NULL, NULL);
	if (iRet != 0)
	{
		AfxMessageBox("关闭视频回调失败！！");
		return ;
	}
}

void CSnapDlg::OnBnClickedButton6()//YUV2RGB
{
	m_bYUVtoRGB = TRUE;
}


int  CALLBACK  CSnapDlg::OnMediaDataRecv(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, void * pUser,long nReserved2)
{
	CSnapDlg *pSnapDlg = (CSnapDlg *)pUser;
	CString strCallBack;
	strCallBack.Format("nSize = %d\n", nSize);
	int iCount = pSnapDlg->m_ctlCallBack.GetCount();
	if (iCount > 100)
	{
		TRACE("1111111111\n");
		pSnapDlg->m_ctlCallBack.DeleteString(iCount-1);
	}
	pSnapDlg->m_ctlCallBack.InsertString(0,strCallBack.GetBuffer());

	if (pSnapDlg->m_bYUVtoRGB)
	{
		pSnapDlg->m_bYUVtoRGB = FALSE;
		unsigned char * pRGBbuffer=NULL;
		int MemorySize=pSnapDlg->m_nVideoWidth * pSnapDlg->m_nVideoHeight * pSnapDlg->m_nColorBit / 8;
		pRGBbuffer = (uint8_t *)new char[MemorySize];
		int lpscan = pSnapDlg->m_nVideoWidth * pSnapDlg->m_nColorBit/8;;
		int convert_ok=YUVToRGB(pSnapDlg->m_nColorBit,pSnapDlg->m_nVideoWidth,pSnapDlg->m_nVideoHeight,(unsigned char*)pBuf,pRGBbuffer,lpscan);					
		if(convert_ok)
		{
			int nsuccess=1;
			HBITMAP hBmp=CreateBitmap(pSnapDlg->m_nVideoWidth, pSnapDlg->m_nVideoHeight,1, pSnapDlg->m_nColorBit,pRGBbuffer);
			if(hBmp)
			{
				SYSTEMTIME	nowtime;
				GetLocalTime(&nowtime);
				
				CString strFileName;
				strFileName.Format("c:\\YUV2RGB_%04d%02d%02d%02d%02d%02d%04d_%08d.bmp",
					nowtime.wYear,nowtime.wMonth,nowtime.wDay,nowtime.wHour,
					nowtime.wMinute,nowtime.wSecond,GetTickCount()%10000);
		
				pSnapDlg->SaveBmp2File(hBmp,strFileName);
			}
		}
	}

	return 0;
}

int CSnapDlg::SaveBmp2File(HBITMAP hBitmap, CString strFileName)
{
	if(!hBitmap || strFileName.IsEmpty())
	{
		return FALSE;
	}
	HDC hDC;
	// 定义调色板大小, 位图中像素字节大小 ，位图文件大小 , 写入文件字节数 
	DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; 
	BITMAP Bitmap;							// 位图属性结构
	BITMAPFILEHEADER bmfHdr;				// 位图文件头结构
	BITMAPINFOHEADER bi;					// 位图信息头结构
	LPBITMAPINFOHEADER lpbi;				// 指向位图信息头结构
	HANDLE fh, hDib, hPal, hOldPal = NULL;	// 定义文件，分配内存句柄，调色板句柄
	GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
	bi.biSize = sizeof(BITMAPINFOHEADER);
	bi.biWidth = Bitmap.bmWidth;
	bi.biHeight = Bitmap.bmHeight;
	bi.biPlanes = 1;
	bi.biBitCount = Bitmap.bmBitsPixel;
	bi.biCompression = BI_RGB;
	bi.biSizeImage = 0;
	bi.biXPelsPerMeter = 0;
	bi.biYPelsPerMeter = 0;
	bi.biClrImportant = 0;
	bi.biClrUsed = 0;
	dwBmBitsSize = ((Bitmap.bmWidth * Bitmap.bmBitsPixel + 31) / 32) * 4 * Bitmap.bmHeight;
	//为位图内容分配内存 
	hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); 
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
	*lpbi = bi; 
	// 处理调色板  
	hPal = GetStockObject(DEFAULT_PALETTE); 
	if (hPal) 
	{
		hDC = ::GetDC(NULL); 
		hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE); 
		RealizePalette(hDC); 
	}

	// 获取该调色板下新的像素值 
	GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,(BITMAPINFO *)lpbi, DIB_RGB_COLORS); 

	// 恢复调色板  
	if(hOldPal) 
	{
		::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
		RealizePalette(hDC);
		::ReleaseDC(NULL, hDC);
	}

	// 创建位图文件
	fh = CreateFile(strFileName , GENERIC_WRITE,0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if (fh == INVALID_HANDLE_VALUE)
		return -1; 

	// 设置位图文件头 
	bmfHdr.bfType = 0x4D42; // "BM"
	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;

	// 写入位图文件头
	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

	// 写入位图文件其余内容
	WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);

	// 清除  
	GlobalUnlock(hDib);
	GlobalFree(hDib);
	CloseHandle(fh);
	return 0;
}
