// VideoViewBase.cpp : implementation file
//

#include "stdafx.h"
#include "VideoViewBase.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CVideoViewBase

CVideoViewBase::CVideoViewBase()
{
	m_pActivePage = NULL;
	m_bMultiScreen = FALSE;
	m_nCurViewMode = 0;
	m_bFullScreen  = FALSE;
	m_bDrawActive  = TRUE;
	m_clrRect	   = RGB(255, 0, 0);
	m_clrBack      = RGB(127,127,127);
	m_bAutoSizeAdj = TRUE;
	m_nWorkMode    = 1; // 1 - live, 2 - play
	m_nButtom	   = 0;
	m_nRight       = 0;
	m_nCurStartChn = 0;
}

CVideoViewBase::~CVideoViewBase()
{
}

BEGIN_MESSAGE_MAP(CVideoViewBase, CWnd)
	//{{AFX_MSG_MAP(CVideoViewBase)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CVideoViewBase message handlers

BOOL CVideoViewBase::Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext )
{
	dwStyle|=WS_EX_TOOLWINDOW;
	
	return CWnd::Create(lpszClassName,lpszWindowName,dwStyle,rect,pParentWnd,nID,pContext );
}

//	全屏显示
void CVideoViewBase::SetFullScreen(BOOL bFlag)
{
	if(bFlag == m_bFullScreen) return;
	
	m_bFullScreen = bFlag;
	if( bFlag )
	{//全屏
		//得到显示器分辨率
		int cx = GetSystemMetrics(SM_CXSCREEN);
		int cy = GetSystemMetrics(SM_CYSCREEN);
		
		// 保存位置信息
		GetWindowPlacement(&_temppl);
		//修改风格
		ModifyStyle(WS_CHILD, WS_POPUP);
		ModifyStyleEx(0, WS_EX_TOOLWINDOW);
		//修改父窗口
		_tempparent = SetParent(NULL);//m_hWnd, ::GetDesktopWindow());
	
		//AfxGetMainWnd()->ShowWindow(SW_HIDE);
		//移动窗口;
		MoveWindow(0, 0, cx, cy, TRUE);
		//::SetWindowPos(m_hWnd, HWND_TOPMOST,0,0,cx,cy,SWP_NOMOVE|SWP_NOSIZE);
		::SetWindowPos(m_hWnd, HWND_TOPMOST,0,0,cx,cy,SWP_NOMOVE|SWP_NOSIZE);
	}
	else if(_tempparent)
	{	//还原
		//还原父窗口
		//_tempparent->ShowWindow(SW_SHOW);
		SetParent(_tempparent);
		//还原风格
		ModifyStyle(WS_POPUP, WS_CHILD);
		//还原位置
		SetWindowPlacement(&_temppl);
		_tempparent->SetFocus();
	}
	//Invalidate();
}

//	多屏显示
void CVideoViewBase::SetMultiScreen(BOOL bFlag)
{
	//if(m_bMultiScreen == bFlag) return;
	m_bMultiScreen = bFlag;
	CRect rc;
	GetRefrenRect(rc);
	rc.left --;
	rc.right ++;
	rc.top --;
	rc.bottom += 3;
	InvalidateRect(rc);
}
void CVideoViewBase::SetActivePage(VideoWndChn *pWnd, BOOL bRepaint)
{
	// check parameter
	if(	!pWnd || !IsWindow(pWnd->m_hWnd) )	return;
	
	// if pWnd is the Active Page, return 
	if( m_pActivePage == pWnd ) return;
	if(!m_bMultiScreen || m_PageList.GetCount() == 1) return;
	//TRACE("Set ActivePage : %d\n", ((CVideoWnd*)pWnd)->GetWinID());
	
	// check list
	POSITION pos=m_PageList.Find(pWnd);
	if(pos==NULL)
	{
		TRACE("__This Window is not a member of container, the operation will terminate.\n");
		return;
	}
	
	if(bRepaint) UpdateWnd();
	
	if( m_bDrawActive ) 
		DrawActivePage(FALSE);
	
	m_pActivePage = pWnd;
	
	if( m_bDrawActive )
		DrawActivePage(TRUE);

	//if(m_pActivePage && m_nWorkMode == 1)
	//	pOcx->LiveActiveEvent(m_pActivePage->m_lHandle, m_pActivePage->m_nStreamInx);
}

void CVideoViewBase::SetDrawActiveRect(BOOL bFlag, COLORREF clrRect)
{
	if(m_bDrawActive==bFlag) return;
	if(bFlag)
	{
		m_clrRect = clrRect;
	}
	m_bDrawActive = bFlag;
	DrawActivePage(bFlag);
}

