// MapFrm.cpp : implementation of the CMapFrame class
//

#include "stdafx.h"
#include "mdimap.h"
#include "Map_load.h"
#include "MainFrm.h"
#include "Options.h"
#include "Newmap.h"
#include "EditAnim.h"

#include "MapFrm.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMapFrame

IMPLEMENT_DYNCREATE(CMapFrame, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CMapFrame, CMDIChildWnd)
	//{{AFX_MSG_MAP(CMapFrame)
		ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
		ON_WM_SETFOCUS()
		ON_WM_CREATE()
	ON_WM_SIZE()
	ON_COMMAND(ID_FILE_OPENMAP, OnFileOpenmap)
	ON_COMMAND(ID_ADDTOANIM, OnAddtoanim)
	ON_COMMAND(ID_ANIM_DEL, OnAnimDel)
	ON_COMMAND(ID_ANIM_EDIT, OnAnimEdit)
	ON_COMMAND(ID_BRUSH_LOAD, OnBrushLoad)
	ON_COMMAND(ID_BRUSH_SAVE, OnBrushSave)
	ON_COMMAND(ID_DELBRUSH, OnDelbrush)
	ON_COMMAND(ID_FILE_SAVEMAP, OnFileSavemap)
	ON_COMMAND(ID_LAYER_1, OnLayer1)
	ON_COMMAND(ID_LAYER_3, OnLayer3)
	ON_COMMAND(ID_LAYER_LOAD, OnLayerLoad)
	ON_COMMAND(ID_SELBIT1, OnSelbit1)
	ON_COMMAND(ID_SELBIT2, OnSelbit2)
	ON_COMMAND(ID_SELBIT3, OnSelbit3)
	ON_COMMAND(ID_SELBIT4, OnSelbit4)
	ON_COMMAND(ID_SELBIT5, OnSelbit5)
	ON_COMMAND(ID_SELBIT6, OnSelbit6)
	ON_COMMAND(ID_SELBLOCK, OnSelblock)
	ON_COMMAND(ID_SELNOBIT, OnSelnobit)
	ON_COMMAND(ID_TILES_OPEN, OnTilesOpen)
	ON_COMMAND(ID_TOOLS_OPTIONS, OnToolsOptions)
	ON_COMMAND(ID_TOOLS_UNDO, OnToolsUndo)
	ON_COMMAND(ID_WALKBITS1, OnWalkbits1)
	ON_COMMAND(ID_WALKBITS2, OnWalkbits2)
	ON_COMMAND(ID_WALKBITS3, OnWalkbits3)
	ON_COMMAND(ID_WALKBITS4, OnWalkbits4)
	ON_COMMAND(ID_WALKBITS5, OnWalkbits5)
	ON_COMMAND(ID_WALKBITS6, OnWalkbits6)
	ON_COMMAND(ID_WALKBITS_PAINT, OnWalkbitsPaint)
	ON_COMMAND(ID_BRUSH_BRUSH1, OnBrush1)
	ON_COMMAND(ID_BRUSH_BRUSH2, OnBrush2)
	ON_COMMAND(ID_BRUSH_BRUSH3, OnBrush3)
	ON_COMMAND(ID_BRUSH_BRUSH4, OnBrush4)
	ON_COMMAND(ID_BRUSH_BRUSH5, OnBrush5)
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMapFrame construction/destruction

CMapFrame::CMapFrame()
{
	// Init and load in cfg
	LoadCfg( );

	m_TilesDlg = NULL;
	m_MapDlg = NULL;
	m_AnimDlg = NULL;
	
	m_SelBrush=0;
	m_SelLayer=0;
	m_SelBit=0;
	m_Changed=m_PaintBit=FALSE;
	m_Tiles = NULL;
	m_TileSet = new CStringArray;
	m_Map = NULL;

	for(int i=0; i<5; i++ )
	{	m_Brush[i]=0;
		m_BrushX[i]=m_BrushY[i]=0;
	}
	
}

CMapFrame::~CMapFrame()
{
	int i;


	for(i = 0; i < m_NumLayers; i++)
	{
		SAFEDELETE(m_Tiles[i]);
		SAFEDELETE(m_Map[i]);
	}

	DELETEARRAY(m_Tiles);
	DELETEARRAY(m_Map);

	m_AnimDlg->DestroyWindow();
	m_MapDlg->DestroyWindow();
	m_TilesDlg->DestroyWindow();

	SAFEDELETE(m_AnimDlg);
	SAFEDELETE(m_MapDlg);
	SAFEDELETE(m_TilesDlg);
	SAFEDELETE(m_TileSet);

	for(i = 0; i<5; i++ )
		DELETEARRAY( m_Brush[i] );

	FILE *fptr = fopen( "ZDMapED.cfg", "wb" );
	if( fptr )
	{
		fwrite( &cfg, sizeof( cfg ), 1, fptr );
		fclose( fptr );
	}
}

