// playDlg.cpp : 実装ファイル
//

#include "stdafx.h"
#include "play.h"
#include "playDlg.h"

#include <locale.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CplayDlg ダイアログ

#define PLAY_INI_FILE	_T(".\\play.ini")
#define CAPSTS_INI_FILE	_T(".\\cap_sts_sea.ini")

BOOL no_prompt;

#if 1
#define Wcscpy_s(d,n,s) wcsncpy_s((d),-1,(s),(n)-1)
#define Wcscat_s(d,n,s) wcsncat_s((d),-1,(s),(n)-1)
#define Wcsncpy_s(d,m,s,n) wcsncpy_s((d),-1,(s),((n)>=(m))?(m)-1:(n))
#else
#define Wcscpy_s wcscpy_s
#define Wcscat_s wcscat_s
#define Wcsncpy_s wcsncpy_s
#endif

CplayDlg::CplayDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CplayDlg::IDD, pParent)
	, m_filename(_T(""))
	, m_vlcparam(_T(""))
	, m_time(_T(""))
	, m_no_prompt(FALSE)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CplayDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_ChList);
	DDX_Text(pDX, IDC_EDIT1, m_filename);
	DDX_Text(pDX, IDC_EDIT3, m_time);
	DDX_Control(pDX, IDC_BUTTON1, m_view_button);
	DDX_Check(pDX, IDC_CHECK1, m_no_prompt);
	DDX_Control(pDX, IDC_COMBO1, m_ComboEncode);
}

BEGIN_MESSAGE_MAP(CplayDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_LBN_SELCHANGE(IDC_LIST1, &CplayDlg::OnLbnSelchangeList1)
	ON_BN_CLICKED(IDC_BUTTON1, &CplayDlg::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CplayDlg::OnBnClickedButton2)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_BUTTON3, &CplayDlg::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON5, &CplayDlg::OnBnClickedButton5)
	ON_BN_CLICKED(IDC_BUTTON4, &CplayDlg::OnBnClickedButton4)
	ON_LBN_DBLCLK(IDC_LIST1, &CplayDlg::OnLbnDblclkList1)
	ON_CBN_CLOSEUP(IDC_COMBOENCODE, &CplayDlg::OnCbnCloseupComboencode)
END_MESSAGE_MAP()


// CplayDlg メッセージ ハンドラ

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

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	// TODO: 初期化をここに追加します。

	m_hThread = NULL;
	m_sel_ch = -1;

	LoadChannelFile();


	wchar_t buff[1024];
	GetPrivateProfileString(L"PLAY_SETTING",L"VLC_PARAM",L"",buff,sizeof(buff),PLAY_INI_FILE);
	m_vlcparam = buff;
	GetPrivateProfileString(L"PLAY_SETTING",L"TIME",L"30",buff,sizeof(buff),PLAY_INI_FILE);
	m_time = buff;
	GetPrivateProfileString(L"PLAY_SETTING",L"FILENAME",L"test.ts2",buff,sizeof(buff),PLAY_INI_FILE);
	m_filename = buff;
	GetPrivateProfileString(L"PLAY_SETTING",L"ENCODE",L"",buff,sizeof(buff),PLAY_INI_FILE);
	m_vlcparam = buff;

	m_no_prompt = GetPrivateProfileInt(L"PLAY_SETTING",L"NO_PROMPT",0,PLAY_INI_FILE) ? true : false;
	no_prompt = m_no_prompt;
	UpdateData(FALSE);


	PowerOn();

    CRect  rcWindow;
    rcWindow.left   = GetPrivateProfileInt( L"PLAY_SETTING", L"left", 0 ,PLAY_INI_FILE);
    rcWindow.top   = GetPrivateProfileInt( L"PLAY_SETTING", L"top", 0 ,PLAY_INI_FILE);
    rcWindow.right   = GetPrivateProfileInt( L"PLAY_SETTING", L"right", 0 ,PLAY_INI_FILE);
    rcWindow.bottom   = GetPrivateProfileInt( L"PLAY_SETTING", L"bottom", 0 ,PLAY_INI_FILE);
    //  ウィンドウ位置修正
	if(rcWindow.right)
		MoveWindow( rcWindow );

	OpenSeaIni();
	m_ComboEncode.SetCurSel(m_ComboEncode.FindString(0,(LPCTSTR)m_vlcparam));

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

