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

#include "stdafx.h"
#include "CH91PayloadSoftware.h"
#include "ShowReplayDlg.h"
#include "afxdialogex.h"
#include "Global.h"
#include "GlobalMessage.h"

// 多媒体定时器
#include "MMSystem.h"
#pragma comment(lib, "winmm")

//timeSetEvent中的回调函数,名字随便起,但是内容固定
void CALLBACK TimerPlayFunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
	// 目的:调用ReadandPlay,将dwUser强制转换为ptr,可以使用ptr格式,更加方便
	CShowReplayDlg* ptr = reinterpret_cast<CShowReplayDlg*>(dwUser);
	// 读取文件并播放
	if (ptr != NULL)
	{
		ptr->ReadAndPlay();
	}
}


// CShowReplayDlg 对话框

IMPLEMENT_DYNAMIC(CShowReplayDlg, CDialogEx)

CShowReplayDlg::CShowReplayDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CShowReplayDlg::IDD, pParent)
{
	m_TimerID = 0;	    
	m_TimerPeriod = 20;  // 默认20ms	调用一次多媒体时钟函数,由于EO和IR穿插,因此一秒钟调用50次,EO和IR帧频各25
	m_bFileOpen = FALSE;

	m_bIsPlay = FALSE;  
	m_bPauseSliderReflect = FALSE;
	m_bService = FALSE; // 初始情况下后台服务程序未打开

	m_bTransParent = FALSE; // 初始情况下不透明
}

CShowReplayDlg::~CShowReplayDlg()
{
}

void CShowReplayDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SLIDER_REPLAYRATIO, m_SliderReplayRatio);
}


BEGIN_MESSAGE_MAP(CShowReplayDlg, CDialogEx)
	ON_BN_CLICKED(IDC_BTN_OPENFILE, &CShowReplayDlg::OnBnClickedBtnOpenfile)
	ON_BN_CLICKED(IDC_BTN_FILEPLAYPAUSE, &CShowReplayDlg::OnBnClickedBtnFileplaypause)
	ON_BN_CLICKED(IDC_BTN_FILESTOP, &CShowReplayDlg::OnBnClickedBtnFilestop)
	ON_BN_CLICKED(IDC_BTN_FILESLOW, &CShowReplayDlg::OnBnClickedBtnFileslow)
	ON_BN_CLICKED(IDC_BTN_FILEFAST, &CShowReplayDlg::OnBnClickedBtnFilefast)
	ON_CBN_SELCHANGE(IDC_COMBOX_PLAYTYPE, &CShowReplayDlg::OnCbnSelchangeComboxPlaytype)
	ON_WM_DESTROY()
	ON_MESSAGE(WM_BITMAPSLIDER_MOVING, OnBitmapSliderMoving)
	ON_MESSAGE(WM_RETURN_PAYLOAD_TYPE_WARNING, &CShowReplayDlg::ReturnPayloadTypeWarning)
END_MESSAGE_MAP()


// CShowReplayDlg 消息处理程序
BOOL CShowReplayDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	// 键盘消息
	if (pMsg->message == WM_KEYDOWN)
	{
		// 忽略ESC和回车键
		if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
		{
			return TRUE;
		}
		// F1键控制“视频控制”窗口的现实/隐藏
		if (pMsg->wParam == VK_F1)
		{
			// 关闭窗口
			OnOK();
		}
	}
	return CDialogEx::PreTranslateMessage(pMsg);
}