BOOL CMapFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	if( !CMDIChildWnd::PreCreateWindow(cs) )
		return FALSE;

	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);


	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CMapFrame diagnostics

#ifdef _DEBUG
void CMapFrame::AssertValid() const
{
	CMDIChildWnd::AssertValid();
}

void CMapFrame::Dump(CDumpContext& dc) const
{
	CMDIChildWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMapFrame Misc functions

//NOTE:  alphabatize these functions so they can be found more easily

// Arranges all client windows in the MainWindow
void CMapFrame::SizeWindows()
{
	RECT rc;
	GetClientRect( &rc );

	// left windows
	int xsplit=rc.right*2/5;
	int ysplit=rc.bottom*3/5;

	m_TilesDlg->MoveWindow(0, 0, xsplit, ysplit, 0 );
	m_AnimDlg->MoveWindow(0, ysplit, xsplit, rc.bottom - ysplit, 0 );


	// right windows
	m_MapDlg->MoveWindow( xsplit, 0, rc.right - xsplit, rc.bottom, 0 );
}

void CMapFrame::UpdateMenu()
{
	CMenu *menu = GetParentFrame()->GetMenu();
	// Layer/Map Menu Items
	menu->EnableMenuItem( ID_FILE_NEW, (m_Tiles[m_SelLayer]) ? MF_ENABLED : MF_GRAYED );
	menu->EnableMenuItem( ID_FILE_SAVEMAP, (m_Map[0]) ? MF_ENABLED : MF_GRAYED );
	menu->EnableMenuItem( ID_LAYER_3, (m_Map[0]) ? MF_ENABLED : MF_GRAYED );
	menu->EnableMenuItem( ID_LAYER_LOAD, (m_Tiles[m_SelLayer]) ? MF_ENABLED : MF_GRAYED );
	
	// Brush Menu Items
	menu->EnableMenuItem( ID_DELBRUSH, (m_Brush[m_SelBrush]) ? MF_ENABLED : MF_GRAYED );
	menu->EnableMenuItem( ID_BRUSH_SAVE, (m_Brush[m_SelBrush]) ? MF_ENABLED : MF_GRAYED );
	menu->CheckMenuItem( 1100+m_SelBrush, MF_CHECKED );

	// Walkbits
	menu->EnableMenuItem( ID_WALKBITS_PAINT, (m_SelBit) ? MF_ENABLED : MF_GRAYED );
	menu->CheckMenuItem( 34000+m_SelBit, MF_CHECKED );
	menu->CheckMenuItem( ID_WALKBITS_PAINT, (m_PaintBit) ? MF_CHECKED : MF_UNCHECKED );
}

void CMapFrame::LoadCfg()
{
	FILE *fptr = fopen( "ZDMapED.cfg", "rb" );
	if( fptr )
	{	fseek( fptr, 0, SEEK_END );
		if( ftell( fptr ) != sizeof( cfg ) ) ResetCfg( );
		else
		{
			fseek( fptr, 0, SEEK_SET );
			fread( &cfg, sizeof( cfg ), 1, fptr );
		}
		fclose( fptr );
	}
	else ResetCfg( );
}

void CMapFrame::ResetCfg()
{
	cfg.m_ColorKey=FALSE;
	cfg.m_ColorKeyRGB=RGB(255,0,255);
	cfg.m_CaptionRGB=RGB(100,0,155);
	cfg.m_CaptionHalfRGB=RGB(50,0,77);
	cfg.m_DrawTrans=TRUE;
	cfg.m_XorTiles=FALSE;
	cfg.m_PlayAnim=FALSE;
	cfg.m_LeftLine=0;
	cfg.m_AllLayers=0;
}

void CMapFrame::PopUp( CWnd *wnd, int id, CPoint point )
{
	CMenu menu;
	CMenu *submenu;
	// load the menu
	menu.LoadMenu(id);
	// get the popup menu
	submenu = menu.GetSubMenu(0);
	// convert to screen coordinates
	wnd->ClientToScreen(&point);
	// post the menu
	submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
		                    point.x, point.y,
			                AfxGetApp()->m_pMainWnd,NULL);	
}

