//
//  wincnc.h - wincnc main implementation
//
//  $Id: wincnc.cpp 52 2014-02-07 19:31:45Z brian $ 
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#include "stdafx.h"

CString UnitsName[2];

BEGIN_MESSAGE_MAP(WinCncApp, CWinApp)
	ON_COMMAND(ID_FILE_NEW,						CWinApp::OnFileNew)
	ON_COMMAND(ID_FILE_OPEN,					CWinApp::OnFileOpen)
	ON_COMMAND(ID_FILE_PRINT_SETUP,				CWinApp::OnFilePrintSetup)

	ON_COMMAND(ID_SETUP_GENERAL,				WinCncApp::OnSetupGeneral)
	ON_COMMAND(ID_SETUP_AXES,					WinCncApp::OnSetupAxes)
	ON_COMMAND(ID_SETUP_CUTTER,					WinCncApp::OnSetupCutter)
	ON_COMMAND(ID_SETUP_FEED,					WinCncApp::OnSetupFeed)
	ON_COMMAND(ID_SETUP_HOMING,					WinCncApp::OnSetupHoming)
	ON_COMMAND(ID_SETUP_JOGGING,				WinCncApp::OnSetupJogging)
	ON_COMMAND(ID_SETUP_LIMITS,					WinCncApp::OnSetupLimits)
	ON_COMMAND(ID_SETUP_MACHINE_COORDINATES,	WinCncApp::OnSetupMachineCoordinates)
	ON_COMMAND(ID_SETUP_RAPID,					WinCncApp::OnSetupRapid)
	ON_COMMAND(ID_SETUP_SPINDLE,				WinCncApp::OnSetupSpindle)
	ON_COMMAND(ID_SETUP_TOOLS,					WinCncApp::OnSetupTools)
	ON_COMMAND(ID_SETUP_WORK_COORDINATES,		WinCncApp::OnSetupWorkCoordinates)
	ON_COMMAND(ID_SETUP_SAVE,					WinCncApp::OnSetupSave)
	ON_COMMAND(ID_SETUP_SAVE_AS,				WinCncApp::OnSetupSaveAs)

	ON_COMMAND(ID_VIEW_CURRENT,					WinCncApp::OnViewCurrent)
	ON_UPDATE_COMMAND_UI(ID_VIEW_CURRENT,		WinCncApp::OnUpdateViewCurrent)
	ON_COMMAND(ID_VIEW_OPTIMAL,					WinCncApp::OnViewOptimal)
	ON_UPDATE_COMMAND_UI(ID_VIEW_OPTIMAL,		WinCncApp::OnUpdateViewOptimal)
	ON_COMMAND(ID_VIEW_STATUS,					WinCncApp::OnViewStatus)
	ON_UPDATE_COMMAND_UI(ID_VIEW_STATUS,		WinCncApp::OnUpdateViewStatus)
	ON_COMMAND(ID_VIEW_PROGRAM,					WinCncApp::OnViewProgram)
	ON_UPDATE_COMMAND_UI(ID_VIEW_PROGRAM,		WinCncApp::OnUpdateViewProgram)
	ON_COMMAND(ID_VIEW_MESSAGES,				WinCncApp::OnViewMessages)
	ON_UPDATE_COMMAND_UI(ID_VIEW_MESSAGES,		WinCncApp::OnUpdateViewMessages)

	ON_COMMAND(ID_APP_ABOUT,					WinCncApp::OnAppAbout)

	ON_COMMAND(ID_CALIBRATE_JOYSTICK, OnCalibrateJoystick)
	ON_UPDATE_COMMAND_UI(ID_CALIBRATE_JOYSTICK, OnUpdateCalibrateJoystick)
	ON_COMMAND(ID_MODE_RUN, OnModeRun)
	ON_UPDATE_COMMAND_UI(ID_MODE_RUN, OnUpdateModeRun)
	ON_COMMAND(ID_MODE_MDI, OnModeMdi)
	ON_UPDATE_COMMAND_UI(ID_MODE_MDI, OnUpdateModeMdi)
	ON_COMMAND(ID_MODE_JOG, OnModeJog)
	ON_UPDATE_COMMAND_UI(ID_MODE_JOG, OnUpdateModeJog)
	ON_COMMAND(ID_OPTIONS_DRYRUN, OnOptionsDryrun)
	ON_UPDATE_COMMAND_UI(ID_OPTIONS_DRYRUN, OnUpdateOptionsDryrun)
	ON_COMMAND(ID_OPTIONS_BLOCKSKIP, OnOptionsBlockskip)
	ON_UPDATE_COMMAND_UI(ID_OPTIONS_BLOCKSKIP, OnUpdateOptionsBlockskip)
	ON_COMMAND(ID_FILE_RESTART, OnFileRestart)
	ON_COMMAND(ID_MODE_HOME, OnModeHome)
	ON_UPDATE_COMMAND_UI(ID_MODE_HOME, OnUpdateModeHome)
	ON_COMMAND(ID_SETUP_PROGRAM_COORDINATES, OnSetupProgramCoordinates)
	ON_COMMAND(ID_SETUP_EXTERNAL_CONTROLS, OnSetupExternalControls)
	ON_COMMAND(ID_SETUP_OFFSETS, OnSetupOffsets)