bool CplayDlg::OpenSeaIni(void)
{
	FILE	*fp;
	CString pg;
	wchar_t buffer[WCHAR_MAX];
	errno_t err;

	m_ComboEncode.Clear();

	m_ComboEncode.InsertString(-1,L"無効(TS保存)");

	err = _wfopen_s(&fp, L"cap_sts_sea.ini" , L"rt");	//読み込み専用、テキストモード

	if(err) return false;

	for(;;){
		if(fgetws(buffer, WCHAR_MAX, fp) == NULL){	//一行読み込み(S-JIS -> Unicode自動変換)
			// 中身がない
			fclose(fp);
			break;
		}
		if(wcsstr(buffer, L"[VLC_SETTING]") == buffer){
			pg = L"vlc:";
			continue;
		} else if(wcsstr(buffer, L"[FFMPEG_SETTING]") == buffer){
			pg = L"ffmpeg:";
			continue;
		} else if(wcsstr(buffer, L"[") == buffer){
			pg = "";
		} else if(wcsstr(buffer, L";")){
			continue;
		} else if(wcsstr(buffer, L"PATH")){
			continue;
		}

		if(pg != ""){
			wchar_t* arg;
			arg = wcsstr(buffer, L"=");
			if(arg == NULL) continue;
			*arg=NULL;
			CString buf = pg;
			buf+=buffer;
			buf.Trim();
			m_ComboEncode.AddString(buf);
		}
	}
	fclose(fp);
	return true;
}

// ダイアログに最小化ボタンを追加する場合、アイコンを描画するための
//  下のコードが必要です。ドキュメント/ビュー モデルを使う MFC アプリケーションの場合、
//  これは、Framework によって自動的に設定されます。

void CplayDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 描画のデバイス コンテキスト

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// クライアントの四角形領域内の中央
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// アイコンの描画
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// ユーザーが最小化したウィンドウをドラッグしているときに表示するカーソルを取得するために、
//  システムがこの関数を呼び出します。
HCURSOR CplayDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CplayDlg::OnLbnSelchangeList1()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	m_sel_ch = m_ChList.GetCurSel();
}

void CplayDlg::LoadChannelFile(void)
{
	FILE	*fp;
	wchar_t buffer[WCHAR_MAX];

	_wsetlocale(LC_CTYPE, L"Japanese");					//ロケーションセット

	channel_number = 0;
	memset(channel, '\0', sizeof(channel));

	wchar_t file[256];
	wchar_t *lastbackslash;
	GetModuleFileNameW(NULL,file,256);
	lastbackslash = wcsrchr(file, '\\');
	Wcscpy_s(lastbackslash, 256 - (lastbackslash - &file[0]), L"\\channel.txt");

	_wfopen_s(&fp, file, L"r+t");	//読み込み専用、テキストモード
	if(fp == NULL){
		return;
	}
	wchar_t *f, *n;
	while(true){
		if(fgetws(buffer, WCHAR_MAX, fp) == NULL) break;
		if(buffer[0] == L'\n') goto SKIP;
		if((buffer[0] == L'/')&&(buffer[1] == L'/')) goto SKIP;

		f = wcschr(&buffer[0], ',');
		Wcsncpy_s(channel[channel_number].name, 32, &buffer[0], f - &buffer[0]);
		m_ChList.InsertString(channel_number,channel[channel_number].name);
		f++;
		n = wcschr(f, ',');
		Wcsncpy_s(channel[channel_number].command, 10, f, n - f);
		n++;
		Wcscpy_s(channel[channel_number].IdentificationWord, 128, n);
		channel_number++;

		SKIP:
		;
	}
	fclose(fp);


}


DWORD WINAPI func(LPVOID lpArg) 
{

	PROCESS_INFORMATION pi;
	STARTUPINFO si;

	ZeroMemory(&si,sizeof(si));
	si.cb=sizeof(si);

	CreateProcess(NULL,(LPTSTR)lpArg,NULL,NULL,FALSE,no_prompt ? DETACHED_PROCESS : 0,
		NULL,NULL,&si,&pi);

	CloseHandle(pi.hThread);

	WaitForSingleObject(pi.hProcess,INFINITE);

	CloseHandle(pi.hProcess);

	ExitThread(0);

	return 0;

}