//Will create a map with tiles preset to Fill
//Dimensions of x*y and
void CMapFrame::CreateMap(CStringArray *TileSets, int Layers, int Height, int Width, int Fill)
{
	int i;

	// Delete old map and create new array
	DELETEARRAY( m_Map );
	m_Map = new CDXMap*[Layers];

	//Load the TileSets
	LoadTiles(TileSets);


	//Loop for each Layer
	for(i = 0; i < Layers; i++)
	{
		//truncate the path from the tileset list
		TileSets->SetAt(i, GetFile( TileSets->GetAt(i) ) );
		m_TileSet->SetAtGrow(i, (LPCTSTR) TileSets->GetAt(i));

		//Create new map
		Fill = min( Fill, m_Tiles[i]->m_BlockNum - 1 );
	
		if( i==0 )
		{
			SAFEDELETE( m_MapDlg->m_WalkBits );
			m_MapDlg->m_WalkBits = new int[Width * Height];
		}

		m_Map[i] = new CDXMap(m_Tiles[i], m_MapDlg->m_Screen);


		ZeroMemory( m_MapDlg->m_WalkBits, Width * Height );

		m_Map[i]->Create( Width, Height, Fill );
		m_Changed=TRUE;
	}

	// Set the Viewport of the map
	m_MapDlg->ReCalcScreen( );
	UpdateMenu();

}


//Map loading, what's it look like ;)
//I'll get to more in depth commenting l8r
BOOL CMapFrame::LoadMap( CString str)
{
	int i;
	sMapHeader MapHeader;
	CString path = GetPath(str);

	FILE *fptr = fopen( str, "rb" );
	
	if( fptr == NULL ) return FALSE;

	fseek( fptr, - (int) sizeof( MapHeader ), SEEK_END );
	fread( &MapHeader, sizeof( MapHeader ), 1, fptr );

	m_NumLayers = MapHeader.gfxLayers;

	
	//Create or clear Map array if needed
	if(m_Map)
	{
		for( i = 0; i < m_NumLayers; i++ )
			SAFEDELETE( m_Map[i] );
	}	
	else
	{
		m_Map = new CDXMap*[m_NumLayers];
		for(i = 0; i < m_NumLayers; i++)
			m_Map[i] = NULL;
	}


	//Create or clear Tile array if needed
	if(m_Tiles)
	{
		for( i = 0; i < m_NumLayers; i++ )
			SAFEDELETE( m_Tiles[i] );
	}
	else
	{
		m_Tiles = new CDXTile*[m_NumLayers];
		for(i = 0; i < m_NumLayers; i++)
			m_Tiles[i] = NULL;
	}

	
	if( strncmp( MapHeader.Id, "EXT", 3 ) )
	{
		if( m_Tiles[0] )
		{
			SAFEDELETE( m_Map[0] );
			m_Map[0] = new CDXMap(m_Tiles[0], m_MapDlg->m_Screen);
			fseek( fptr, 0, SEEK_SET );
			m_Map[0]->Load( fptr );
			m_Tiles[0]->LoadAnim( fptr );

			DELETEARRAY( m_MapDlg->m_WalkBits );
			m_MapDlg->m_WalkBits = new int[m_Map[0]->GetMapSize()];
			ZeroMemory( m_MapDlg->m_WalkBits, m_Map[0]->GetMapSize() );
		}
	}
	else
	{

		//Layer infor should be read one at a time..
		sLayerInfo *LayerInfo = new sLayerInfo[MapHeader.gfxLayers];
		fseek( fptr, - (int) (sizeof( MapHeader ) + MapHeader.gfxLayers * sizeof( sLayerInfo )), SEEK_END );
		for( i = 0; i < MapHeader.gfxLayers; i++)
			fread( &LayerInfo[i], sizeof( sLayerInfo ), 1, fptr );

		for( i=0; i<MapHeader.gfxLayers; i++ )
		{
			if( LayerInfo[i].offset != -1 )
			{
				if( LayerInfo[i].TileSet[0] )
				{
					m_Tiles[i] = new CDXTile();

					if(!m_Tiles[i]->Create( m_MapDlg->m_Screen, path + LayerInfo[i].TileSet, 32, 32, 0))
						return FALSE;

//					CString *str = new CString(LayerInfo[i].TileSet);
					m_TileSet->SetAtGrow( i, (LPCTSTR) LayerInfo[i].TileSet );
				}

				if( m_Tiles[i] )
				{
					m_Map[i] = new CDXMap(m_Tiles[i], m_MapDlg->m_Screen);
					fseek( fptr, LayerInfo[i].offset, SEEK_SET );

					if( !m_Map[i]->Load( fptr ) || !m_Tiles[i]->LoadAnim( fptr ))
						return FALSE;					
				}
			}
		}

		if( MapHeader.WalkBitsOffset > 0 )
		{
			fseek( fptr, MapHeader.WalkBitsOffset, SEEK_SET );

			DELETEARRAY( m_MapDlg->m_WalkBits );
			m_MapDlg->m_WalkBits = new int[m_Map[0]->GetMapSize()];
			fread( m_MapDlg->m_WalkBits, sizeof( int ), m_Map[0]->GetMapSize(), fptr );
		}
		DELETEARRAY( LayerInfo );
	}

	fclose( fptr );
	return TRUE;    
}