END_MESSAGE_MAP()

WinCncApp::WinCncApp()
	: m_control_panel(NULL), m_homing_display_template(NULL), m_machine(NULL), m_mdi_panel_template(NULL), 
	  m_output_on_idle(false), m_output_display_template(NULL), m_status_display_template(NULL) 
{
}

WinCncApp theApp;

BOOL WinCncApp::InitInstance()
{
	// Initialize units management data
	InitDimUnits();
	InitPerUnits();
	UnitsName[ENGLISH] = ENGLISH_UNITS_TITLE;
	UnitsName[METRIC] = METRIC_UNITS_TITLE;
	
	SetDialogBkColor();        // Set dialog background color to gray
	LoadStdProfileSettings();  // Load standard INI file options (including MRU)

	//  Load the MCAPI library (dynamic link)
	if (MCLoadApi() != MCERR_NOERROR) 
	{
		std::ostringstream message;
		message << "This application requires version " 
				<< _MCAPI_VER / 100 << (_MCAPI_VER % 100) / 10 << _MCAPI_VER % 10
				<< "\nor later of the Motion Control API!";
		MessageBox(NULL, message.str().c_str(), "Win CNC", MB_ICONSTOP | MB_OK);
		return false;
	}

	if (MCLoadDialogs() != MCERR_NOERROR) 
	{
		std::ostringstream message;
		message << "This application requires version "
				<< _MCDLG_VER / 100 << (_MCDLG_VER % 100) / 10 << _MCDLG_VER % 10
				<< "\nor later of the Motion Control Dialogs!";
		MessageBox(NULL, message.str().c_str(), "Win CNC", MB_ICONSTOP | MB_OK);
		return false;
	}

	// Register the application's document templates.  Document templates serve as the connection 
	// between documents, frame windows and views.

	// Note that the IDR_MACHTYPE resource strings for the Machine Document Templates do not specify 
	// a file extension. This prevents additional CMachine Documents from being opened from a File 
	// Open dialog. If a file with an extension that is not specified in one of the templates is 
	// opened, the Framework will open a document of the first registerd template type. Since any 
	// file opened is assumed to be a part program (or at least a text file), we want to open it 
	// using the Part Template. For this reason the Part Template must be registered first.
	CMultiDocTemplate* pPartTemplate;
	pPartTemplate = new CMultiDocTemplate(
		IDR_PARTTYPE,
		RUNTIME_CLASS(CPart),
		RUNTIME_CLASS(CMDIChildWnd),
		RUNTIME_CLASS(CPartView));
	AddDocTemplate(pPartTemplate);

	CMultiDocTemplate* pMachineTemplate;
	pMachineTemplate = new CMultiDocTemplate(
		IDR_MACHTYPE,
		RUNTIME_CLASS(CMachine),
		RUNTIME_CLASS(CMDIChildWnd),        // standard MDI child frame
		RUNTIME_CLASS(CMachineView));		// CView with no visble window
	AddDocTemplate(pMachineTemplate);

	m_status_display_template = new CMultiDocTemplate(
		IDR_MACHTYPE,
		RUNTIME_CLASS(CMachine),
		RUNTIME_CLASS(CMDIChildWnd),
		RUNTIME_CLASS(CStatusDisplay));
	AddDocTemplate(m_status_display_template);

	m_output_display_template = new CMultiDocTemplate(
		IDR_MACHTYPE,
		RUNTIME_CLASS(CMachine),
		RUNTIME_CLASS(CMDIChildWnd),
		RUNTIME_CLASS(COutputDisplay));
	AddDocTemplate(m_output_display_template);

	m_mdi_panel_template = new CMultiDocTemplate(
		IDR_MACHTYPE,
		RUNTIME_CLASS(CMachine),
		RUNTIME_CLASS(CMDIChildWnd),
		RUNTIME_CLASS(CMDIPanel));
	AddDocTemplate(m_mdi_panel_template);

	m_homing_display_template = new CMultiDocTemplate(
		IDR_MACHTYPE,
		RUNTIME_CLASS(CMachine),
		RUNTIME_CLASS(CMDIChildWnd),
		RUNTIME_CLASS(HomingView));
	AddDocTemplate(m_homing_display_template);

	// create main MDI Frame window
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
		return FALSE;
	m_pMainWnd = pMainFrame;

	// enable file manager drag/drop and DDE Execute open
	EnableShellOpen();
	RegisterShellFileTypes();

	if (m_lpCmdLine[0] == '\0')
		pMachineTemplate->OpenDocumentFile(NULL, MAKE_VIEW_INVISIBLE);			// create a new machine with default settings
	else
		pMachineTemplate->OpenDocumentFile(m_lpCmdLine, MAKE_VIEW_INVISIBLE);	// open an existing machine file
	
	m_pMainWnd->DragAcceptFiles();

	// The main window has been initialized, so show and update it.
	pMainFrame->ShowWindow(m_nCmdShow);
	pMainFrame->UpdateWindow();

	pMainFrame->InitialUpdate();

	// Start in homing mode
	if (m_machine)
		m_machine->ModeHome();
	
	return TRUE;
}

