// Copyright (c) 1998-2005 B2C2, Incorporated.  All Rights Reserved.
//
// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF B2C2, INCORPORATED.
// The copyright notice above does not evidence any
// actual or intended publication of such source code.
//
// This file is proprietary source code of B2C2, Incorporated. and is released pursuant to and
// subject to the restrictions of the non-disclosure agreement and license contract entered
// into by the parties.
//
//
// AVPlaybackDlg.cpp : implementation file
//

#include "stdafx.h"
#include "SDKDemo.h"
#include "AVPlaybackDlg.h"

#include "AVPlaybackCtrl.h"
#include "B2FilterGraphHandler.h"
#include ".\avplaybackdlg.h"
#include "AboutDlg.h"

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

#define RECT2POS(cr) cr.left, cr.top, cr.Width(), cr.Height()

// Status Bar Panels
enum {
	SBP_PLAY = 0,
	SBP_RECORD,
	SBP_MAX,		// Must be last
};

// TEMPORARY

extern E_PVR_CALLBACK_STATE g_ePvrStateChange;

///////////////////////////////////////////////////////////////////////////////
// CAVPlaybackDlg dialog

CAVPlaybackDlg::CAVPlaybackDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAVPlaybackDlg::IDD, pParent)
	, m_nSliderPosition(0)
{
	//{{AFX_DATA_INIT(CAVPlaybackDlg)
		// 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);

	m_pAVPlaybackCtrl = new CAVPlaybackCtrl;
	ASSERT( m_pAVPlaybackCtrl);
	if (!m_pAVPlaybackCtrl)
	{
		AfxThrowMemoryException();
	}

	//
	m_nStatusTimer = 0;

	m_bScrollBarRepositioning = FALSE;

}


// virtual ////////////////////////////////////////////////////////////////////
CAVPlaybackDlg::~CAVPlaybackDlg()
{
	if (m_pAVPlaybackCtrl)
	{
		delete m_pAVPlaybackCtrl;
		m_pAVPlaybackCtrl = NULL;
	}
}

void CAVPlaybackDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAVPlaybackDlg)
	// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_SLIDER1, m_cSliderCtrl);
	DDX_Slider(pDX, IDC_SLIDER1, m_nSliderPosition);
}

BEGIN_MESSAGE_MAP(CAVPlaybackDlg, CDialog)
	//{{AFX_MSG_MAP(CAVPlaybackDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_DESTROY()
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_BT_PLAY, OnBtPlay)
	ON_BN_CLICKED(IDC_BT_STOP, OnBtStop)
	ON_BN_CLICKED(IDC_BT_RECORD, OnBtRecord)
	ON_WM_SIZE()
	ON_WM_SIZING()
	ON_WM_TIMER()
	ON_WM_ACTIVATE()
	ON_BN_CLICKED(IDC_BT_JUMP_TO_START, OnBnClickedBtJumpToStart)
	ON_BN_CLICKED(IDC_BT_JUMP_TO_END, OnBnClickedBtJumpToEnd)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*-----------------------------------------------------------------------------------------------*/

// CAVPlaybackDlg message handlers

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

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	
	// Initialize main class
	ASSERT( m_pAVPlaybackCtrl);

	m_pAVPlaybackCtrl->PassB2FilterGraphHandler(m_pB2FilterGraph);
	m_pAVPlaybackCtrl->PassAudioVideoPID(m_iAudioPID,m_iVideoPID);
	m_pAVPlaybackCtrl->PassAutoDeleteTimeshift(m_bAutoDeleteTimeshift);
	m_pAVPlaybackCtrl->PassAutoStartTimeshift(m_bAutoStartTimeshift);

	m_pAVPlaybackCtrl->Initialize(GetDlgItem( IDC_ST_VIDEO_WND)->GetSafeHwnd());

	// Create the status bar and get the size
	VERIFY( m_cStatusBar.Create( WS_CHILD|WS_VISIBLE|CCS_BOTTOM|SBARS_SIZEGRIP, 
									 CRect(0,0,0,0), this, IDC_STATUS_BAR));


	m_cStatusBar.GetWindowRect( m_crStatusBar);
	m_iStatusBarHeight = m_crStatusBar.Height();

	int aiPartDim[]= {m_crStatusBar.Width() / 2, -1};
	int iParts = sizeof (aiPartDim) / sizeof (aiPartDim[0]);

	m_cStatusBar.SetParts( iParts, aiPartDim);


	m_cSliderCtrl.GetWindowRect( m_crSliderCtrl);
	m_iSliderCtrlHeight = m_crSliderCtrl.Height();


	// Devide parts

	//
	// Window Size
	//
	m_dfRatio = 9.0 / 16.0;
	m_dfRatio = 3.0 / 4.0;

	m_bLockRatio = TRUE;

	m_crVidFrame.left = 0;
	m_crVidFrame.top = 0;
	m_crVidFrame.right = 0;
	m_crVidFrame.bottom = 0;

	m_cpVidSize.x = 544;
	m_cpVidSize.y = 480;

	CalcVideoWindowSize(FALSE, TRUE);

	CalcMainWindow();

	// Update Windows
	UpdateMainWindow();
	UpdateVideoWindow();
	UpdateButtons();
	UpdateStatusBar();

	UpdateState();

	StartStatusTimer();

	OnBtPlay();

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

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;

		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