BOOL CMapFrame::SaveMap( CString *str )
{
	int i;

	sMapHeader MapHeader;
	ZeroMemory( &MapHeader, sizeof( MapHeader ) );
	memcpy( MapHeader.Id, "EXT", 3 );

	FILE *fptr = fopen( str->Left( str->GetLength() ), "wb" );
	if( fptr == NULL ) return FALSE;

	sLayerInfo *LayerInfo = new sLayerInfo[m_NumLayers];
	ZeroMemory( LayerInfo, sizeof( sLayerInfo ) * m_NumLayers );
	MapHeader.gfxLayers = m_NumLayers;
			
	for( i=0; i < m_NumLayers; i++ )
	{
		if( m_Map[i] )
		{	
			LayerInfo[i].offset = ftell( fptr );
			m_Map[i]->Save( fptr );
			m_Tiles[i]->SaveAnim( fptr );
		}
		else LayerInfo[i].offset = -1;

		strncpy( LayerInfo[i].TileSet, (LPCTSTR) m_TileSet->GetAt(i), 20 );
	}

	MapHeader.WalkBitsOffset = ftell( fptr );

	if(m_MapDlg->m_WalkBits)
		fwrite( m_MapDlg->m_WalkBits, sizeof(int), m_Map[0]->GetMapSize(), fptr );

	MapHeader.LayerInfoOffset = ftell( fptr );
	fwrite( LayerInfo, sizeof( sLayerInfo ), m_NumLayers, fptr );
	DELETEARRAY( LayerInfo );

	fwrite( &MapHeader, sizeof( MapHeader ), 1, fptr );
	fclose( fptr );

	return TRUE;
}

BOOL CMapFrame::LoadTiles(CStringArray *StrArray)
{
	int i;

	DELETEARRAY( m_Tiles );
	m_Tiles = new CDXTile*[StrArray->GetSize()];


	for(i = 0; i < StrArray->GetSize(); i++)
	{
		//The length is in here to prevent buffer overflow
		//Probably a cleaner way to do it though...
//		if( str && str.GetLength() < 21)
//		{
			m_Tiles[i] = new CDXTile();
			m_Tiles[i]->Create(m_TilesDlg->m_Screen, (LPCTSTR) StrArray->GetAt(i), 32, 32, 0);

			CDXTile *tiles = m_Tiles[i];

//			if( m_Map && m_Map[i] != NULL )
//				m_Map[i]->LoadTiles( tiles );


			SetScrollRange( SB_HORZ, 0, (tiles->m_BlockX) - m_TilesDlg->m_xTiles );
			SetScrollRange( SB_VERT, 0, (tiles->m_BlockY) - m_TilesDlg->m_yTiles );

			m_AnimDlg->SetScrollRange( SB_VERT, 0, (tiles->GetAnimCount( ) + 1) - m_AnimDlg->m_yTiles );

			if( cfg.m_ColorKey )
				tiles->SetColorKey( m_TilesDlg->m_Screen->MakeColor( cfg.m_ColorKeyRGB ) );
//		}
	}
		
	return TRUE;
//	}
}

CDXMap* CMapFrame::GetMap(int layer)
{
	if(m_NumLayers == 0 || layer < 0 || layer >= m_NumLayers)
		return NULL;
	return m_Map[layer];
}