// Use this to delete CMachine object if it is static
BOOL WinCncApp::ExitInstance()
{
	return(CWinApp::ExitInstance());
}

BOOL WinCncApp::OnIdle(LONG lCount)
{
	char sLineBuf[PARTMAXLINELENGTH];
	
	bool more = CWinApp::OnIdle(lCount) != 0;
	
	if (OutputOnIdle() && m_machine)
	{
		sLineBuf[0] = static_cast<char>(m_machine->MtnCtrlr.GetC());
		if (sLineBuf[0] != 0)
		{
			// Retieve rest of string from motion controller and pass it to machine object for display
			m_machine->MtnCtrlr.GetS(&sLineBuf[1], sizeof(sLineBuf) - 1);
			m_machine->OutputText(sLineBuf);
			more = TRUE;			// Set flag so that OnIdle continues to be called
		}
		else
		{
			// No message ready from motion controller, clear flag so that idle processing is 
			// not done until next message
			OutputOnIdle(false);
		}
	}
	
	return more;
}

void WinCncApp::OnAppAbout(void)
{
	MCDLG_AboutBox(NULL, "Win CNC", 0);
}

void WinCncApp::OnFileRestart(void)
{
	theApp.GetMachine()->FileRestart();
}

void WinCncApp::OnViewCurrent(void)
{
	theApp.GetMachine()->ViewCurrent();
}

void WinCncApp::OnUpdateViewCurrent(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateViewCurrent(pCmdUI);
}

void WinCncApp::OnViewOptimal(void)
{
	theApp.GetMachine()->ViewOptimal();
}

void WinCncApp::OnUpdateViewOptimal(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateViewOptimal(pCmdUI);
}

void WinCncApp::OnViewStatus(void)
{
	theApp.GetMachine()->ViewStatus();
}