/*-----------------------------------------------------------------------------------------------*/

// 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 CAVPlaybackDlg::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();

		UpdateVideoWindow();
	}
}

/*-----------------------------------------------------------------------------------------------*/

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

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnDestroy() 
{
	StopStatusTimer();

	OnBtStop();

	m_pB2FilterGraph->ReleaseVideoWindow();

	CDialog::OnDestroy();
	
	// TODO: Add your message handler code here
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnSizing(UINT nSide, LPRECT pRect) 
{

	// Calculate frame parameter
	CPoint cpChild(pRect->right - pRect->left, pRect->bottom - pRect->top);

	// Get Changes
	int nXDiff = pRect->right - pRect->left - m_crMainWnd.Width();
	int nYDiff = pRect->bottom - pRect->top - m_crMainWnd.Height();

	CRect crCurWnd;
	GetWindowRect( crCurWnd);

	// Validate minimum size
	int nMinX = 310;

	if (   pRect->right - pRect->left <= nMinX
		&& nXDiff <= 0 
		&& nYDiff <= 0)
	{
		// Apply size limits
		pRect->left   = crCurWnd.left  ;
		pRect->right  = crCurWnd.right ;
		pRect->top    = crCurWnd.top   ;
		pRect->bottom = crCurWnd.bottom;

		nXDiff = 0; 
		nYDiff = 0;
	}

	//TRACE( "OnSizing(%d,%d,%d,%d,%d - %d,%d)\n", nSide, pRect->left, pRect->top, pRect->right, pRect->bottom, nXDiff ,nYDiff);

	if( nXDiff || nYDiff)
	{
		// Store current size
		CPoint cpCurVid(m_cpVidSize);

		// Apply changes
		m_cpVidSize.x += nXDiff; 
		m_cpVidSize.y += nYDiff; 

		BOOL bModifyY;

		switch (nSide)
		{
		case WMSZ_LEFT :		// Left edge 
		case WMSZ_RIGHT :		// Right edge 
			bModifyY = TRUE;
			break;
		case WMSZ_TOP :			// Top edge 
		case WMSZ_BOTTOM :		// Bottom edge 
			bModifyY = FALSE;
			break;
		case WMSZ_BOTTOMLEFT :	// Bottom-left corner 
		case WMSZ_BOTTOMRIGHT :	// Bottom-right corner 
		case WMSZ_TOPLEFT :		// Top-left corner 
		case WMSZ_TOPRIGHT :	// Top-right corner 
			if (nXDiff < nYDiff)
			{
				bModifyY = FALSE;
			}
			else
			{
				bModifyY = TRUE;
			}
			break;
		default:
			ASSERT(!"Unhandled coordinate!");
		}

		CalcVideoWindowSize( FALSE, bModifyY);

		// Get real changes
		nXDiff -= m_cpVidSize.x - cpCurVid.x;
		nYDiff -= m_cpVidSize.y - cpCurVid.y;

		switch (nSide)
		{
		case WMSZ_LEFT :		// Left edge 
		case WMSZ_RIGHT :		// Right edge 
			pRect->bottom -= nYDiff;
			break;
		case WMSZ_TOP :			// Top edge 
		case WMSZ_BOTTOM :		// Bottom edge 
			pRect->right -= nXDiff;
			break;
		case WMSZ_BOTTOMLEFT :	// Bottom-left corner 
			pRect->bottom -= nYDiff;
			pRect->left	 += nXDiff;
			break;
		case WMSZ_BOTTOMRIGHT :	// Bottom-right corner 
			pRect->bottom -= nYDiff;
			pRect->right -= nXDiff;
			break;
		case WMSZ_TOPLEFT :		// Top-left corner 
			pRect->top += nYDiff;
			pRect->left	 += nXDiff;
			break;
		case WMSZ_TOPRIGHT :	// Top-right corner 
			pRect->top += nYDiff;
			pRect->right -= nXDiff;
			break;
		default:
			ASSERT(!"Unhandled coordinate!");
		}

		//TRACE( "Sizing diff: %d,%d\n", nXDiff, nYDiff);

		CalcMainWindow();

		UpdateButtons();

		UpdateStatusBar();
	}

	CDialog::OnSizing(nSide, pRect);
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if (m_cStatusBar.GetSafeHwnd())
	{
		LPARAM size;

		size = cx;
		size |= cy << 16;

		m_cStatusBar.SendMessage( WM_SIZE, nType, size);
	}
}

/*-----------------------------------------------------------------------------------------------*/

DWORD CAVPlaybackDlg::GetBorderHeight()
{
    return GetSystemMetrics(SM_CYBORDER)*2;
}

/*-----------------------------------------------------------------------------------------------*/

DWORD CAVPlaybackDlg::GetButtonListHeight()
{
	// Buttons
	return GetSystemMetrics(SM_CYSIZE);
}

/*-----------------------------------------------------------------------------------------------*/

// Frame top left must be given 
// if bUseFrame, frame right, buttom will be used to calcualte cpVidSize
// if !bUseFrame, cpVidSize will be used to calculate frame right buttom
void CAVPlaybackDlg::CalcVideoWindowSize(BOOL bUseFrame, BOOL bModifyY)
{
	CPoint cpEdge(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));

	// Do cross calculations
	if (bUseFrame)
	{
		// Total frame size is given, so calculate view size
		m_cpVidSize.x = m_crVidFrame.Width() - cpEdge.x*2;
		m_cpVidSize.y = m_crVidFrame.Height() - cpEdge.y*2;
	}
	else
	{
		// View size is given, so calculate frame size
		m_crVidFrame.right = m_crVidFrame.left + m_cpVidSize.x + cpEdge.x*2;
		m_crVidFrame.bottom = m_crVidFrame.top + m_cpVidSize.y + cpEdge.y*2;
	}

	// Apply keep ratio
	if (m_bLockRatio)
	{
		if (bModifyY)
		{
			int nYDiff = m_cpVidSize.y - (int) ((double) m_cpVidSize.x * m_dfRatio + 0.5);
			if (nYDiff != 0)
			{
				m_cpVidSize.y -= nYDiff;
				m_crVidFrame.bottom -= nYDiff;
			}
		}
		else
		{
			int nXDiff = m_cpVidSize.x - (int) ((double) m_cpVidSize.y / m_dfRatio + 0.5);
			if (nXDiff != 0)
			{
				m_cpVidSize.x -= nXDiff;
				m_crVidFrame.right -= nXDiff;
			}
		}
	}
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::CalcMainWindow()
{
	CPoint cpFrameSize( GetSystemMetrics(SM_CXSIZEFRAME), GetSystemMetrics(SM_CYSIZEFRAME));
    int nTitleHeight  = GetSystemMetrics(SM_CYCAPTION);

	// Show video Window to get Frame size

	// Calculate sizes
	m_crChildPos.left = cpFrameSize.x;
	m_crChildPos.right = m_crChildPos.left + m_crVidFrame.Width();
	m_crChildPos.top = nTitleHeight + cpFrameSize.y;
	m_crChildPos.bottom = m_crChildPos.top 
						+ m_crVidFrame.Height() 
						+ GetBorderHeight() + GetButtonListHeight()
						+ m_iSliderCtrlHeight
						+ GetBorderHeight() + GetStatusBarHeight();

	m_crMainWnd.left = 0;
	m_crMainWnd.right = m_crChildPos.right + cpFrameSize.x;
	m_crMainWnd.top = 0;
	m_crMainWnd.bottom = m_crChildPos.bottom + cpFrameSize.y;

	m_crButtons.left = 0;
	m_crButtons.right = m_crChildPos.Width();
	m_crButtons.bottom = m_crChildPos.Height() - m_iSliderCtrlHeight - GetBorderHeight() - GetStatusBarHeight();
	m_crButtons.top = m_crButtons.bottom - GetButtonListHeight();

	m_crSliderCtrl.left = 0;
	m_crSliderCtrl.right = m_crChildPos.Width();
	m_crSliderCtrl.bottom = m_crChildPos.Height() - GetBorderHeight() - GetStatusBarHeight();
	m_crSliderCtrl.top = m_crSliderCtrl.bottom - m_iSliderCtrlHeight;

	m_crStatusBar.left = 0;
	m_crStatusBar.right = m_crChildPos.Width();
	m_crStatusBar.bottom = m_crChildPos.Height();
	m_crStatusBar.top = m_crStatusBar.bottom - GetStatusBarHeight();

}

/*-----------------------------------------------------------------------------------------------*/

CPoint CAVPlaybackDlg::GetButtonDistance()
{
	CPoint crBtSize( GetButtonSize());
	return CPoint( crBtSize.x / 4, crBtSize.y / 2);
}

/*-----------------------------------------------------------------------------------------------*/

DWORD CAVPlaybackDlg::GetStatusBarHeight()
{
	return m_iStatusBarHeight;
}

/*-----------------------------------------------------------------------------------------------*/

CPoint CAVPlaybackDlg::GetButtonSize()
{
	return CPoint( GetSystemMetrics( SM_CXSIZE) * 2, GetButtonListHeight());
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::UpdateMainWindow()
{
	// Main Window
    SetWindowPos( NULL, RECT2POS(m_crMainWnd), SWP_NOOWNERZORDER);
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::UpdateVideoWindow()
{
	// Get Video Window
	CWnd* pVideoWnd = GetDlgItem( IDC_ST_VIDEO_WND);

    pVideoWnd->SetWindowPos( NULL, RECT2POS(m_crVidFrame), SWP_NOOWNERZORDER);

	// Update Video Window filter
	if (m_pAVPlaybackCtrl)
	{
		m_pAVPlaybackCtrl->UpdateVideoSize( GetDlgItem(IDC_ST_VIDEO_WND)->GetSafeHwnd());
	}
	
	pVideoWnd->RedrawWindow();
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::UpdateButtons()
{
	CPoint crBtSize( GetButtonSize());

	CPoint cpButtonDist( GetButtonDistance());

	CRect crBtFf( m_crButtons);
	crBtFf.right = crBtFf.left + crBtSize.x;

	CRect crBtFb( m_crButtons);
	crBtFb.left = crBtFb.right - crBtSize.x;

	CPoint crBtCenter(m_crButtons.CenterPoint());

	CRect crBtStop( m_crButtons);
	crBtStop.left =  crBtCenter.x - crBtSize.x/2; /*- crBtSize.x/2 - crBtSize.x*2 - cpButtonDist.x;*/ 
	crBtStop.right = crBtStop.left + crBtSize.x;
	
	CRect crBtPlay( m_crButtons);
	crBtPlay.left = crBtStop.left - crBtSize.x - cpButtonDist.x; 
	crBtPlay.right = crBtPlay.left + crBtSize.x;

	CRect crBtRec( m_crButtons);
	crBtRec.left = crBtStop.right + cpButtonDist.x;
	crBtRec.right = crBtRec.left + crBtSize.x;

	// Jump-to-Begining Button
	CWnd* pFfBt = GetDlgItem( IDC_BT_JUMP_TO_END);
	ASSERT( pFfBt);
	if (pFfBt)
	{
		pFfBt->SetWindowPos( NULL, RECT2POS(crBtFb), SWP_NOOWNERZORDER);
	}

	// Jump-to-End Button
	CWnd* pFbBt = GetDlgItem( IDC_BT_JUMP_TO_START);
	ASSERT( pFbBt);
	if (pFbBt)
	{
		pFbBt->SetWindowPos( NULL, RECT2POS(crBtFf), SWP_NOOWNERZORDER);
	}

	// Rec(ord) Button
	CWnd* pRecBt = GetDlgItem( IDC_BT_RECORD);
	ASSERT( pRecBt);
	if (pRecBt)
	{
		pRecBt->SetWindowPos( NULL, RECT2POS(crBtRec), SWP_NOOWNERZORDER);
	}

	// Stop Button
	CWnd* pStopBt = GetDlgItem( IDC_BT_STOP);
	ASSERT( pStopBt);
	if (pStopBt)
	{
		pStopBt->SetWindowPos( NULL, RECT2POS(crBtStop), SWP_NOOWNERZORDER);
	}

	// Default button must be last

	// Play Button
	CWnd* pPlayBt = GetDlgItem( IDC_BT_PLAY);
	ASSERT( pPlayBt);
	if (pPlayBt)
	{
		pPlayBt->SetWindowPos( NULL, RECT2POS(crBtPlay), SWP_NOOWNERZORDER);
	}

	CWnd* pSliderCtrl = GetDlgItem( IDC_SLIDER1);
	ASSERT( pSliderCtrl);
	if (pSliderCtrl)
	{
		pSliderCtrl->SetWindowPos( NULL, RECT2POS(m_crSliderCtrl), SWP_NOOWNERZORDER);
	}
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::UpdateStatusBar()
{
	// Update Parts size
	//
	int aiPartDim[SBP_MAX]= {m_crStatusBar.Width() / 2, -1};

	m_cStatusBar.SetParts( SBP_MAX, aiPartDim);
}

/*-----------------------------------------------------------------------------------------------*/

CString CAVPlaybackDlg::Value2String(__int64 llValue)
{
	CString csVal;
	
	LPCTSTR pstrUnit = _T("");

	double dfVal;
										
	if (llValue >= (__int64) 1024 * 1024 * 1024 * 1024 * 1024) 
	{
		dfVal = ((double)(int) (llValue / (1024 * 1024 * 1024))) / (1024.0);	//0x4 0000 0000 0000
		pstrUnit = _T("T");
	}
	if (llValue >= (__int64) 900 * 1024 * 1024 * 1024)
	{
		dfVal = ((double)(int) (llValue / (1024))) / (1024.0 * 1024.0 * 1024.0);	// 0x100 0000 0000
		pstrUnit = _T("T");
	}
	else if (llValue >= (__int64) 900 * 1024 * 1024)
	{	
		dfVal = ((double)(int) llValue) / (1024.0 * 1024.0 * 1024.0);	//0x4000 0000
		pstrUnit = _T("G");
	}
	else if (llValue >= 900 * 1024)
	{
		dfVal = ((double)(int) llValue) / (1024.0 * 1024.0); // 0x10 0000
		pstrUnit = _T("M");
	}
	else if (llValue >= 900)
	{
		dfVal = ((double)(int) llValue) / 1024.0;
		pstrUnit = _T("K");
	} 
	else
	{
		csVal.Format( _T("%d "), (int) llValue);
	}

	if (csVal.IsEmpty())
	{
		DWORD dwPrecision = 3;
		if (dfVal >= 100.0)
		{
			dwPrecision = 1;
		}
		else if (dfVal >= 10.0)
		{
			dwPrecision = 2;
		}
		
		csVal.Format( _T("%.*f %s"), dwPrecision, dfVal, pstrUnit);
	}

	return csVal;
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::UpdateState()
{
	// Update button state
	if (m_pAVPlaybackCtrl)
	{
		// STOP button
		GetDlgItem( IDC_BT_STOP)->EnableWindow(	m_pAVPlaybackCtrl->IsStopEnabled() );

		// PLAY button
		CString csPlayCaption;
		if ( m_pAVPlaybackCtrl->IsPauseEnabled() )
		{
			csPlayCaption.LoadString( IDS_PAUSE);
		}
		else
		{
			csPlayCaption.LoadString( IDS_PLAY);
		}
		GetDlgItem( IDC_BT_PLAY)->SetWindowText( csPlayCaption);

		// Get Update PVR state
		m_pAVPlaybackCtrl->GetStatistics();

		__int64 i64PlaybackFilePosition = m_pAVPlaybackCtrl->GetPlaybackFilePosition();
		__int64 i64RecordFileSize = m_pAVPlaybackCtrl->GetRecordFileSize();


		BOOL bPlaybackFileAvailable = i64RecordFileSize ? TRUE : FALSE;

		// FAST FORWARD button ... enabled for for timeshifting and file playback
		GetDlgItem( IDC_BT_JUMP_TO_START )->EnableWindow( bPlaybackFileAvailable );

		// REWIND button ... enabled for for timeshifting and file playback
		GetDlgItem( IDC_BT_JUMP_TO_END )->EnableWindow( bPlaybackFileAvailable );

		// FAST FORWARD button ... enabled for for timeshifting and file playback
		GetDlgItem( IDC_SLIDER1 )->EnableWindow( bPlaybackFileAvailable );

		// REC button
		GetDlgItem( IDC_BT_RECORD )->EnableWindow( m_pAVPlaybackCtrl->IsRecordEnabled() );


		// If the Playback position in non-zero, show the Position
		if ( i64PlaybackFilePosition )
		{
			CString csPlayCap;
			csPlayCap.Format( _T("Played %sBytes from %s"), 
							  Value2String(i64PlaybackFilePosition),m_pAVPlaybackCtrl->GetRecordPathName());
			m_cStatusBar.SetText( csPlayCap, SBP_PLAY, 0);
		}
		// If the Playback position is zero and the Pause has been selected, indicated playback paused.
		else if ( m_pAVPlaybackCtrl->IsLivePause() || m_pAVPlaybackCtrl->IsTimeShiftPlay()  )
		{
			m_cStatusBar.SetText( _T("Playback paused"), SBP_PLAY, SBT_NOBORDERS);
		}
		// If the Playback position is zero and the Pause was not selected, indicated nothing.
		else
		{
			m_cStatusBar.SetText( _T(""), SBP_PLAY, SBT_NOBORDERS);
		}

		// Update Status Bar Record text
		if (i64RecordFileSize)
		{
			CString csRecCap;
			csRecCap.Format( _T("Recorded %sBytes to %s"), 
							 Value2String(i64RecordFileSize),m_pAVPlaybackCtrl->GetRecordPathName() );
			m_cStatusBar.SetText( csRecCap, SBP_RECORD, 0);

			// If playback is is progress, position the slider to show position within the file
			if ( !m_bScrollBarRepositioning )
			{
				if (i64PlaybackFilePosition)
				{
					int iTemp = (int) ( (int)(i64PlaybackFilePosition/1000000) *100 / (int)(i64RecordFileSize/1000000) );

					m_cSliderCtrl.SetPos(iTemp);
				}
				// No playback in progress, position the bar at the far right
				else
				{
					m_cSliderCtrl.SetPos(100);
				}
			}

		}
		else
		{
			m_cStatusBar.SetText( _T(""), SBP_RECORD, SBT_NOBORDERS);
			m_cStatusBar.RedrawWindow();	// To update border changes

			if ( !m_bScrollBarRepositioning )
			{
				// No Recording in Process, position the slider at the far left and disable
				m_cSliderCtrl.SetPos(0);
			}

			// FAST FORWARD button ... enabled for for timeshifting and file playback
			GetDlgItem( IDC_SLIDER1 )->EnableWindow( FALSE );
		}
	}
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnBtPlay() 
{
	// TODO: Add your control notification handler code here
	if (!m_pAVPlaybackCtrl)
	{
		return;
	}

	if ( m_pAVPlaybackCtrl->IsPauseEnabled() )
	{
		m_pAVPlaybackCtrl->Pause();
	}
	else
	{
		m_pAVPlaybackCtrl->Play();
	}
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnBtStop() 
{
	// TODO: Add your control notification handler code here
	if (!m_pAVPlaybackCtrl)
	{
		return;
	}

	m_pAVPlaybackCtrl->Stop();
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnBtRecord() 
{
	static bool bIgnoreNextClick = FALSE;

	// TODO: Add your control notification handler code here
	if (!m_pAVPlaybackCtrl)
	{
		return;
	}

	m_pAVPlaybackCtrl->Record();
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if (nIDEvent == m_nStatusTimer)
	{
		m_pAVPlaybackCtrl->CheckTimeshiftStateChange();

		UpdateState();
	}

	CDialog::OnTimer(nIDEvent);
}

/*-----------------------------------------------------------------------------------------------*/

enum 
{
	PVR_STATUS_TIMER = 1,
};

#define PVR_STATUS_TIMER_PIODE	100

void CAVPlaybackDlg::StartStatusTimer()
{
	if (m_nStatusTimer != 0)
	{
		// Already running
		return;
	}

	m_nStatusTimer = SetTimer(PVR_STATUS_TIMER, PVR_STATUS_TIMER_PIODE, NULL);
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::StopStatusTimer()
{
	if (m_nStatusTimer == 0)
	{
		// Not running
		return;
	}

	KillTimer(m_nStatusTimer);
	m_nStatusTimer = 0;
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnBnClickedBtJumpToStart()
{
	m_pAVPlaybackCtrl->JumpToStart();
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnBnClickedBtJumpToEnd()
{
	m_pAVPlaybackCtrl->JumpToEnd();
}

/*-----------------------------------------------------------------------------------------------*/

void CAVPlaybackDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	if (nSBCode == TB_THUMBTRACK)
	{
		m_bScrollBarRepositioning = TRUE;
	}
	else if (nSBCode == TB_THUMBPOSITION)
	{
		m_cSliderCtrl.SetPos(nPos);
		m_pAVPlaybackCtrl->RepositionSliderBar( m_cSliderCtrl.GetPos() );

		m_bScrollBarRepositioning = FALSE;
	}
}

/*-----------------------------------------------------------------------------------------------*/