CDXTile* CMapFrame::GetTiles(int layer)
{
	if(m_NumLayers == 0 || layer < 0 || layer >= m_NumLayers)
		return NULL;
	return m_Tiles[layer];
}

int* CMapFrame::GetBrush(int brushnum)
{
	if(brushnum >= 0 && brushnum < 5)
		return m_Brush[brushnum];
	return NULL;
}

int CMapFrame::GetBrushX(int brushnum)
{
	if(brushnum >= 0 && brushnum < 5)
		return m_BrushX[brushnum];
	return -1;
}

int CMapFrame::GetBrushY(int brushnum)
{
	if(brushnum >= 0 && brushnum < 5)
		return m_BrushY[brushnum];
	return -1;
}

void CMapFrame::SetBrush(int brushnum, int height, int width, int left, int top)
{
	DELETEARRAY( m_Brush[brushnum] );
	m_Brush[brushnum] = new int [width * height];
	m_BrushX[brushnum] = width;
	m_BrushY[brushnum] = height;
	
	for( int y = 0; y < height; y++ )
	{
		for( int x = 0; x < width; x++ )
		{
			m_Brush[brushnum][y * (width) + x] = (y + top) * (m_Tiles[m_SelLayer]->m_BlockX) + x + left;
		}
	}
	
	UpdateMenu();
}

/////////////////////////////////////////////////////////////////////////////
// CMapFrame message handlers
void CMapFrame::OnFileClose() 
{
	// To close the frame, just send a WM_CLOSE, which is the equivalent
	// choosing close from the system menu.

	SendMessage(WM_CLOSE);
}

int CMapFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	

	if(!m_TilesDlg){
		m_TilesDlg = new CTilesDlg( this );
		m_TilesDlg->Create(IDD_TILES, this);
	}

	if(!m_AnimDlg){
		m_AnimDlg = new CAnimDlg( this );
		m_AnimDlg->Create(IDD_ANIM, this);
	}

	if(!m_MapDlg){
		m_MapDlg = new CMapDlg( this );
		m_MapDlg->Create(IDD_MAPDLG, this);
	}

    // Create a timer to flip the pages
    SetTimer(TIMER_ID, TIMER_RATE, NULL);


	SizeWindows();

	return 0;
}

void CMapFrame::OnSetFocus(CWnd* pOldWnd) 
{
	CMDIChildWnd::OnSetFocus(pOldWnd);

	PostMessage(WM_PAINT);
}


void CMapFrame::OnSize(UINT nType, int cx, int cy) 
{
	CMDIChildWnd::OnSize(nType, cx, cy);
	
	SizeWindows();

	PostMessage(WM_PAINT);

}


void CMapFrame::OnPaint() 
{
	m_AnimDlg->PostMessage(WM_PAINT);
	m_MapDlg->PostMessage(WM_PAINT);
	m_TilesDlg->PostMessage(WM_PAINT);

	CMDIChildWnd::OnPaint();
}


UINT CMapFrame::ScrollBar(UINT nSBCode, UINT nPos, UINT nTHUMBPOS, UINT nPage )
{
	switch( nSBCode )
	{
		case SB_RIGHT:		nPos=65000;
							break;

		case SB_LINERIGHT:	nPos++;
							break;

		case SB_LINELEFT:	nPos--;
							break;

		case SB_THUMBTRACK:
		case SB_THUMBPOSITION:	nPos=nTHUMBPOS;
								break;

		case SB_PAGERIGHT:	nPos+=nPage;
							break;

		case SB_PAGELEFT:	nPos-=nPage;
							break;

		case SB_LEFT:		nPos=0;
							break;
	}

	return nPos;
}

void CMapFrame::OnFileOpenmap() 
{
	CString Filter = "Map Files (*.map)|*.map|All Files (*.*)|*.*||";
	CFileDialog FileDlg(TRUE, "*.map", NULL, OFN_FILEMUSTEXIST, Filter, NULL);

	FileDlg.m_ofn.lpstrTitle = "Open Map - File";
	if(FileDlg.DoModal() == IDOK)
	{	
		LoadMap( FileDlg.GetPathName( ) );
		m_Changed=FALSE;
		m_MapDlg->ReCalcScreen( );
		UpdateMenu( );
	}
}

void CMapFrame::OnAddtoanim() 
{
	int x = m_TilesDlg->m_MenuPoint.x/32 + m_TilesDlg->GetScrollPos( SB_HORZ );
	int y = m_TilesDlg->m_MenuPoint.y/32 + m_TilesDlg->GetScrollPos( SB_VERT );

	m_Changed=TRUE;
	m_AnimDlg->AddTile( y*(m_Tiles[m_SelLayer]->GetWidth()/32)+x );
}