void WinCncApp::OnUpdateViewStatus(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateViewStatus(pCmdUI);
}

void WinCncApp::OnViewProgram(void)
{
	theApp.GetMachine()->ViewProgram();
}

void WinCncApp::OnUpdateViewProgram(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateViewProgram(pCmdUI);
}

void WinCncApp::OnViewMessages(void)
{
	theApp.GetMachine()->ViewMessages();
}

void WinCncApp::OnUpdateViewMessages(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateViewMessages(pCmdUI);
}

void WinCncApp::OnSetupGeneral(void)
{
	theApp.GetMachine()->SetupGeneral();
}

void WinCncApp::OnSetupAxes(void)
{
	theApp.GetMachine()->SetupAxes();
}

void WinCncApp::OnSetupCutter(void)
{
	theApp.GetMachine()->SetupCutter();
}

void WinCncApp::OnSetupFeed(void)
{
	theApp.GetMachine()->SetupFeed();
}

void WinCncApp::OnSetupLimits(void)
{
	theApp.GetMachine()->SetupLimits();
}

void WinCncApp::OnSetupMachineCoordinates(void)
{
	theApp.GetMachine()->SetupMachineCoordinates();
}

void WinCncApp::OnSetupProgramCoordinates(void)
{
	theApp.GetMachine()->SetupProgramCoordinates();
}

void WinCncApp::OnSetupRapid(void)
{
	theApp.GetMachine()->SetupRapid();
}

void WinCncApp::OnSetupSpindle(void)
{
	theApp.GetMachine()->SetupSpindle();
}

void WinCncApp::OnSetupTools(void)
{
	theApp.GetMachine()->SetupTools();
}

void WinCncApp::OnSetupOffsets(void)
{
	theApp.GetMachine()->SetupOffsets();
}

void WinCncApp::OnSetupWorkCoordinates(void)
{
	theApp.GetMachine()->SetupWorkCoordinates();
}

void WinCncApp::OnSetupJogging(void)
{
	theApp.GetMachine()->SetupJogging();
}

void WinCncApp::OnSetupHoming(void)
{
	theApp.GetMachine()->SetupHoming();
}

void WinCncApp::OnSetupExternalControls(void)
{
	theApp.GetMachine()->SetupExternalControls();
}

void WinCncApp::OnSetupSave(void)
{
	theApp.GetMachine()->SetupSave();
}

void WinCncApp::OnSetupSaveAs(void)
{
	theApp.GetMachine()->SetupSaveAs();
}

void WinCncApp::OnCalibrateJoystick(void)
{
	theApp.GetMachine()->CalibrateJoystick();
}

void WinCncApp::OnUpdateCalibrateJoystick(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateCalibrateJoystick(pCmdUI);
}

void WinCncApp::OnModeRun(void)
{
	theApp.GetMachine()->ModeRun();
}

void WinCncApp::OnUpdateModeRun(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateModeRun(pCmdUI);
}

void WinCncApp::OnModeMdi(void)
{
	theApp.GetMachine()->ModeMdi();
}

void WinCncApp::OnUpdateModeMdi(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateModeMdi(pCmdUI);
}

void WinCncApp::OnModeJog(void)
{
	theApp.GetMachine()->ModeJog();
}

void WinCncApp::OnUpdateModeJog(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateModeJog(pCmdUI);
}

void WinCncApp::OnModeHome(void)
{
	theApp.GetMachine()->ModeHome();
}

void WinCncApp::OnUpdateModeHome(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateModeHome(pCmdUI);
}

void WinCncApp::OnOptionsBlockskip(void)
{
	theApp.GetMachine()->OptionsBlockskip();
}

void WinCncApp::OnUpdateOptionsBlockskip(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateOptionsBlockskip(pCmdUI);
}

void WinCncApp::OnOptionsDryrun(void)
{
	theApp.GetMachine()->OptionsDryrun();
}

void WinCncApp::OnUpdateOptionsDryrun(CCmdUI* pCmdUI)
{
	theApp.GetMachine()->UpdateOptionsDryrun(pCmdUI);
}
