// TilesDlg.cpp : implementation file
//

#include "stdafx.h"
#include "mdimap.h"
#include "TilesDlg.h"
#include "MapFrm.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTilesDlg dialog


CTilesDlg::CTilesDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTilesDlg::IDD, pParent)
{
	// Set all data
	m_Screen = NULL;
	m_MouseDown =FALSE;
	m_InWindow = FALSE;

	//{{AFX_DATA_INIT(CTilesDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CTilesDlg::~CTilesDlg()
{
	SAFEDELETE( m_Screen );
}

BOOL CTilesDlg::InitCDX()
{
	if(!m_Screen){
		m_Screen = new CDXScreen;
		m_Screen->CreateWindowed(m_hWnd,GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
	}

	return TRUE;

}

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


BEGIN_MESSAGE_MAP(CTilesDlg, CDialog)
	//{{AFX_MSG_MAP(CTilesDlg)
	ON_WM_HSCROLL()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTilesDlg message handlers


//Break into Paint() and DrawScreen a la MapDlg and AnimDlg
void CTilesDlg::Paint() 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());
	CDXTile *tiles = pParent->GetTiles(pParent->GetSelLayer());

	if(m_Screen){
		m_Screen->GetBack( )->Fill( 0 );

		if( tiles )
		{
			RECT src;
			int MinX = m_SelMinX-GetScrollPos( SB_HORZ ),
				MinY = m_SelMinY-GetScrollPos( SB_VERT ),
				MaxX = m_SelMaxX-GetScrollPos( SB_HORZ ),
				MaxY = m_SelMaxY-GetScrollPos( SB_VERT );

			for( int y=0; y<m_yTiles+1; y++ )
			{
				int yTilePos = y + GetScrollPos( SB_VERT );
				if( yTilePos < tiles->m_BlockY )
				{	
					for( int x=0; x<tiles->m_BlockX; x++ )
					{	
						int xTilePos = x + GetScrollPos( SB_HORZ );
						if( xTilePos < tiles->m_BlockX )
						{
							SetRect( &src, xTilePos*32, yTilePos*32, xTilePos*32+32, yTilePos*32+32 );

							if( m_MouseDown && x>=MinX && x<=MaxX && y>=MinY && y<=MaxY )
							{	if( pParent->cfg.m_XorTiles )
								{
									tiles->CDXSurface::DrawBlk( m_Screen->GetBack( ), x*32, y*32, &src );	
									m_Screen->GetBack( )->InvertColors( x*32, y*32, x*32+32, y*32+32 );
								}
								else tiles->CDXSurface::DrawBlkAlpha( m_Screen->GetBack( ), x*32, y*32, &src, 50 );
							}
							else tiles->Draw( x*32, y*32, m_Screen->GetBack( ), 0, yTilePos*(tiles->m_BlockX)+xTilePos);
						}
					}
				}
			}
		}
	}

	m_Screen->Flip( pParent->cfg.m_PlayAnim, FALSE );
}

BOOL CTilesDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	m_SelMinX=m_SelMaxX=m_SelMinY=m_SelMaxY=0;

	if(!InitCDX()) return FALSE;

	return TRUE;	// return TRUE unless you set the focus to a control
					// EXCEPTION: OCX Property Pages should return FALSE
}

void CTilesDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{

	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());
	UINT pos = GetScrollPos( SB_HORZ );

	pos = pParent->ScrollBar( nSBCode, pos, nPos, m_xTiles-1 );
	SetScrollPos( SB_HORZ, pos );

	PostMessage(WM_PAINT);
	
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTilesDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	UINT x = GetScrollPos( SB_HORZ ),
		 y = GetScrollPos( SB_VERT );

	if( nChar==VK_UP )		   y--;
	else if( nChar==VK_DOWN )  y++;
	else if( nChar==VK_LEFT )  x--;
	else if( nChar==VK_RIGHT ) x++;

	SetScrollPos( SB_HORZ, x );
	SetScrollPos( SB_VERT, y );

	PostMessage(WM_PAINT);

	CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CTilesDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());

	if( GetAsyncKeyState( VK_CONTROL ) & 0x8000 )
	{	int x = point.x/32 + GetScrollPos( SB_HORZ );
		int y = point.y/32 + GetScrollPos( SB_VERT );

		if( pParent->GetTiles(pParent->GetSelLayer()) ){
			pParent->GetAnimDlg()->AddTile( y * (pParent->GetTiles(pParent->GetSelLayer())->GetWidth() / 32) + x );
		}
	}
	else
	{
		m_MouseDown = TRUE;
		m_MouseBegin = point;
		m_MouseEnd = point;
		SetMouseRect( );
	}

	PostMessage(WM_PAINT);

	CDialog::OnLButtonDown(nFlags, point);
}