bool CplayDlg::OpenCommandBlock(LPTSTR vlc)
{
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	// VLCの起動。
	::ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb           = sizeof(STARTUPINFO);
	si.dwFlags      = STARTF_USESHOWWINDOW;
	si.wShowWindow  = SW_SHOWNORMAL;
	CreateProcess(NULL, vlc, NULL, NULL, TRUE, no_prompt ? DETACHED_PROCESS : 0, NULL, NULL, &si, &pi);

	CloseHandle(pi.hThread);

	WaitForSingleObject(pi.hProcess,INFINITE);

	CloseHandle(pi.hProcess);

	return TRUE;
}


bool CplayDlg::OpenCommandNoBlock(LPTSTR vlc)
{
	DWORD dwThreadId;
	
	m_hThread = CreateThread(NULL,0,func,vlc,0,&dwThreadId); 

	return TRUE;
}



void CplayDlg::OnBnClickedButton1()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	wchar_t buffer[WCHAR_MAX];
	CString str;
	UpdateData(TRUE);
	no_prompt = m_no_prompt;

	if(m_hThread){
//		wcscpy_s(buffer,WCHAR_MAX,L"cap_sts.exe stop");
//		OpenCommandBlock(buffer);
//		WaitForSingleObject(m_hThread,3000);
//		m_hThread = 0;
		
		str = "cap_sts.exe ch:@";
		str += channel[m_sel_ch].command;

		wcscpy_s(buffer,WCHAR_MAX,str);

		no_prompt = TRUE;

		OpenCommandNoBlock(buffer);

		return;
	} else {

		if(m_sel_ch != -1){
			str = "cap_sts.exe view sel noeits 120 @";
			str += channel[m_sel_ch].command;
		} else {
			str = "cap_sts.exe view sel noeits 120 B";
		}
	}
	m_view_button.SetWindowTextW((LPCTSTR)L"ch切り替え");

	wcscpy_s(buffer,WCHAR_MAX,str);

	no_prompt = m_no_prompt;

	OpenCommandNoBlock(buffer);
}

void CplayDlg::OnBnClickedButton2()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。

	wchar_t buffer[WCHAR_MAX];
	UpdateData(TRUE);
	no_prompt = m_no_prompt;


	if(m_hThread){
		no_prompt = TRUE;

		wcscpy_s(buffer,WCHAR_MAX,L"cap_sts.exe stop");
		OpenCommandBlock(buffer);
		WaitForSingleObject(m_hThread,3000);
		m_hThread = 0;
		m_view_button.SetWindowTextW((LPCTSTR)L"視聴");

	}
}

void CplayDlg::PowerOn()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。

	wchar_t buffer[WCHAR_MAX];

	if(m_hThread == 0){
		no_prompt = TRUE;

		wcscpy_s(buffer,WCHAR_MAX,L"cap_sts.exe stop fpon");
		OpenCommandBlock(buffer);
		WaitForSingleObject(m_hThread,3000);
	}
}

void CplayDlg::PowerOff()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。

	wchar_t buffer[WCHAR_MAX];

	no_prompt = TRUE;
	wcscpy_s(buffer,WCHAR_MAX,L"cap_sts.exe stop fpoff");
	OpenCommandBlock(buffer);
	WaitForSingleObject(m_hThread,3000);
}

