// Sample11_FLVPlayerDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Sample11_FLVPlayer.h"
#include "Sample11_FLVPlayerDlg.h"
#include "URLDialog.h"

#include <locale.h>
#include <msxml2.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSample11_FLVPlayerDlg dialog

CSample11_FLVPlayerDlg::CSample11_FLVPlayerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSample11_FLVPlayerDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSample11_FLVPlayerDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSample11_FLVPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSample11_FLVPlayerDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSample11_FLVPlayerDlg, CDialog)
	//{{AFX_MSG_MAP(CSample11_FLVPlayerDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(ID_SITE, OnSite)
	ON_BN_CLICKED(ID_ORDER, OnOrder)
	ON_BN_CLICKED(IDC_CHECK_SHOW_CONTROLS, OnCheckShowControls)
	ON_BN_CLICKED(ID_PLAY, OnPlay)
	ON_BN_CLICKED(ID_PAUSE, OnPause)
	ON_BN_CLICKED(ID_PLAY_FLV, OnLoadFLV)
	ON_BN_CLICKED(ID_PLAY_FROM_FILE, OnPlayFromFile)
	ON_BN_CLICKED(ID_PLAY_FROM_URL, OnPlayFromURL)
	ON_BN_CLICKED(ID_PLAY_FROM_RTMP, OnPlayFromRTMP)
	ON_BN_CLICKED(ID_PLAY_EMBEDDED_FLV, OnPlayEmbedded)
	ON_BN_CLICKED(IDC_CHECK_ENABLE_SOUNDS, OnCheckEnableSounds)
	ON_WM_TIMER()
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSample11_FLVPlayerDlg message handlers

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

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	// FlashPlayerControl creating
	// NOTE: CALL FPC_LoadRegisteredOCX() or FPC_LoadOCXCodeFromMemory() before creating!
	// See InitInstance() implementation
	{
		RECT rc;
		GetDlgItem(IDC_STATIC_FPC_PLACE)->GetWindowRect(&rc);
		ScreenToClient(&rc);

		m_hwndFlashPlayerControl = 
			CreateWindow((LPCTSTR)FPC_GetClassAtom(theApp.m_hFPC), 
						 NULL, 
						 WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 
						 rc.left, 
						 rc.top, 
						 rc.right - rc.left, 
						 rc.bottom - rc.top, 
						 m_hWnd, 
						 NULL, 
						 NULL, 
						 NULL);
	}

	FPCPutMovieFromResource(m_hwndFlashPlayerControl, NULL, _T("FLVPLAYER"), _T("SWF"));

	FPC_AddOnLoadExternalResourceHandler(theApp.m_hFPC, &StaticGlobalOnLoadExternalResourceHandler, (LPARAM)this);

	FPC_EnableFullScreen(m_hwndFlashPlayerControl, TRUE);
	FPC_PutBackgroundColor(m_hwndFlashPlayerControl, 0x000000);

	CheckDlgButton(IDC_CHECK_SHOW_CONTROLS, TRUE);
	CheckDlgButton(IDC_CHECK_PLAY_AUTOMATICALLY, TRUE);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSample11_FLVPlayerDlg::OnCheckShowControls()
{
	BOOL bShowControls = IsDlgButtonChecked(IDC_CHECK_SHOW_CONTROLS);

	BSTR bstrRequest;
	
	if (bShowControls)
		bstrRequest = SysAllocString(L"<invoke name=\"showAllControl\" returntype=\"void\"><arguments></arguments></invoke>");
	else
		bstrRequest = SysAllocString(L"<invoke name=\"hideAllControl\" returntype=\"void\"><arguments></arguments></invoke>");

	BSTR bstrResponse = NULL;
	FPCCallFunctionBSTR(m_hwndFlashPlayerControl, bstrRequest, &bstrResponse);
	if (NULL != bstrResponse)
		SysFreeString(bstrResponse);
}

void CSample11_FLVPlayerDlg::OnPlay()
{
	BSTR bstrRequest = SysAllocString(L"<invoke name=\"resumeVideo\" returntype=\"void\"><arguments></arguments></invoke>");

	BSTR bstrResponse = NULL;
	
	FPCCallFunctionBSTR(m_hwndFlashPlayerControl, bstrRequest, &bstrResponse);
	
	if (NULL != bstrResponse)
		SysFreeString(bstrResponse);
}