BOOL CShowReplayDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置对话框标题
	SetWindowText(g_str_TitleReplay);
	// 设置文件路径名称
	GetDlgItem(IDC_STATIC_HF_FILE_PATH) -> SetWindowText(g_str_FilePath);
	//设置回放进度条各参数
	m_SliderReplayRatio.SetBitmapChannel( IDB_MP_CHANNEL, IDB_MP_CHANNEL_ACTIVE );
	m_SliderReplayRatio.SetBitmapThumb( IDB_MP_THUMB, IDB_MP_THUMB_ACTIVE, TRUE );
	m_SliderReplayRatio.DrawFocusRect( FALSE );
	m_SliderReplayRatio.SetMargin( 2, 3, 2, 0 );
	m_SliderReplayRatio.SetRange(0, 5000);
	m_SliderReplayRatio.SetPos(0);
	
	// 获取窗口句柄
	g_ReplayDlgHwnd = GetSafeHwnd();


	// 工作模式

	((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->AddString("回放");
	((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->AddString("实时");

	((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->SetCurSel(1); 

	OnCbnSelchangeComboxPlaytype();

	// 设置界面按钮
	// 打开文件
	m_Btn_OpenFile.SubclassDlgItem(IDC_BTN_OPENFILE, this);
	m_Btn_OpenFile.SetIcon(IDI_ICON_OPENFILE);
	m_Btn_OpenFile.DrawTransparent(TRUE);
	m_Btn_OpenFile.SetTooltipText("文件");
	m_Btn_OpenFile.DrawBorder(FALSE);

	// 开始/暂停
	m_Btn_PlayPause.SubclassDlgItem(IDC_BTN_FILEPLAYPAUSE, this);
	m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);
	m_Btn_PlayPause.DrawTransparent(TRUE);
	m_Btn_PlayPause.SetTooltipText("开始/暂停");
	m_Btn_PlayPause.DrawBorder(FALSE);

	// 停止
	m_Btn_Stop.SubclassDlgItem(IDC_BTN_FILESTOP, this);
	m_Btn_Stop.SetIcon(IDI_ICON_STOP);
	m_Btn_Stop.DrawTransparent(TRUE);
	m_Btn_Stop.SetTooltipText("停止");
	m_Btn_Stop.DrawBorder(FALSE);

	// 加速
	m_Btn_SpeedUp.SubclassDlgItem(IDC_BTN_FILEFAST, this);
	m_Btn_SpeedUp.SetIcon(IDI_ICON_SPEEDUP);
	m_Btn_SpeedUp.DrawTransparent(TRUE);
	m_Btn_SpeedUp.SetTooltipText("加速");
	m_Btn_SpeedUp.DrawBorder(FALSE);

	// 减速
	m_Btn_SpeedDown.SubclassDlgItem(IDC_BTN_FILESLOW, this);
	m_Btn_SpeedDown.SetIcon(IDI_ICON_SPEEDDOWN);
	m_Btn_SpeedDown.DrawTransparent(TRUE);
	m_Btn_SpeedDown.SetTooltipText("减速");
	m_Btn_SpeedDown.DrawBorder(FALSE);

	// 设置播放比率初始值
	GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(_T("0%"));
	return TRUE; 
}


// 打开回放视频文件
void CShowReplayDlg::OnBnClickedBtnOpenfile()
{
	// 首先停止播放视频
	OnBnClickedBtnFilestop();
	// 打开文件夹
	CFileDialog Dialog(
		TRUE, 
		NULL,
		NULL,
		OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
		_T("Video Files (*.tx) |*.tx| All Files (*.*) |*.*||"),
		NULL);
	Dialog.m_ofn.lpstrTitle = _T("Open Files");

	if (Dialog.DoModal()!=IDOK)
	{
		return;
	}

	if (m_bIsPlay == FALSE)
	{
		m_HFfilePath = Dialog.GetPathName();

		// 显示文件路径
		GetDlgItem(IDC_STATIC_HF_FILE_PATH)->SetWindowText(g_str_FilePath + m_HFfilePath);
	}
	else
	{

	}
}

//启动定时器——多媒体定时器,与
void CShowReplayDlg::StartTimer()
{
	// 启动定时器,回调函数:TimerPlayFunc,固定格式,只需编译回调函数TimerPlayFunc
	m_TimerID = timeSetEvent(m_TimerPeriod,	1,	TimerPlayFunc, (DWORD_PTR)this, TIME_PERIODIC);
}

//停止定时器
void CShowReplayDlg::StopTimer()
{
	if (m_TimerID != 0)
	{
		timeKillEvent(m_TimerID);
		m_TimerID = 0;
	}
}

// 播放及暂停视频
void CShowReplayDlg::OnBnClickedBtnFileplaypause()
{
	if (m_bFileOpen == FALSE)
	{
		// 显示文件名之后打开文件,获取文件长度,文件内容当前进度以及文件
		if (m_ReplayFile.Open(m_HFfilePath, CFile::modeRead) == TRUE)
		{
			m_bFileOpen = TRUE;

			m_FileInfo.FileTotalLen = m_ReplayFile.GetLength(); // 获取文件长度
			m_FileInfo.curFilePos = 0;                                         //获取文件当前内容位置为0
			m_FileInfo.FrameLen = 1024;//1024;                                  //设定读取一帧的字节大小(10KB)
		}
		else
		{
			return;
		}
	}
	if (m_bFileOpen == TRUE)
	{
		//如果没有播放
		if (m_bIsPlay == FALSE)
		{
			// 如果上一次定时器(或者其他情况下)处于意外没有停止,则停止当前定时器
			if (m_TimerID != 0)
			{
				timeKillEvent(m_TimerID);
				m_TimerID = 0;
			}

			m_bIsPlay = TRUE;
			//设定新的定时器,并用定时器调用读取每一帧进行播放
			StartTimer();
			//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("暂停");
			m_Btn_PlayPause.SetIcon(IDI_ICON_PAUSE);
		}
		//如果正在播放,则暂停
		else
		{
			if (m_TimerID != 0)
			{
				timeKillEvent(m_TimerID);
				m_TimerID = 0;
			}

			m_bIsPlay = FALSE;
			g_bEOImgUpdate = FALSE;
			g_bIRImgUpdate = FALSE;
			//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("播放");
			m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);
		}
	}
	g_bReplayPlay = m_bIsPlay;
}

//读文件并播放,在TimerPlayFunc中调用
void CShowReplayDlg::ReadAndPlay()
{
	//如果正在播放且滑动条没有暂停相应
	if(m_bIsPlay == TRUE && m_bPauseSliderReflect == FALSE)
	{
		if (m_bFileOpen == FALSE)
		{
			return;
		}

		int readLen = 0;
		//时钟设定之后,每次调用函数,每次顺次读一下文件
		readLen = m_ReplayFile.Read(m_FileInfo.Buffer, m_FileInfo.FrameLen);
		
		//当前文件位置
		m_FileInfo.curFilePos += readLen;
		
		// 判断是否已到文件结尾
		if(m_FileInfo.curFilePos < m_FileInfo.FileTotalLen)
		{
			// 输出原始数据
			ReplayInputData(m_FileInfo.Buffer, readLen);

			// 输出播放百分比
			double ratio = 0.0;
			ratio = m_FileInfo.curFilePos * 1.0 / m_FileInfo.FileTotalLen;
			int rangeMax = m_SliderReplayRatio.GetRangeMax();
			int currentPos = static_cast<int>(ratio * rangeMax + 0.5); // int类型强制转换为向下取整,加上0.5可以保证取整时四舍五入

			m_bPauseSliderReflect = TRUE; // 暂停滑动条响应
			m_SliderReplayRatio.SetPos(currentPos);
			CString str;
			str.Format("%.1f", ratio * 100);
			str = str + "%";
/*			UpdateData(TRUE);*/
			GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(str);
			m_bPauseSliderReflect = FALSE; // 所有关于输出百分比设置的事情结束之后,开始滑动条响应
		}
		else
		{
		}
	}
}

// 设置回放进度
void CShowReplayDlg::SetFileReplayRatio(double ratio) 
{
	if (ratio < 0 || ratio > 1)
	{
		return;
	}
	else
	{
		if (m_bFileOpen == TRUE)
		{
			// 计算文件大小
			m_FileInfo.curFilePos = ULONGLONG(m_FileInfo.FileTotalLen * ratio);
			m_ReplayFile.Seek(LONGLONG(m_FileInfo.curFilePos), CFile::begin);
		}
	}
}

// 拖动滑动条响应函数
LRESULT CShowReplayDlg::OnBitmapSliderMoving(WPARAM wParam, LPARAM lParam)
{
	if (m_bPauseSliderReflect == FALSE)
	{
		// 滑动条暂停响应
		m_bPauseSliderReflect = TRUE;
		// 确定当前读取文件位置
		int pos = m_SliderReplayRatio.GetPos();
		int rangeMax = m_SliderReplayRatio.GetRangeMax();
		double ratio = pos * 1.0 / rangeMax;
		SetFileReplayRatio(ratio);
		// 滑动条开始响应
		m_bPauseSliderReflect = FALSE;
	}
	return 0;
}

// 停止播放
void CShowReplayDlg::OnBnClickedBtnFilestop()
{
	if (g_bWorkMode == true)
	{
		StopTimer();

		// 读取图像缓存清零
		if (m_bFileOpen == TRUE)
		{
			m_ReplayFile.Close();
			m_bFileOpen = FALSE;
			m_FileInfo.ClearStru();
		}

		m_bIsPlay = FALSE;

		Sleep(20);

		// 播放进度条复位
		m_SliderReplayRatio.SetPos(0);

		// 播放比率置零
		GetDlgItem(IDC_STATIC_REPLAY_RATIO)->SetWindowText(_T("0%"));
		//GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->SetWindowTextA("播放");
		m_Btn_PlayPause.SetIcon(IDI_ICON_PLAY);

	//	::PostMessage(g_mainDlgHwnd, WM_SHOW_STOP, 0, 0);
	}
}

// 减速——通过设定每帧字节的大小来控制播放的快慢
void CShowReplayDlg::OnBnClickedBtnFileslow()
{
	if(m_bFileOpen == TRUE && m_bIsPlay == TRUE)
	{
		if ((m_FileInfo.FrameLen - 1024) >= g_MinReadLen)
		{
			m_FileInfo.FrameLen = m_FileInfo.FrameLen - 1024;
		}
		else
		{
			m_FileInfo.FrameLen = g_MinReadLen;
		}
	}
}

// 加速——通过设定每帧字节的大小来控制播放的快慢
void CShowReplayDlg::OnBnClickedBtnFilefast()
{
	if(m_bFileOpen == TRUE && m_bIsPlay == TRUE)
	{
		if (m_FileInfo.FrameLen + 1024 <= g_MaxReadLen)
		{
			m_FileInfo.FrameLen = m_FileInfo.FrameLen + 1024;
		}
		else
		{
			m_FileInfo.FrameLen = g_MaxReadLen;
		}
	}
}


void CShowReplayDlg::OnCbnSelchangeComboxPlaytype()
{
	int state = ((CComboBox*)GetDlgItem(IDC_COMBOX_PLAYTYPE))->GetCurSel(); 
	// 视频回放功能
	if (state == 0)
	{
		g_bWorkMode = true; // 回放

		GetDlgItem(IDC_BTN_OPENFILE)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_FILESTOP)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_FILESLOW)->EnableWindow(TRUE);
		GetDlgItem(IDC_BTN_FILEFAST)->EnableWindow(TRUE);
	}

	// 实时接收数据显示功能
	else
	{
		// 停止文件回放
		OnBnClickedBtnFilestop(); 

		GetDlgItem(IDC_BTN_OPENFILE)->EnableWindow(FALSE);
		GetDlgItem(IDC_BTN_FILEPLAYPAUSE)->EnableWindow(FALSE);
		GetDlgItem(IDC_BTN_FILESTOP)->EnableWindow(FALSE);
		GetDlgItem(IDC_BTN_FILESLOW)->EnableWindow(FALSE);
		GetDlgItem(IDC_BTN_FILEFAST)->EnableWindow(FALSE);

		g_bWorkMode = false; // 实时
	}
}
void CShowReplayDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// 停止文件回放
	OnBnClickedBtnFilestop(); 
}

// 判断进程是否正在运行函数 返回0说明没有运行
DWORD CShowReplayDlg::GetProcessIdFromName(LPCTSTR name)
{
	PROCESSENTRY32 pe;
	DWORD id = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	pe.dwSize = sizeof(PROCESSENTRY32);
	if( !Process32First(hSnapshot,&pe) )
		return 0;
	while(1)
	{
		pe.dwSize = sizeof(PROCESSENTRY32);
		if( Process32Next(hSnapshot,&pe)==FALSE )
			break;
		if(strcmp(pe.szExeFile,name) == 0)
		{
			id = pe.th32ProcessID;
			break;
		}
	}
	CloseHandle(hSnapshot);
	return id;
}


LRESULT CShowReplayDlg::ReturnPayloadTypeWarning(WPARAM wParam, LPARAM lParam)
{
	UpdateData(FALSE);
	return 0;
}