void CTilesDlg::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());

	if( m_MouseDown )
	{	
		m_MouseDown = FALSE;
		m_MouseEnd = point;
		
		SetMouseRect( );
		PostMessage(WM_PAINT);

		// Save the Selected tiles as new Brush
		if( pParent->GetTiles(pParent->GetSelLayer()) )
		{	
			pParent->SetBrush(pParent->GetSelBrush(),
				m_SelMaxY - m_SelMinY + 1, m_SelMaxX - m_SelMinX + 1,
				m_SelMinX, m_SelMinY);

		} 
		pParent->UpdateMenu( );
	}
	CDialog::OnLButtonUp(nFlags, point);
}

void CTilesDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());

	if( m_InWindow == FALSE )
	{
		SetFocus( );
		m_InWindow=TRUE;
//		SendMessage( WM_NCPAINT, 0, 0 );
	}

	if( pParent->GetTiles(pParent->GetSelLayer()) )
	{
//		CString str;
//		str.Format( "Tile: %i", (point.y/32 + GetScrollPos( SB_VERT )) * (m_Tiles[pParent->m_SelLayer]->m_BlockX) + (point.x/32 + GetScrollPos( SB_HORZ )) );
		
//		pParent->m_StatusBar->SetText(str,1,0);

		if( m_MouseDown )
		{
			m_MouseEnd = point;
			SetMouseRect( );
			PostMessage(WM_PAINT);
		}
	}
	CDialog::OnMouseMove(nFlags, point);
}

void CTilesDlg::OnRButtonDown(UINT nFlags, CPoint point) 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());

	if( pParent->GetTiles(pParent->GetSelLayer()) )
		pParent->PopUp( this, IDR_TILES, point );

	CDialog::OnRButtonDown(nFlags, point);
}

void CTilesDlg::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());
	CDXTile* tiles = pParent->GetTiles(pParent->GetSelLayer());

	m_xTiles = (cx)/32;
	m_yTiles = (cy)/32;

	if( tiles)
	{	
		SetScrollRange( SB_HORZ, 0, (tiles->m_BlockX)-m_xTiles );
		SetScrollRange( SB_VERT, 0, (tiles->m_BlockY)-m_yTiles );
	}
}

void CTilesDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());
	UINT pos = GetScrollPos( SB_VERT );
	
	pos = pParent->ScrollBar( nSBCode, pos, nPos, m_yTiles-1 );
	SetScrollPos( SB_VERT, pos );

	PostMessage(WM_PAINT);

	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}


//////////////////////////////////////////////////////////////////////////////////////
//Miscellaneous Functions

void CTilesDlg::SetMouseRect()
{
	CMapFrame* pParent = STATIC_DOWNCAST(CMapFrame, GetParentFrame());
	CDXTile* tiles = pParent->GetTiles(pParent->GetSelLayer());

	m_SelMinX = min( m_MouseBegin.x, m_MouseEnd.x )/32 + GetScrollPos( SB_HORZ );
	m_SelMinY = min( m_MouseBegin.y, m_MouseEnd.y )/32 + GetScrollPos( SB_VERT );
	m_SelMaxX = max( m_MouseBegin.x, m_MouseEnd.x )/32 + GetScrollPos( SB_HORZ );
	m_SelMaxY = max( m_MouseBegin.y, m_MouseEnd.y )/32 + GetScrollPos( SB_VERT );

	if( m_SelMinX<0 ) m_SelMinX=0;
	if( m_SelMinY<0 ) m_SelMinY=0;
	if( tiles )
	{
		if( m_SelMaxX >= tiles->m_BlockX ) m_SelMaxX = tiles->m_BlockX-1;
		if( m_SelMaxY >= tiles->m_BlockY ) m_SelMaxY = tiles->m_BlockY-1;
	}
}

void CTilesDlg::OnPaint() 
{
	Paint();
	CDialog::OnPaint();
}