void CMapFrame::OnAnimDel() 
{	
	CDXTile *tiles = m_Tiles[m_SelLayer];
	if( m_AnimDlg->m_Pos == 0 )
		tiles->DelAnim( m_AnimDlg->m_SelAnim );
	else
		tiles->RemoveTile( m_AnimDlg->m_SelAnim, m_AnimDlg->m_Pos-1 );

	m_Changed=TRUE;
	m_AnimDlg->SetScrollRange( SB_VERT, 0, (tiles->GetAnimCount( )+1)-m_AnimDlg->m_yTiles );
	m_AnimDlg->PostMessage(WM_PAINT);
}

void CMapFrame::OnAnimEdit() 
{
	CEditAnim dlg;

	CDX_ANIMSTRUCT *ptr = m_Tiles[m_SelLayer]->GetAnimData(m_AnimDlg->m_SelAnim);
	dlg.m_FrameRate = ptr->framerate;
	dlg.m_Delay = ptr->pause;
	dlg.m_Rand = ptr->rnd;
	dlg.m_PingPong = ptr->pingpong;
	if( dlg.DoModal() )
	{
		ptr->framerate = dlg.m_FrameRate;
		ptr->pause = dlg.m_Delay;
		ptr->rnd = dlg.m_Rand;
		ptr->pingpong = dlg.m_PingPong;
		m_Changed=TRUE;
	}
}

// Brush 1 selected
void CMapFrame::OnBrush1() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 1100+m_SelBrush, MF_UNCHECKED );
	m_SelBrush=0;
	UpdateMenu( );
}

// Brush 2 selected
void CMapFrame::OnBrush2() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 1100+m_SelBrush, MF_UNCHECKED );
	m_SelBrush=1;
	UpdateMenu( );
}

// Brush 3 selected
void CMapFrame::OnBrush3() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 1100+m_SelBrush, MF_UNCHECKED );
	m_SelBrush=2;
	UpdateMenu( );
}

// Brush 4 selected
void CMapFrame::OnBrush4() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 1100+m_SelBrush, MF_UNCHECKED );
	m_SelBrush=3;
	UpdateMenu( );
}

// Brush 5 selected
void CMapFrame::OnBrush5() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 1100+m_SelBrush, MF_UNCHECKED );
	m_SelBrush=4;
	UpdateMenu( );
}

void CMapFrame::OnBrushLoad() 
{
	CString Filter = "Brush Files (*.bsh)|*.bsh|All Files (*.*)|*.*||";
	CFileDialog FileDlg(TRUE, "*.bsh", NULL, OFN_FILEMUSTEXIST, Filter, NULL);

	FileDlg.m_ofn.lpstrTitle = "Open a Brush from Disk";

	if(FileDlg.DoModal() == IDOK)
    {
		int Sel = m_SelBrush;
		SAFEDELETE( m_Brush[Sel] );
		
		CFile fptr( FileDlg.GetPathName( ), CFile::modeRead );
		fptr.Read( &m_BrushX[Sel], sizeof( int ) );
		fptr.Read( &m_BrushY[Sel], sizeof( int ) );
		
		m_Brush[Sel] = new int [m_BrushX[Sel]*m_BrushY[Sel]];
		fptr.Read( m_Brush[Sel], sizeof( int )*m_BrushX[Sel]*m_BrushY[Sel] );
		fptr.Close( );
	}
	
	UpdateMenu( );
}

void CMapFrame::OnBrushSave() 
{
	if( m_Brush[m_SelBrush] )
	{
		CString Filter = "Brush Files (*.bsh)|*.bsh|All Files (*.*)|*.*||";
		CFileDialog FileDlg(FALSE, "*.bsh", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, Filter, NULL);

		FileDlg.m_ofn.lpstrTitle = "Save Brush to File";
		if(FileDlg.DoModal() == IDOK)
		{
			int sel = m_SelBrush;
			CFile fptr( FileDlg.GetPathName( ), CFile::modeCreate | CFile::modeWrite );
			fptr.Write( &m_BrushX[sel], sizeof( int ) );
			fptr.Write( &m_BrushY[sel], sizeof( int ) );
			fptr.Write( &m_Brush[sel], sizeof( int )*m_BrushX[sel]*m_BrushY[sel] );
			fptr.Close( );
		}
	}
	
}

