/*
	UndoPush()
*/
BOOL CWallBrowserStretchView::UndoPush(int nID)
{
	BOOL bUndo = FALSE;

	if(++m_nUndoLevel <= MAX_STACK_SIZE)
	{
		// salva il contenuto dell'immagine nello stack per l'undo
		CWallBrowserDoc* pDoc = (CWallBrowserDoc*)GetDocument();
		if(pDoc)
		{
			CImage *pImage = pDoc->GetImage();
			if(pImage && pImage->GetWidth() > 0 && pImage->GetHeight() > 0)
			{
				CImage* pImg;
				CImageFactory* pImgFactory = new CImageFactory();
				char szLibraryName[_MAX_PATH+1];
				strcpy(szLibraryName,pImage->GetLibraryName());
				pImg = pImgFactory->Create(szLibraryName,sizeof(szLibraryName));
				DIBINFO DibInfo;
				DibInfo.nPerspective = 0;

				HDIB hDib = pImage->GetDIB(&DibInfo);
				if(hDib)
				{
					pImg->SetDIB(hDib,&DibInfo);
					::GlobalFree(hDib);
					
					UNDOINFO* undoinfo = new UNDOINFO;
					undoinfo->pImageFactory = pImgFactory;
					undoinfo->DibInfo.nPerspective = DibInfo.nPerspective;
					undoinfo->nRedo = nID;
					int nLevel = m_UndoInfo.Push(undoinfo);
					if(nLevel!=-1)
						bUndo = TRUE;
				}
				else
				{
					delete pImgFactory;
				}
			}
		}
	}
	else
		m_nUndoLevel--;

	CWnd* pWnd = AfxGetMainWnd();
	if(pWnd)
	{
		pWnd->SendMessage(WM_EDIT_UNDO,UndoEnabled(),0L);
		pWnd->SendMessage(WM_EDIT_REDO,FALSE,0L);
	}

	return(bUndo);
}
/*
	OnDraw()
*/
void CWallBrowserStretchView::OnDraw(CDC* pDC)
{
	// documento
	CWallBrowserDoc* pDoc = (CWallBrowserDoc*)GetDocument();
	if(!pDoc)
		return;

	// nome file
	memset(m_szFileName,'\0',sizeof(m_szFileName));
	strcpyn(m_szFileName,pDoc->GetFileName(),sizeof(m_szFileName));
	if(m_szFileName[0]=='\0')
		return;

	// immagine
	CImage *pImage = pDoc->GetImage();
	if(pImage && pImage->GetWidth() > 0 && pImage->GetHeight() > 0)
		m_ImageDraw.SetImage(pImage);
	else
		return;

	// immagine valida
	if(!pDoc->GetPictureFlag())
		return;

	// dimensione corrente della vista
	GetClientRect(&m_rcClient);

	// adatta l'immagine alla dimensione corrente della vista
	double nRemains = 0.0;
	double nWidth   = (double)pImage->GetWidth();
	double nHeight  = (double)pImage->GetHeight();

	if(nHeight > (double)m_rcClient.bottom)
	{
		nRemains = FDIV(nHeight,(double)m_rcClient.bottom);
		if(nRemains > 0.0)
		{
			nHeight = FDIV(nHeight,nRemains);
			nWidth  = FDIV(nWidth,nRemains);
		}
	}
	if(nWidth > (double)m_rcClient.right)
	{
		nRemains = FDIV(nWidth,(double)m_rcClient.right);
		if(nRemains > 0.0)
		{
			nHeight = FDIV(nHeight,nRemains);
			nWidth  = FDIV(nWidth,nRemains);
		}
	}

	m_rcInvalid.SetRect(0,0,(int)nWidth,(int)nHeight);

	// nome del file
	if(m_pMainFrameStatusBar)
	{
		strcpyn(m_szStatus,pDoc->GetFileName(),sizeof(m_szStatus));
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_FILENAME_ID,m_szStatus);
	}

	double nFactor = 0.0;
	char szFactor[8] = {0};
	if(m_nViewType==VIEWTYPE_SCROLL)
	{
		nFactor = GetZoomRatio();
		if(nFactor >= 1.0)
			sprintf(szFactor,"%.2f:1",nFactor);
		else
			sprintf(szFactor,"1:%.2f",1/nFactor);
	}

	// fattore di zoom e % di visualizzazione dell'immagine nella vista
	int nRatio = (int)((nWidth * 100.0)/pImage->GetWidth());
	if(m_pMainFrameStatusBar)
	{
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_ZOOM_ID,szFactor);
		
		if(m_nViewType==VIEWTYPE_STRETCH)
			_snprintf(m_szStatus,sizeof(m_szStatus)-1,"%d%% (stretch)",nRatio);
		else
			_snprintf(m_szStatus,sizeof(m_szStatus)-1,"%.1f%% (scroll)",nFactor * 100.0);
		
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_RATIO_ID,m_szStatus);
	}
	
	// area della vista (client rect)
	m_rcClient.right  = (int)nWidth;
	m_rcClient.bottom = (int)nHeight;

	// ricava le informazioni per il titolo
	char szTitle[_MAX_PATH+1] = {0};
	int nColors = pImage->GetNumColors();
	if(m_nViewType==VIEWTYPE_STRETCH)
		_snprintf(szFactor,sizeof(szFactor)-1,"%d%%",nRatio);
	_snprintf(szTitle,
			sizeof(szTitle)-1,
			"%s (%s) - %d x %d x %d%s",
			pDoc->GetFileName(),
			szFactor,
			pImage->GetWidth(),
			pImage->GetHeight(),
			(nColors > 256 || nColors==0) ? 16 : nColors,
			(nColors > 256 || nColors==0) ? "M" : ""
			);
	pDoc->SetTitle(szTitle);

	// ricava le informazioni per la status bar
	if(m_pMainFrameStatusBar)
	{
		int nColors = pImage->GetNumColors();
		_snprintf(m_szStatus,
				sizeof(m_szStatus)-1,
				"%d x %d x %d%s colors, %d bpp",
				pImage->GetWidth(),
				pImage->GetHeight(),
				(nColors > 256 || nColors==0) ? 16 : nColors,
				(nColors > 256 || nColors==0) ? "M" : "",
				pImage->GetBPP()
				);
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_INFO_ID,m_szStatus);

		UINT nMemUsed = pImage->GetMemUsed();
		if(nMemUsed < 1024L)
			_snprintf(m_szStatus,sizeof(m_szStatus)-1,"%ld bytes",nMemUsed);
		else if(nMemUsed < 1048576L)
			_snprintf(m_szStatus,sizeof(m_szStatus)-1,"%0.1f KB",FDIV(((float)nMemUsed),1024.0f));
		else
			_snprintf(m_szStatus,sizeof(m_szStatus)-1,"%0.2f MB",FDIV(((float)nMemUsed),1048576.0f));
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_MEM_ID,m_szStatus);

		strcpyn(m_szStatus,pImage->GetLibraryName(),sizeof(m_szStatus));
		m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_LIBRARY_ID,m_szStatus);
	}
	
	// area dell'immagine
	CRect rcImg(0,0,pImage->GetWidth(),pImage->GetHeight());

	// se per la vista deve usare lo scroll, imposta le aree in modo tale che vengano visualizzate le barre di scorrimento
	if(m_nViewType==VIEWTYPE_SCROLL)
		m_rcClient = rcImg;

	// visualizza l'immagine scalata rispetto alla dimensione corrente della vista
	m_ImageDraw.DrawEx(pDC->GetSafeHdc(),
					&m_rcClient,
					&rcImg,
					NULL,
					FALSE,
					COLORONCOLOR,
					m_nDrawMode,
					SRCCOPY,
					m_bRebuildPalette
					);

	m_bRebuildPalette = FALSE;
}