void CSample11_FLVPlayerDlg::OnPause()
{
	BSTR bstrRequest = SysAllocString(L"<invoke name=\"pauseVideo\" returntype=\"void\"><arguments></arguments></invoke>");

	BSTR bstrResponse = NULL;
	
	FPCCallFunctionBSTR(m_hwndFlashPlayerControl, bstrRequest, &bstrResponse);
	
	if (NULL != bstrResponse)
		SysFreeString(bstrResponse);
}

void CSample11_FLVPlayerDlg::OnLoadFLV()
{
	CRect rc;
	GetDlgItem(ID_PLAY_FLV)->GetWindowRect(&rc);

	CMenu menu;
	menu.LoadMenu(IDR_MENU_FLV);
	menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN, rc.left, rc.bottom, this);
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSample11_FLVPlayerDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		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;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSample11_FLVPlayerDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

HRESULT WINAPI CSample11_FLVPlayerDlg::GlobalOnLoadExternalResourceHandler(LPCTSTR lpszURL, IStream** ppStream, HFPC hFPC)
{
	HRESULT hr = E_FAIL;

	if (0 == lstrcmpi(lpszURL, _T("http://FLV/FlashVideo.flv")))
	{
		// Save flash video to the stream from the resource
		HMODULE hModule = GetModuleHandle(NULL);
		HRSRC hResInfo = FindResource(hModule, _T("EMBEDDED_FLV"), _T("FLV"));
		HGLOBAL hResData = LoadResource(hModule, hResInfo);
		LPCVOID lpData = LockResource(hResData);
		DWORD dwSize = SizeofResource(hModule, hResInfo);

		ULONG nWritten;
		(*ppStream)->Write(lpData, dwSize, &nWritten);

		hr = S_OK;
	}

	return hr;
}

void CSample11_FLVPlayerDlg::PostNcDestroy() 
{
	CDialog::PostNcDestroy();

	FPC_RemoveOnLoadExternalResourceHandler(theApp.m_hFPC, m_dwHandlerCookie);
}

void CSample11_FLVPlayerDlg::OnSite() 
{
	ShellExecute(m_hWnd, NULL, _T("http://www.f-in-box.com/dll/"), NULL, NULL, SW_SHOW);
}

void CSample11_FLVPlayerDlg::OnOrder() 
{
	ShellExecute(m_hWnd, NULL, _T("http://www.f-in-box.com/dll/order.html"), NULL, NULL, SW_SHOW);
}

void CSample11_FLVPlayerDlg::OnPlayFromFile()
{
    CFileDialog dlg(TRUE, 
                    _T("flv"), 
                    _T(""), 
                    0, 
                    _T("Flash Video Files (*.flv)|*.flv|All Files (*.*)|*.*||"), 
                    this);

    if (IDOK == dlg.DoModal())
    {
        //
        CString strFlashMoviePath = dlg.GetPathName();

		BOOL bPlayAutomatically = IsDlgButtonChecked(IDC_CHECK_PLAY_AUTOMATICALLY);

		// Prepare parameters
		CString strFlashVars =
			_T("type_video=flv&url=") + 
			strFlashMoviePath + 
			_T("&auto_play=") + 
			(bPlayAutomatically ? _T("true") : _T("false"));

		// Set parameters
		FPC_PutFlashVars(m_hwndFlashPlayerControl, strFlashVars);
		// Load player form resources
		FPCPutMovieFromResource(m_hwndFlashPlayerControl, NULL, _T("FLVPLAYER"), _T("SWF"));
	}
}

void CSample11_FLVPlayerDlg::OnPlayFromURL()
{
    CURLDialog dlg;

    if (IDOK == dlg.DoModal())
    {
        //
        CString strFlashMovieURL = dlg.GetURL();

		BOOL bPlayAutomatically = IsDlgButtonChecked(IDC_CHECK_PLAY_AUTOMATICALLY);

		// Prepare parameters: type_video=flv !
		CString strFlashVars =
			_T("type_video=flv&url=") + 
			strFlashMovieURL + 
			_T("&auto_play=") + 
			(bPlayAutomatically ? _T("true") : _T("false"));

		// Set parameters
		FPC_PutFlashVars(m_hwndFlashPlayerControl, strFlashVars);
		// Load player form resources
		FPCPutMovieFromResource(m_hwndFlashPlayerControl, NULL, _T("FLVPLAYER"), _T("SWF"));
	}
}