void CplayDlg::OnClose()
{
	// TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。
	PowerOff();

	UpdateData(TRUE);
	no_prompt = m_no_prompt;

	WritePrivateProfileString(L"PLAY_SETTING",L"VLC_PARAM",m_vlcparam,PLAY_INI_FILE);
	WritePrivateProfileString(L"PLAY_SETTING",L"TIME",m_time,PLAY_INI_FILE);
	WritePrivateProfileString(L"PLAY_SETTING",L"FILENAME",m_filename,PLAY_INI_FILE);
	WritePrivateProfileString(L"PLAY_SETTING",L"NO_PROMPT",m_no_prompt ? L"1" : L"0" ,PLAY_INI_FILE);
	WritePrivateProfileString(L"PLAY_SETTING",L"ENCODE",m_vlcparam ,PLAY_INI_FILE);
    WINDOWPLACEMENT  wndpl;
    //  ウィンドウ位置を取得
    GetWindowPlacement( &wndpl );
    //  レジストリに保存
	wchar_t buffer[WCHAR_MAX];
	wsprintf(buffer,L"%d",wndpl.rcNormalPosition.left);
    WritePrivateProfileString( L"PLAY_SETTING", L"left",   buffer ,PLAY_INI_FILE);
	wsprintf(buffer,L"%d",wndpl.rcNormalPosition.top);
    WritePrivateProfileString( L"PLAY_SETTING", L"top",   buffer ,PLAY_INI_FILE);
	wsprintf(buffer,L"%d",wndpl.rcNormalPosition.right);
    WritePrivateProfileString( L"PLAY_SETTING", L"right",   buffer ,PLAY_INI_FILE);
	wsprintf(buffer,L"%d",wndpl.rcNormalPosition.bottom);
    WritePrivateProfileString( L"PLAY_SETTING", L"bottom",   buffer ,PLAY_INI_FILE);

	CDialog::OnClose();
}

BOOL FileExist(
LPCTSTR lpszFileName)
{
	return GetFileAttributes(lpszFileName) != 0xFFFFFFFF;
}

void CplayDlg::OnBnClickedButton3()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。

	// 今すぐ録画
	wchar_t buffer[WCHAR_MAX];

	UpdateData(TRUE);
	no_prompt = m_no_prompt;

	if(FileExist(m_filename)){
		if(MessageBox(L"ファイルが存在します。上書きしますか？",L"確認",MB_OKCANCEL|MB_ICONQUESTION|MB_TOPMOST) != IDOK){
			return;
		}
	}

	if(m_hThread){
		wcscpy_s(buffer,WCHAR_MAX,L"cap_sts.exe stop");
		no_prompt = TRUE;
		OpenCommandBlock(buffer);
		WaitForSingleObject(m_hThread,3000);
		m_hThread = 0;
		m_view_button.SetWindowTextW((LPCTSTR)L"視聴");
	}
	CString str;

	if(m_sel_ch != -1){
		str = "cap_sts.exe B noeits fn @";
		str += channel[m_sel_ch].command;
	} else {
		str = "cap_sts.exe fn noeits B";
	}
	if(m_time != ""){
		str += " ";
		str += m_time;
	} else {
		str += " 30";
	}
	if(m_vlcparam != "" && m_vlcparam != "無効(TS保存)"){
		str += " ";
		str += m_vlcparam;
	}
	if(m_filename != ""){
		str += " ";
		str += m_filename;
	} else {
		str += " test.ts2";
	}

	wcscpy_s(buffer,WCHAR_MAX,str);
	no_prompt = m_no_prompt;

	OpenCommandNoBlock(buffer);
}

void CplayDlg::OnBnClickedButton5()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	// Addボタン
	CString str;
	wchar_t buffer[WCHAR_MAX];

	str = "cap_sts.exe ADD";

	if(m_time != ""){
		str += " ";
		str += m_time;
	} else {
		str += " 30";
	}

	wcscpy_s(buffer,WCHAR_MAX,str);

	OpenCommandNoBlock(buffer);
}

void CplayDlg::OnBnClickedButton4()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	// 追っかけ再生ボタン
	
	wchar_t buff[256];

	GetPrivateProfileString(L"VLC_SETTING",L"VLC_PATH",L"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe",buff,sizeof(buff),CAPSTS_INI_FILE);
	CString str;

	ShellExecute(NULL,NULL,buff,m_filename,NULL,SW_SHOWNORMAL);
}

void CplayDlg::OnLbnDblclkList1()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	OnBnClickedButton1();
}

void CplayDlg::OnCbnCloseupComboencode()
{
	// TODO: ここにコントロール通知ハンドラ コードを追加します。
	UpdateData(TRUE);
	if(m_ComboEncode.GetCurSel() >= 0){
		m_ComboEncode.GetLBText( m_ComboEncode.GetCurSel(),m_vlcparam );
	}
}
