/*
Copyright (c) 1998 Richard Lawrence

This program is free software; you can redistribute it and/or modify it under the terms 
of the GNU General Public License as published by the Free Software Foundation; either 
version 2 of the License, or (at your option) any later version. This program is 
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details. You should have received a copy of the GNU
General Public License along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

// Atari800Win.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include <mmsystem.h>
#include "Atari800Win.h"
#include "MainFrm.h"
#include "Atari800WinDoc.h"
#include "Atari800WinView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern "C" {
#include "graphics.h"
extern HWND				hWnd, MainhWnd;
extern ULONG	ulMiscStates;
extern ULONG	ulAtariState;
extern ULONG	ulScreenMode;
extern ULONG	ulAtariState;
extern void		WinAtari800_Hardware( void );
extern ULONG	ulAtari_HW_Nexttime;
extern int	default_tv_mode;
extern char szSystemText[];
extern LARGE_INTEGER	lnTimeFreq;
extern ULONG ulDeltaT;
}

extern CWnd  *statusWnd;
extern int	argc;
extern char	*argv[];
extern char	szCmdLine[];

static long nHWLoopCounter=0;
static	int	nCmdIndex;
static unsigned long ulStartMeasure;
/////////////////////////////////////////////////////////////////////////////
// CAtari800WinApp

BEGIN_MESSAGE_MAP(CAtari800WinApp, CWinApp)
	//{{AFX_MSG_MAP(CAtari800WinApp)
	ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard file based document commands
	ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
	// Standard print setup command
	ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

void CAtari800WinCommandLineInfo::ParseParam(const char* pszParam,BOOL bFlag,BOOL bLast)
{
	if( bFlag )
	{
		argv[argc] = &szCmdLine[ nCmdIndex ];
		argc++;
		szCmdLine[ nCmdIndex++ ] = '-';
		strcpy( &szCmdLine[ nCmdIndex ], pszParam );
		nCmdIndex += strlen( &szCmdLine[nCmdIndex] ) + 1;
	}
	else
	{
		argv[argc] = &szCmdLine[ nCmdIndex ];
		argc++;
		strcpy( &szCmdLine[ nCmdIndex ], pszParam );
		nCmdIndex += strlen( &szCmdLine[nCmdIndex] ) + 1;
	}
//	CCommandLineInfo::ParseParam(pszParam, bFlag, bLast);
}

/////////////////////////////////////////////////////////////////////////////
// CAtari800WinApp construction

CAtari800WinApp::CAtari800WinApp()
{
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CAtari800WinApp object

CAtari800WinApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CAtari800WinApp initialization

BOOL CAtari800WinApp::InitInstance()
{
	char	szDir[ MAX_PATH ];

	// Standard initialization
	// If you are not using these features and wish to reduce the size
	//  of your final executable, you should remove from the following
	//  the specific initialization routines you do not need.

#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

	// Change the registry key under which our settings are stored.
	// You should modify this string to be something appropriate
	// such as the name of your company or organization.
	//SetRegistryKey(_T("HKEY_CURRENT_USER\\Software\\Atari800Win"));

	//LoadStdProfileSettings();  // Load standard INI file options (including MRU)

	// Register the application's document templates.  Document templates
	//  serve as the connection between documents, frame windows and views.

	CSingleDocTemplate* pDocTemplate;
	pDocTemplate = new CSingleDocTemplate(
		IDR_MAINFRAME,
		RUNTIME_CLASS(CAtari800WinDoc),
		RUNTIME_CLASS(CMainFrame),       // main SDI frame window
		RUNTIME_CLASS(CAtari800WinView));
	AddDocTemplate(pDocTemplate);

	argc = 1;
	argv[0] = &szCmdLine[0];
	strcpy( szCmdLine, this->m_pszAppName );
	nCmdIndex = strlen( szCmdLine ) + 1;

	// Parse command line for standard shell commands, DDE, file open
	CAtari800WinCommandLineInfo cmdInfo;
	ParseCommandLine(cmdInfo);

	// Dispatch commands specified on the command line
	if (!ProcessShellCommand(cmdInfo))
		return FALSE;

	// The one and only window has been initialized, so show and update it.
	m_pMainWnd->ShowWindow(SW_SHOW);
	m_pMainWnd->UpdateWindow();

	ulStartMeasure = timeGetTime();

	// For a variety of reasons it's better to set the current working directory
	// to where Atari800Win (the executable) is located.
	memset( szDir, 0, MAX_PATH );
	GetModuleFileName( NULL, szDir, MAX_PATH );
	if( strlen( szDir ) )
	{
		unsigned int	i=strlen( szDir );

		while( i && szDir[i]!='\\' )
			i--;
		if( i )
			szDir[i] = 0;
		SetCurrentDirectory( szDir );
	}

	return TRUE;
}

int CAtari800WinApp::ExitInstance() 
{
	
	return CWinApp::ExitInstance();
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BOOL CAboutDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	char	message[LOADSTRING_STRING_SIZE];
	
	LoadString( NULL, IDS_COPYRIGHT, message, LOADSTRING_STRING_SIZE );
	SetDlgItemText( IDC_COPYRIGHT, message );
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CAtari800WinApp::OnAppAbout()
{
	CAboutDlg aboutDlg;
	aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CAtari800WinApp commands

BOOL CAtari800WinApp::OnIdle(LONG lCount) 
{
	//Full time for PAL would be 1280ms, for NTSC 1067ms
	const unsigned long ulTimes[3] = { 0, 2560, 2134 };

	if( !(ulAtariState & (ATARI_PAUSED | ATARI_UI_ACTIVE | ATARI_NOFOCUS)) )
	{
		if( ++nHWLoopCounter == 128 )
		{
			unsigned long ulTotalTime = timeGetTime() - ulStartMeasure;
			unsigned long speed;
			char	cspeed[128];
			
			if( ulTotalTime == 0 )
				ulTotalTime = 1;

			speed = ulTimes[default_tv_mode] * 100 / ulTotalTime + 5;
			if( !(ulMiscStates & ATARI_FULL_SPEED) && speed > 100 )
				speed = 100;

			sprintf( cspeed, "Speed: %d%% ", speed);
			if( ulScreenMode & DDRAW_FULL )
				strcat( cspeed, szSystemText );

			if( !(ulScreenMode & DDRAW_NO_MENU_MODE ) )
				statusWnd->SetWindowText( cspeed );

			ulStartMeasure = timeGetTime();
			nHWLoopCounter = 0;
		}

		if( ulAtariState & ATARI_RUNNING )
			WinAtari800_Hardware();
		return TRUE;
	}

	return FALSE;
}