void CMapFrame::OnDelbrush() 
{
	int Sel = m_SelBrush;
	SAFEDELETE( m_Brush[Sel] );
		
	m_BrushX[Sel]=0;
	m_BrushY[Sel]=0;
	UpdateMenu( );
}

// File->Save (Clicked)
void CMapFrame::OnFileSavemap() 
{

	CDXMap *map = m_Map[m_SelLayer];
	if( map )
	{
		CString Filter = "Map Files (*.map)|*.map|All Files (*.*)|*.*||";
		CFileDialog FileDlg(FALSE, "*.map", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, Filter, NULL);

		FileDlg.m_ofn.lpstrTitle = "Save Map - File";
		if(FileDlg.DoModal() == IDOK)
		{	
			SaveMap( &FileDlg.GetPathName() );
			m_Changed=FALSE;
		}
	}
}

void CMapFrame::OnLayer1() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( ID_LAYER_3, MF_UNCHECKED );
	m_SelLayer = 0;
	GetParentFrame()->GetMenu()->CheckMenuItem( ID_LAYER_1, MF_CHECKED );

	PostMessage(WM_PAINT);

	UpdateMenu( );
}

void CMapFrame::OnLayer3() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( ID_LAYER_1, MF_UNCHECKED );
	m_SelLayer = 1;
	GetParentFrame()->GetMenu()->CheckMenuItem( ID_LAYER_3, MF_CHECKED );

	PostMessage(WM_PAINT);

	UpdateMenu( );
}

void CMapFrame::OnLayerLoad() 
{
	int sel = m_SelLayer;
	CDXTile *tiles = m_Tiles[sel];
	if( tiles )
	{
		CString Filter = "Map Files (*.map)|*.map|All Files (*.*)|*.*||";
		CFileDialog FileDlg(TRUE, "*.map", NULL, OFN_FILEMUSTEXIST, Filter, NULL);

		FileDlg.m_ofn.lpstrTitle = "Open Map-File as a Layer";
		if(FileDlg.DoModal() == IDOK)
		{	
			// Delete old map and create/load the new map
			SAFEDELETE( m_Map[sel] );
			m_Map[sel] = new CDXMap(m_Tiles[sel], m_MapDlg->m_Screen);
			m_Map[sel]->Load( FileDlg.GetPathName( ) );

			if( sel==0 )
			{
				DELETEARRAY( m_MapDlg->m_WalkBits );
				m_MapDlg->m_WalkBits = new int[m_Map[0]->GetMapSize()];
				ZeroMemory( m_MapDlg->m_WalkBits, m_Map[0]->GetMapSize() );
			}

			// Set the Viewport of the map
			m_MapDlg->ReCalcScreen( );
			UpdateMenu( );
		}
	}	
}

void CMapFrame::OnSelbit1() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 1;
	UpdateMenu( );
}

void CMapFrame::OnSelbit2() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 2;
	UpdateMenu( );
}

void CMapFrame::OnSelbit3() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 3;
	UpdateMenu( );
}

void CMapFrame::OnSelbit4() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 4;
	UpdateMenu( );
}

void CMapFrame::OnSelbit5() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 5;
	UpdateMenu( );
}

void CMapFrame::OnSelbit6() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 6;
	UpdateMenu( );
}

void CMapFrame::OnSelblock() 
{
	m_MapDlg->m_BKeyDown = TRUE;
	m_MapDlg->m_BlockX1 = m_MapDlg->m_BlockX2 = m_MapDlg->m_MouseTile.x;
	m_MapDlg->m_BlockY1 = m_MapDlg->m_BlockY2 = m_MapDlg->m_MouseTile.y;
	if( cfg.m_PlayAnim==FALSE )
		m_MapDlg->RedrawWindow( NULL, NULL, RDW_INTERNALPAINT );
}

void CMapFrame::OnSelnobit() 
{
	GetParentFrame()->GetMenu()->CheckMenuItem( 34000+m_SelBit, MF_UNCHECKED );
	m_SelBit = 0;
	m_PaintBit=FALSE;
	UpdateMenu( );
}

// Tiles->Open (Clicked)
void CMapFrame::OnTilesOpen() 
{
	CString Filter = "Bmp Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";
	CFileDialog FileDlg(TRUE, "*.bmp", NULL, OFN_FILEMUSTEXIST, Filter, NULL);

	FileDlg.m_ofn.lpstrTitle = "Open the Tile File";
	if(FileDlg.DoModal() == IDOK)
    {
//		LoadTiles( FileDlg.GetPathName( ) );
	}

	UpdateMenu( );
	PostMessage(WM_PAINT);

}