// 计算窗口位置和尺寸
void CVideoViewBase::CalcPageRect(LPRECT lpRect, int nIndex, int nPageCount)
{
	int nWidth;
	int nHeight;
	CPoint pt;
	if((nPageCount<=0)||(nIndex>=nPageCount))
	{
		lpRect->left=lpRect->right=lpRect->top=lpRect->bottom=0;
		return;
	}
	//get row count
	if(    m_nCurViewMode == VIDEO_MODE_1
		|| m_nCurViewMode == VIDEO_MODE_4
		|| m_nCurViewMode == VIDEO_MODE_9
		|| m_nCurViewMode == VIDEO_MODE_16
		|| m_nCurViewMode == VIDEO_MODE_25
		|| m_nCurViewMode == VIDEO_MODE_36)
	{
		int nRow=0;
		while((nRow)*(nRow)<m_nCurViewMode) nRow++;
		//get singledlg width and height
		nWidth=(lpRect->right-lpRect->left)/nRow;
		nHeight=(lpRect->bottom-lpRect->top)/nRow;
		
		//get top-left point
		
		pt.x=lpRect->left+nWidth*(nIndex%nRow);
		pt.y=lpRect->top+nHeight*(nIndex/nRow);
	}
	else if(m_nCurViewMode == VIDEO_MODE_2)
	{
		nWidth  = (lpRect->right - lpRect->left) / 2;
		nHeight = (lpRect->bottom - lpRect->top);
		pt.x = lpRect->left + nWidth * nIndex;
		pt.y = lpRect->top;
	}
	else if(m_nCurViewMode == VIDEO_MODE_6)
	{
		nWidth=(lpRect->right-lpRect->left)/3;
		nHeight=(lpRect->bottom-lpRect->top)/3;
		if(nIndex == 0)
		{
			pt.x = lpRect->left;
			pt.y = lpRect->top;
			nWidth <<= 1;
			nHeight <<= 1;
		}
		else if(nIndex >= 1 && nIndex <= 2)
		{
			pt.x = lpRect->left + nWidth * 2;
			pt.y = lpRect->top + nHeight * (nIndex - 1);
		}
		else
		{
			pt.x = lpRect->left + nWidth * (nIndex - 3);
			pt.y = lpRect->top + nHeight * 2;
		}
	}
	else if(m_nCurViewMode == VIDEO_MODE_8)
	{
		nWidth=(lpRect->right-lpRect->left)/4;
		nHeight=(lpRect->bottom-lpRect->top)/4;
		if(nIndex == 0)
		{
			pt.x = lpRect->left;
			pt.y = lpRect->top;
			nWidth *= 3;
			nHeight *= 3;
		}
		else if(nIndex >= 1 && nIndex <= 3)
		{
			pt.x = lpRect->left + nWidth * 3;
			pt.y = lpRect->top + nHeight * (nIndex - 1);
		}
		else
		{
			pt.x = lpRect->left + nWidth * (nIndex - 4);
			pt.y = lpRect->top + nHeight * 3;
		}
	}
	else if(m_nCurViewMode == VIDEO_MODE_13)
	{
		nWidth=(lpRect->right-lpRect->left)/4;
		nHeight=(lpRect->bottom-lpRect->top)/4;
		if( (nIndex >= 0 && nIndex <= 4))
		{
			pt.x=lpRect->left+nWidth*(nIndex%4);
			pt.y=lpRect->top+nHeight*(nIndex/4);
		}
		else if(nIndex >= 9 && nIndex <= 12)
		{
			pt.x=lpRect->left+nWidth*((nIndex-9)%4);
			pt.y=lpRect->top+nHeight*3;
		}
		else if(nIndex == 5)
		{
			pt.x=lpRect->left+nWidth;
			pt.y=lpRect->top+nHeight;
			nWidth *= 2;
			nHeight *= 2;
		}
		else if(nIndex == 6)
		{
			pt.x=lpRect->left+nWidth*3;
			pt.y=lpRect->top+nHeight;
		}
		else if(nIndex == 7)
		{
			pt.x=lpRect->left;
			pt.y=lpRect->top+nHeight*2;
		}
		else if(nIndex == 8)
		{
			pt.x=lpRect->left+nWidth*3;
			pt.y=lpRect->top+nHeight*2;
		}
	}
	else if(m_nCurViewMode == VIDEO_MODE_20)
	{
		nWidth=(lpRect->right-lpRect->left)/6;
		nHeight=(lpRect->bottom-lpRect->top)/6;
		if( (nIndex >=0 && nIndex <= 1))
		{
			nWidth  *= 3;
			nHeight *= 3;
			pt.x=lpRect->left+ nWidth * (nIndex%2);
			pt.y=lpRect->top;
		}
		else
		{
			nIndex -= 2;	
			pt.x=lpRect->left+nWidth*(nIndex%6);
			pt.y=lpRect->top+ nHeight*(3 + nIndex/6);
		}
	}
	else if(m_nCurViewMode >= VIDEO_MODE_PAN_2 && m_nCurViewMode <= VIDEO_MODE_PAN_8)
	{
		nWidth=(lpRect->right-lpRect->left) / (m_nCurViewMode - VIDEO_MODE_PAN);
		nHeight=(lpRect->bottom-lpRect->top);
		pt.x=lpRect->left + nWidth * nIndex;
		pt.y=lpRect->top;
	}
	else
	{
		TRACE("not support this viewmode \n");
		return;
	}

	//set rect return back
	lpRect->left=pt.x;
	lpRect->top=pt.y;
	lpRect->right=lpRect->left+nWidth;
	lpRect->bottom=lpRect->top+nHeight;
}
//	画激活窗口边框
void CVideoViewBase::DrawActivePage(BOOL bFlag)
{
	if( !m_bMultiScreen || 
		!m_pActivePage	|| 
		m_PageList.GetCount()<2 
		) return;
	
	CRect rt;
	m_pActivePage->GetWindowRect(&rt);
	ScreenToClient(&rt);
	rt.InflateRect(1,1);
	//TRACE("SetDrawActivePage :%d\n", bFlag);
	if(bFlag)
	{
		CDC *pDC=GetDC();
		if(!pDC) return;
		
		//pDC->Draw3dRect(&rt,RGB(70,255,40), RGB(70,255,40));
		pDC->Draw3dRect(&rt,m_clrRect, m_clrRect);
		rt.InflateRect(1,1);
		pDC->Draw3dRect(&rt, m_clrRect, m_clrRect);
		
		ReleaseDC(pDC);
	}
	else
	{
		CDC *pDC=GetDC();
		if(!pDC) return;
		pDC->Draw3dRect(&rt, m_clrBack, m_clrBack);
		rt.InflateRect(1,1);
		pDC->Draw3dRect(&rt, m_clrBack, m_clrBack);
		ReleaseDC(pDC);
	}
}