void CSample11_FLVPlayerDlg::OnPlayFromRTMP()
{
    CURLDialog dlg;

    if (IDOK == dlg.DoModal())
    {
        //
        CString strFlashMovieURL = dlg.GetURL();

		BOOL bPlayAutomatically = IsDlgButtonChecked(IDC_CHECK_PLAY_AUTOMATICALLY);

		// Prepare parameters: type_video=rtmp !
		CString strFlashVars =
			_T("type_video=rtmp&url=") + 
			strFlashMovieURL + 
			_T("&auto_play=") + 
			(bPlayAutomatically ? _T("true") : _T("false"));

		// Set parameters
		FPC_PutFlashVars(m_hwndFlashPlayerControl, strFlashVars);
		// Load player form resources
		FPCPutMovieFromResource(m_hwndFlashPlayerControl, NULL, _T("FLVPLAYER"), _T("SWF"));
	}
}

void CSample11_FLVPlayerDlg::OnPlayEmbedded()
{
	BOOL bPlayAutomatically = IsDlgButtonChecked(IDC_CHECK_PLAY_AUTOMATICALLY);

	// Prepare parameters
	CString strFlashVars = _T("type_video=flv&url=http://FLV/FlashVideo.flv&auto_play=");
	strFlashVars += bPlayAutomatically ? _T("true") : _T("false");

	// Set parameters
	FPC_PutFlashVars(m_hwndFlashPlayerControl, strFlashVars);
	// Load player form resources
	FPCPutMovieFromResource(m_hwndFlashPlayerControl, NULL, _T("FLVPLAYER"), _T("SWF"));

	// CSample11_FLVPlayerDlg::GlobalOnLoadExternalResourceHandler will be called, 
	// we've added this handler (see FPC_AddOnLoadExternalResourceHandler within CSample11_FLVPlayerDlg::OnInitDialog)
}

LRESULT CSample11_FLVPlayerDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	LPNMHDR lpNMHDR = (LPNMHDR)lParam;

	if (WM_NOTIFY == message)
		if (m_hwndFlashPlayerControl == lpNMHDR->hwndFrom)
			switch (lpNMHDR->code)
			{
				case FPCN_FLASHCALL:
				{
					SFPCFlashCallInfoStruct* pInfo = (SFPCFlashCallInfoStruct*)lParam;

					CComPtr<IXMLDOMDocument> pDoc;
                    pDoc.CoCreateInstance(L"Msxml2.DOMDocument");

                    VARIANT_BOOL bSuccessful;
					pDoc->loadXML(CComBSTR(pInfo->request), &bSuccessful);

                    CComPtr<IXMLDOMElement> pDocumentElement;
                    pDoc->get_documentElement(&pDocumentElement);

                    CComPtr<IXMLDOMNamedNodeMap> pDocumentElementAttrs;
                    pDocumentElement->get_attributes(&pDocumentElementAttrs);

                    CComPtr<IXMLDOMNode> pNameNode;
                    pDocumentElementAttrs->getNamedItem(CComBSTR(L"name"), &pNameNode);

                    CComBSTR bstrRequestName;
                    pNameNode->get_text(&bstrRequestName);

					CString strRequestName = (LPCTSTR)bstrRequestName;

					if (strRequestName == _T("onMetaData"))
					{
						BSTR bstrResponse = NULL;

						FPCCallFunctionBSTR(
							m_hwndFlashPlayerControl, 
							CComBSTR(L"<invoke name=\"getDuration\" returntype=\"xml\"><arguments></arguments></invoke>"), 
							&bstrResponse);

						if (NULL != bstrResponse)
						{
                            VARIANT_BOOL bSuccessful;
							pDoc->loadXML(bstrResponse, &bSuccessful);

							char decimal_point = localeconv()->decimal_point[0];
							localeconv()->decimal_point[0] = '.';

                            CComPtr<IXMLDOMElement> pDocumentElement;
                            pDoc->get_documentElement(&pDocumentElement);

                            CComBSTR bstrDuration;
                            pDocumentElement->get_text(&bstrDuration);

							CString strDuration = (LPCTSTR)bstrDuration;

							float fDuration;
							_stscanf(strDuration, _T("%f"), &fDuration);

							localeconv()->decimal_point[0] = decimal_point;

							SysFreeString(bstrResponse);

							CSliderCtrl* pSliderCtrl = (CSliderCtrl*)GetDlgItem(IDC_SLIDER_POSITION);

							pSliderCtrl->SetRange(0, (int)fDuration);

							m_nTimerUpdatePos = SetTimer(1, 500, NULL);

							CString str;
							str.Format(_T("Total length: %d seconds (or %d ms)"), (int)fDuration, (int)(100 * fDuration));
							SetDlgItemText(IDC_STATIC_INFO, str);							
						}
					}

					return 1;
				}
			}
	
	return CDialog::WindowProc(message, wParam, lParam);
}