// Tools->Options (Clicked)
void CMapFrame::OnToolsOptions() 
{
	Options dlg;
	dlg.m_ColorKey = cfg.m_ColorKey;
	dlg.m_DrawTrans = cfg.m_DrawTrans;
	dlg.m_XorTiles = cfg.m_XorTiles;
	dlg.m_PlayAnim = cfg.m_PlayAnim;
	dlg.m_LayerAll = cfg.m_AllLayers;

	dlg.m_RED  = (BYTE)((cfg.m_ColorKeyRGB)%256);
	dlg.m_BLUE = (BYTE)(cfg.m_ColorKeyRGB>>8>>8);
	dlg.m_GREEN= (BYTE)((cfg.m_ColorKeyRGB>>8)%256);

	dlg.m_RED2  = (BYTE)((cfg.m_CaptionRGB)%256);
	dlg.m_BLUE2 = (BYTE)(cfg.m_CaptionRGB>>8>>8);
	dlg.m_GREEN2= (BYTE)((cfg.m_CaptionRGB>>8)%256);

	if( dlg.DoModal( ) )
	{
		cfg.m_ColorKey = dlg.m_ColorKey;
		cfg.m_ColorKeyRGB = RGB( dlg.m_RED, dlg.m_GREEN, dlg.m_BLUE );
		cfg.m_CaptionRGB = RGB( dlg.m_RED2, dlg.m_GREEN2, dlg.m_BLUE2 );
		cfg.m_CaptionHalfRGB = RGB( dlg.m_RED2/2, dlg.m_GREEN2/2, dlg.m_BLUE2/2 );

		CDXTile *tiles = m_Tiles[1];
		if( tiles )
		{
			tiles->SetColorKey( m_TilesDlg->m_Screen->MakeColor( cfg.m_ColorKeyRGB ) );

			PostMessage(WM_PAINT);
		}

		cfg.m_DrawTrans = dlg.m_DrawTrans;
		cfg.m_XorTiles = dlg.m_XorTiles;
		cfg.m_PlayAnim = dlg.m_PlayAnim;
		cfg.m_AllLayers = dlg.m_LayerAll;
	}
}

// Tools->Undo (Clicked)
void CMapFrame::OnToolsUndo() 
{
	CDXMap *map = m_Map[m_SelLayer];
	if( m_Undo.GetSize()>0 )
	{
		for( int i=m_Undo.GetSize()-1; i>=0; i-- )
		{
			int x = m_Undo[i].x, y = m_Undo[i].y,
             tile = map->GetTile( x, y );

			map->SetTile( x, y, m_Undo[i].Tile );
			m_Undo[i].Tile = tile;
		}

		m_StoreUndo = FALSE;
		if( cfg.m_PlayAnim==FALSE )
			m_MapDlg->RedrawWindow( NULL, NULL, RDW_INTERNALPAINT );
	}
}

// Walkbits conversation
void CMapFrame::OnWalkbits1() 
{	m_MapDlg->ChangeBit( 0 );	}

void CMapFrame::OnWalkbits2() 
{	m_MapDlg->ChangeBit( 1 );	}

void CMapFrame::OnWalkbits3() 
{	m_MapDlg->ChangeBit( 2 );	}

void CMapFrame::OnWalkbits4() 
{	m_MapDlg->ChangeBit( 3 );	}

void CMapFrame::OnWalkbits5() 
{	m_MapDlg->ChangeBit( 4 );	}

void CMapFrame::OnWalkbits6() 
{	m_MapDlg->ChangeBit( 5 );	}

void CMapFrame::OnWalkbitsPaint() 
{
	m_PaintBit=!m_PaintBit;
	UpdateMenu( );
}

void CMapFrame::OnTimer(UINT nIDEvent) 
{
//	if(cfg.m_PlayAnim == TRUE)
//	{
//		for( int i = 0; i < 2; i++)
//			if(m_Tiles[i])
//				m_Tiles[i]->NextFrame();
//
//		PostMessage(WM_PAINT);
//	}
	
	CMDIChildWnd::OnTimer(nIDEvent);
}

void CMapFrame::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CMDIChildWnd::OnMouseMove(nFlags, point);
}