void CVideoViewBase::GetRefrenRect(CRect &rcRect)
{
	GetClientRect(&rcRect);
	if(m_nWorkMode == 1)
		rcRect.DeflateRect(1,1);
	rcRect.bottom -= m_nButtom;
	rcRect.right  -= m_nRight;
}

void CVideoViewBase::UpdateWnd()
{
	if(!IsWindowVisible()||IsIconic()) return;

	//得到窗口的设备坐标
	CRect rtContainer;
	GetRefrenRect(rtContainer);
	/*GetClientRect(&rtContainer);
	if(m_nWorkMode == 1)
		rtContainer.DeflateRect(1,1);
	if(m_nButtom)
		rtContainer.bottom -= m_nButtom;
	*/
	if(m_bMultiScreen)
	{ //多屏状态
		CRect rt;
		int nCount = m_PageList.GetCount();
		int i=0;
		POSITION pos;
		for(pos = m_PageList.GetHeadPosition(); pos != NULL;)
		{
			VideoWndChn *p = m_PageList.GetNext(pos);
			rt = rtContainer;
			CalcPageRect(&rt, i, nCount);
			rt.DeflateRect(WINDOW_SPACE, WINDOW_SPACE, WINDOW_SPACE, WINDOW_SPACE); //窗口之间的间隔
			p->MoveWindow(&rt);
			i++;
		}
		for(pos = m_PageList.GetHeadPosition(); pos != NULL;)
		{
			VideoWndChn *p = m_PageList.GetNext(pos);
			p->ShowWindow(SW_SHOW);
		}
		if( m_bDrawActive && m_PageList.GetCount() > 1 ) 
			DrawActivePage(TRUE);
	}
	else
	{ //单屏状态
		for(POSITION pos = m_PageList.GetHeadPosition();pos!=NULL;)
		{
			VideoWndChn *p = m_PageList.GetNext(pos);
			if(!m_pActivePage || p == m_pActivePage)
			{
				m_pActivePage = p;
				p->MoveWindow(&rtContainer);
				p->ShowWindow(SW_SHOW);
				//DPINFO(("Show\n"));
			}
			else 
			{
				p->ShowWindow(SW_HIDE);
				//DPINFO(("Hide\n"));
			}
		}
	}
}

BOOL CVideoViewBase::AddPage(VideoWndChn *pWnd)
{
	// check parameter
	if(	!pWnd || !IsWindow(pWnd->m_hWnd) )	return FALSE;
	
	// check list 
	POSITION pos = m_PageList.Find(pWnd);
	if(pos) 
	{
		TRACE("This Window has been added to container, the operation will terminate.\n");
		return TRUE;
	}
	
	// added page
	m_PageList.AddTail(pWnd);
	
	return TRUE;
}

VideoWndChn *CVideoViewBase::DelPage(VideoWndChn *pWnd)
{
	// check list
	POSITION pos = m_PageList.Find(pWnd);
	if(!pos)
	{
		TRACE("This Window is not a member of container, the operation will terminate.\n");
		return NULL;
	}
	/*if(pWnd == m_pActivePage)
	{
		if(m_pActivePage == GetPrevPage(pWnd))//m_PageList.IsEmpty()?NULL:m_PageList.GetHead();
			m_pActivePage = NULL;
		else
			m_pActivePage = GetPrevPage(pWnd);
	}*/
	if(pWnd == m_pActivePage)
		m_pActivePage = NULL;
	m_PageList.RemoveAt(pos);
	
	if (pWnd)
		pWnd->ShowWindow(SW_HIDE);
	
	return pWnd;
}