void CSample11_FLVPlayerDlg::OnTimer(UINT_PTR nIDEvent) 
{
	if (nIDEvent == m_nTimerUpdatePos)
	{
		BSTR bstrResponse = NULL;

		FPCCallFunctionBSTR(
			m_hwndFlashPlayerControl, 
            CComBSTR(L"<invoke name=\"getCurrPosition\" returntype=\"xml\"><arguments></arguments></invoke>"), 
			&bstrResponse);

		if (NULL != bstrResponse)
		{
			CComPtr<IXMLDOMDocument> pDoc;
            pDoc.CoCreateInstance(L"Msxml2.DOMDocument");

            VARIANT_BOOL bSuccessful;
			pDoc->loadXML(bstrResponse, &bSuccessful);

			char decimal_point = localeconv()->decimal_point[0];
			localeconv()->decimal_point[0] = '.';

            CComPtr<IXMLDOMElement> pDocumentElement;
            pDoc->get_documentElement(&pDocumentElement);

            CComBSTR bstrCurrentPosition;
            pDocumentElement->get_text(&bstrCurrentPosition);

			CString strCurrentPosition = (LPCTSTR)bstrCurrentPosition;

			float fCurrentPosition;
			_stscanf(strCurrentPosition, _T("%f"), &fCurrentPosition);

			localeconv()->decimal_point[0] = decimal_point;

			SysFreeString(bstrResponse);

			CSliderCtrl* pSliderCtrl = (CSliderCtrl*)GetDlgItem(IDC_SLIDER_POSITION);

			pSliderCtrl->SetPos((int)fCurrentPosition);

			CString str;
			str.Format(_T("%d seconds (or %d ms)"), (int)fCurrentPosition, (int)(100 * fCurrentPosition));
			SetDlgItemText(IDC_STATIC_POS, str);
		}
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CSample11_FLVPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	if (pScrollBar->GetDlgCtrlID() == IDC_SLIDER_SOUND_VOLUME)
	{
		CSliderCtrl* pSliderCtrl = (CSliderCtrl*)GetDlgItem(IDC_SLIDER_SOUND_VOLUME);
		int nVolume = pSliderCtrl->GetPos();

		BSTR bstrResponse = NULL;

		CString strRequest;
		strRequest.Format(_T("<invoke name=\"setVolume\" returntype=\"xml\"><arguments><number>%d</number></arguments></invoke>"), nVolume);

        FPCCallFunctionBSTR(m_hwndFlashPlayerControl, CComBSTR((LPCTSTR)strRequest), &bstrResponse);

		if (NULL != bstrResponse)
			SysFreeString(bstrResponse);
	}
	
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CSample11_FLVPlayerDlg::OnCheckEnableSounds()
{
	BOOL bEnableSounds = IsDlgButtonChecked(IDC_CHECK_ENABLE_SOUNDS);

	BSTR bstrResponse = NULL;

	CString strRequest;
	strRequest.Format(_T("<invoke name=\"setMute\" returntype=\"xml\"><arguments><%s /></arguments></invoke>"), bEnableSounds ? _T("true") : _T("false"));

	FPCCallFunctionBSTR(m_hwndFlashPlayerControl, CComBSTR((LPCTSTR)strRequest), &bstrResponse);

	if (NULL != bstrResponse)
		SysFreeString(bstrResponse);
}
