//
//  machine.h - machine class header file
//
//  $Id: machine.h 53 2014-02-07 19:39:59Z brian $ 
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#ifndef MACHINE_H
#define MACHINE_H

// Machine types
#define MAX_MACHINE_TYPES	3		// Number of machine types
#define VMILL	0					// Vertical Mill
#define HMILL	1					// Horizontal Mill
#define LATHE	2					// Lathe

// Machine types used in setup dialog
#define VMILL_NAME	"Mill, Vertical"
#define HMILL_NAME	"Mill, Horizontal"
#define LATHE_NAME	"Lathe"

// Machine type names recognized by motion controller
#define VMILL_SPECIFIER	"VMILL"
#define HMILL_SPECIFIER	"HMILL"
#define LATHE_SPECIFIER	"LATHE"

// Part program styles
#define MAX_PROGRAM_STYLES	2		// Number of program styles
#define FANUC	0
#define AMTICO	1

// Program styles used in setup dialog
#define FANUC_NAME	"Fanuc"
#define AMTICO_NAME	"Amtico"

// Program style names recognized by motion controller
#define FANUC_SPECIFIER		"FANUC"
#define AMTICO_SPECIFIER	"AMTICO"

// Position readout modes
#define SHOW_CURRENT		1
#define SHOW_OPTIMAL		2

// Part program view modes
#define DISPLAY_PROGRAM		1
#define DISPLAY_MESSAGES	2

// Operation modes
#define RUN_MODE	1
#define MDI_MODE	2
#define JOG_MODE	3
#define HOME_MODE	4

#define MAXMACHINEAXES 10

#define DEFAULT_X_CTRLR_AXIS 1
#define DEFAULT_Y_CTRLR_AXIS 2
#define DEFAULT_Z_CTRLR_AXIS 0
#define DEFAULT_U_CTRLR_AXIS 0
#define DEFAULT_V_CTRLR_AXIS 0
#define DEFAULT_W_CTRLR_AXIS 0
#define DEFAULT_S_CTRLR_AXIS 0
#define DEFAULT_C_CTRLR_AXIS 0

// Axis ID's (so a Axis object can identify itself)
#define XAXIS 1
#define YAXIS 2
#define ZAXIS 3
#define UAXIS 4
#define VAXIS 5
#define WAXIS 6

// Jogging states
#define JOG_ALL_STATES			0xFFFF
#define JOG_XPLUS_ACTIVE		0x0010
#define JOG_XPLUS_STOPPING		0x0020
#define JOG_XMINUS_ACTIVE		0x0040
#define JOG_XMINUS_STOPPING	0x0080
#define JOG_YPLUS_ACTIVE		0x0100
#define JOG_YPLUS_STOPPING		0x0200
#define JOG_YMINUS_ACTIVE		0x0400
#define JOG_YMINUS_STOPPING	0x0800
#define JOG_ZPLUS_ACTIVE		0x1000
#define JOG_ZPLUS_STOPPING		0x2000
#define JOG_ZMINUS_ACTIVE		0x4000
#define JOG_ZMINUS_STOPPING	0x8000
#define JOG_XPLUS_STATES			(JOG_XPLUS_ACTIVE | JOG_XPLUS_STOPPING)
#define JOG_XMINUS_STATES			(JOG_XMINUS_ACTIVE | JOG_XMINUS_STOPPING)
#define JOG_YPLUS_STATES			(JOG_YPLUS_ACTIVE | JOG_YPLUS_STOPPING)
#define JOG_YMINUS_STATES			(JOG_YMINUS_ACTIVE | JOG_YMINUS_STOPPING)
#define JOG_ZPLUS_STATES			(JOG_ZPLUS_ACTIVE | JOG_ZPLUS_STOPPING)
#define JOG_ZMINUS_STATES			(JOG_ZMINUS_ACTIVE | JOG_ZMINUS_STOPPING)

// Strings used for machine file entries
#define GENERAL_SECTION					"GENERAL"
#define MACHINE_TYPE_ENTRY				"MACHINETYPE"
#define PROGRAM_STYLE_ENTRY				"PROGRAMSTYLE"
#define DEFAULT_UNITS_ENTRY				"DEFAULTUNITS"
#define SETUP_PRECISION_ENTRY			"SETUPPRECISION"
#define PART_PRGM_ENGLISH_DIM_ENTRY		"PARTPRGMENGLISHDIMUNITS"
#define PART_PRGM_ENGLISH_PER_ENTRY		"PARTPRGMENGLISHPERUNITS"
#define PART_PRGM_METRIC_DIM_ENTRY		"PARTPRGMMETRICDIMUNITS"
#define PART_PRGM_METRIC_PER_ENTRY		"PARTPRGMMETRICPERUNITS"

#define FEED_SECTION					"FEED"
#define FEED_RATE_ENTRY					"FEEDRATE"
#define FEED_ACCEL_ENTRY				"FEEDACCEL"
#define FEED_DECEL_ENTRY				"FEEDDECEL"
#define MAX_FEED_RATE_ENTRY				"MAXFEEDRATE"
#define MAX_ANGLE_ENTRY					"MAXANGLE"

#define JOGGING_SECTION					"JOGGING"
#define MAX_JOG_RATE_ENTRY				"MAXJOGRATE"
#define JOG_ACCEL_ENTRY					"JOGACCEL"
#define JOG_DECEL_ENTRY					"JOGDECEL"
#define USE_PC_JOYSTICK_ENTRY 			"USEPCJOYSTICK"
#define JOYSTICK_DEADBAND_ENTRY			"JOYSTICKDEADBAND"
#define JOYSTICK_X_CENTER_ENTRY 		"JOYSTICKXCENTER"
#define JOYSTICK_X_UPPER_ENTRY 			"JOYSTICKXUPPER"
#define JOYSTICK_X_LOWER_ENTRY 			"JOYSTICKXLOWER"
#define JOYSTICK_X_INVERT_ENTRY 		"JOYSTICKXINVERT"
#define JOYSTICK_Y_CENTER_ENTRY 		"JOYSTICKYCENTER"
#define JOYSTICK_Y_UPPER_ENTRY 			"JOYSTICKYUPPER"
#define JOYSTICK_Y_LOWER_ENTRY 			"JOYSTICKYLOWER"
#define JOYSTICK_Y_INVERT_ENTRY 		"JOYSTICKYINVERT"

#define HOMING_SECTION					"HOMING"
#define HOMING_MACRO_ENTRY				"HOMINGMACRO"
#define SUPPRESS_HOMING_MESSAGES_ENTRY	"SUPPRESSHOMINGMESSAGES"

#define EXTERNAL_CONTROLS_SECTION		"EXTERNALCONTROLS"
#define START_BUTTON_CHANNEL_ENTRY		"STARTBUTTONCHANNEL"
#define BLOCK_BUTTON_CHANNEL_ENTRY		"BLOCKBUTTONCHANNEL"
#define FHOLD_BUTTON_CHANNEL_ENTRY		"FHOLDBUTTONCHANNEL"
#define START_INDICATOR_CHANNEL_ENTRY	"STARTINDICATORCHANNEL"
#define BLOCK_INDICATOR_CHANNEL_ENTRY	"BLOCKINDICATORCHANNEL"
#define FHOLD_INDICATOR_CHANNEL_ENTRY	"FHOLDINDICATORCHANNEL"
#define E_STOP_INPUT_CHANNEL_ENTRY		"ESTOPINPUTCHANNEL"
#define EXT_E_STOP_INPUT_CHANNEL_ENTRY	"EXTESTOPINPUTCHANNEL"
#define DRIVE_FAULT_INPUT_CHANNEL_ENTRY	"DRIVEFAULTINPUTCHANNEL"
#define BLOCK_SKIP_SWITCH_CHANNEL_ENTRY	"BLOCKSKIPSWITCHCHANNEL"
#define DRYRUN_SWITCH_CHANNEL_ENTRY		"DRYRUNSWITCHCHANNEL"

// Define machine defaults
#define DEFAULT_MACHINE_TYPE				VMILL
#define DEFAULT_PROGRAM_STYLE				FANUC
#define DEFAULT_UNITS						ENGLISH		// For part program execution
#define DEFAULT_SETUP_PRECISION				9
#define DEFAULT_PART_PRGM_ENGLISH_DIM_UNIT	INCH_UNIT
#define DEFAULT_PART_PRGM_ENGLISH_PER_UNIT	MINUTE_UNIT
#define DEFAULT_PART_PRGM_METRIC_DIM_UNIT	METER_UNIT
#define DEFAULT_PART_PRGM_METRIC_PER_UNIT	SECOND_UNIT

class CMachine : public CDocument
{
	DECLARE_SERIAL(CMachine)

public:
	/// <summary>Constructor.</summary>
	CMachine();
	/// <summary>Destructor.</summary>
	virtual ~CMachine();

	/// <summary>Overridden serializer for document I/O.</summary>
	/// <param name="ar">Archive.</param>
	virtual void Serialize(CArchive& ar);
	
	/// <summary>Initialize.</summary>
	void Initialize(void);
	/// <summary>New document handler.</summary>
	/// <returns>True on success, false on failure.</returns>
	virtual	BOOL				OnNewDocument(void);
	/// <summary>Document open handler.</summary>
	/// <param name="file_path">Filename and path of file to open.</param>
	/// <returns>True on success, false on failure.</returns>
	virtual BOOL				OnOpenDocument(const char* file_path); 
	/// <summary>Document save handler.</summary>
	/// <param name="file_path">Filename and path of file to save to.</param>
	/// <returns>True on success, false on failure.</returns>
	virtual BOOL				OnSaveDocument(const char* file_path); 

	/// <summary>Get the machine mode.</summary>
	/// <returns>Mode.</returns>
	int							GetMode() { return m_mode; }
	/// <summary>Set the machine mode.</summary>
	/// <param name="mode">Mode.</param>
	void						SetMode(int mode) { m_mode = mode; }
	
	/// <summary>Get the jog state.</summary>
	/// <returns>Jog state.</returns>
	unsigned int				GetJogState() { return m_jog_state; }
	/// <summary>Set a jog state flag (or flags).</summary>
	/// <param name="state">New jog state.</param>
	void						SetJogState(unsigned int state) { m_jog_state |= state; }
	/// <summary>Clear a jog state flag (or flags).</summary>
	/// <param name="state">Flag to clear.</param>
	void						ClearJogState(unsigned int state) { m_jog_state &= ~(state | ~JOG_ALL_STATES); }
	
	/// <summary>Enable cutter while jogging.</summary>
	void						EnableCutterWhileJogging() { m_cutter_enable_jog = true; }
	/// <summary>Disable cutter while jogging.</summary>
	void						DisableCutterWhileJogging() { m_cutter_enable_jog = false; }

	/// Setup Menu ////////////////////////////////////////////////////////

	/// <summary>Process general setup parameters (machine type, program compatability, etc.).</summary>
	void						SetupGeneral(void);
	/// <summary>Process axis setup parameters.</summary>
	void						SetupAxes(void);
	/// <summary>Process feed rate setup parameters.</summary>
	void						SetupFeed(void);
	/// <summary>Process spindle setup parameters.</summary>
	void						SetupSpindle(void);
	/// <summary>Process cutter setup parameters.</summary>
	void						SetupCutter(void);
	/// <summary>Process rapid rate setup parameters.</summary>
	void						SetupRapid(void);
	/// <summary>Process limit setup parameters.</summary>
	void						SetupLimits(void);
	/// <summary>Process machine coordinates setup parameters.</summary>
	void						SetupMachineCoordinates(void);
	/// <summary>Process program coordinates setup parameters.</summary>
	void						SetupProgramCoordinates(void);
	/// <summary>Process work coordinates setup parameters.</summary>
	void						SetupWorkCoordinates(void);
	/// <summary>Process tool setup parameters.</summary>
	void						SetupTools(void);
	/// <summary>Process offset setup parameters.</summary>
	void						SetupOffsets(void);
	/// <summary>Process jogging setup parameters.</summary>
	void						SetupJogging(void);
	/// <summary>Process homing setup parameters.</summary>
	void						SetupHoming(void);
	/// <summary>Process external control setup parameters.</summary>
	void						SetupExternalControls(void);
	/// <summary>Save machine setup.</summary>
	void						SetupSave(void);
	/// <summary>Save machine setup to a new file.</summary>
	void						SetupSaveAs(void);

	/// Mode Menu /////////////////////////////////////////////////////////

	/// <summary>Set program mode to Run.</summary>
	void						ModeRun(void);
	/// <summary>Update Run mode menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateModeRun(CCmdUI* pCmdUI) { pCmdUI->SetRadio(GetMode() == RUN_MODE); }
	/// <summary>Set program mode to MDI.</summary>
	void						ModeMdi(void);
	/// <summary>Update MDI mode menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateModeMdi(CCmdUI* pCmdUI) { pCmdUI->SetRadio(GetMode() == MDI_MODE); }
	/// <summary>Set program mode to Jog.</summary>
	void						ModeJog(void);
	/// <summary>Update Jog mode menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateModeJog(CCmdUI* pCmdUI) { pCmdUI->SetRadio(GetMode() == JOG_MODE); }
	/// <summary>Set program mode to Homing.</summary>
	void						ModeHome(void);
	/// <summary>Update Honing mode menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateModeHome(CCmdUI* pCmdUI) { pCmdUI->SetRadio(GetMode() == HOME_MODE); }
	/// <summary>Open Homing mode view.</summary>
	void						OpenHomingView(void);
	/// <summary>Close Homing mode view.</summary>
	void						CloseHomingView(void) { m_homing_frame = NULL; m_homing_view = NULL; }
	/// <summary>Switching to new mode, terminate operations of current mode.</summary>
	/// <param name="mode">New mode.</param>
	void						EndMode(int mode);

	/// Options Menu //////////////////////////////////////////////////////

	/// <summary>Toggle current Block Skip option menu setting.</summary>
	void						OptionsBlockskip(void);
	/// <summary>Update Block Skip option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateOptionsBlockskip(CCmdUI* pCmdUI);
	/// <summary>Toggle current Dry Run option menu setting.</summary>
	void						OptionsDryrun(void);
	/// <summary>Update Dry Run options menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateOptionsDryrun(CCmdUI* pCmdUI);

	/// View Menu /////////////////////////////////////////////////////////

	/// <summary>View current info.</summary>
	void						ViewCurrent(void) { SetPositionReadoutMode(SHOW_CURRENT); }
	/// <summary>Update view current option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateViewCurrent(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetPositionReadoutMode() == SHOW_CURRENT); }
	/// <summary>View optimal info.</summary>
	void						ViewOptimal(void) { SetPositionReadoutMode(SHOW_OPTIMAL); }
	/// <summary>Update view optimal option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateViewOptimal(CCmdUI* pCmdUI) { pCmdUI->SetCheck(GetPositionReadoutMode() == SHOW_OPTIMAL); }
	/// <summary>View status info.</summary>
	void						ViewStatus(void);
	/// <summary>Update view status option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateViewStatus(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_status_frame != NULL); }
	/// <summary>Close the status info view.</summary>
	void						CloseStatusView(void) { m_status_frame = NULL; m_status_view = NULL; }
	/// <summary>View part program.</summary>
	void						ViewProgram(void);
	/// <summary>Update view program option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateViewProgram(CCmdUI* pCmdUI) { pCmdUI->SetCheck((m_output_frame != NULL) && (GetPartProgramViewMode() == DISPLAY_PROGRAM)); }
	/// <summary>View messages.</summary>
	void						ViewMessages(void);
	/// <summary>Update view messages option menu check mark.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateViewMessages(CCmdUI* pCmdUI) { pCmdUI->SetCheck((m_output_frame != NULL) && (GetPartProgramViewMode() == DISPLAY_MESSAGES)); }
	/// <summary>Set the part program view mode.</summary>
	/// <param name="mode">New part program view mode.</param>
	void						SetPartProgramViewMode(int mode) { m_part_prog_view_mode = mode; }
	/// <summary>Get the part program view mode.</summary>
	/// <returns>View mode.</returns>
	int							GetPartProgramViewMode() { return m_part_prog_view_mode; }
	/// <summary>Open the output view.</summary>
	void						OpenOutputView(void);
	/// <summary>Close the output view.</summary>
	void						CloseOutputView(void);
	/// <summary>Output a string.</summary>
	/// <param name="string">String to output.</param>
	void						OutputText(LPCSTR string);
	/// <summary>Disable all output.</summary>
	void						DisableAllOutput(void);

	/// File Menu /////////////////////////////////////////////////////////
	
	/// <summary>Have user select a file and load it.</summary>
	void						FileLoad(void);
	/// <summary>Restart a file.</summary>
	void						FileRestart(void);
	/// <summary>Load file into edit control.</summary>
	/// <param name="edit_view">Edit control to target.</param>
	void						LoadEditView(CEditView* edit_view);
	
	/// <summary>Set position readout mode.</summary>
	/// <param name="mode">New position readout mode.</param>
	void						SetPositionReadoutMode(int mode) { m_position_readout_mode = mode; }
	/// <summary>Get position readout mode.</summary>
	/// <returns>Readout mode.</returns>
	int							GetPositionReadoutMode() { return m_position_readout_mode; }
	
	/// <summary>Restart a file.</summary>
	void						CalibrateJoystick(void);
	/// <summary>Update calibrate joystick UI.</summary>
	/// <param name="pCmdUI">UI object to update.</param>
	void						UpdateCalibrateJoystick(CCmdUI* pCmdUI);

	/// <summary>Start a program running.</summary>
	void						Start(void);
	/// <summary>Switch to block by block mode.</summary>
	void						Block(void);
	/// <summary>Switch to feed hold mode.</summary>
	void						FHold(void);

	/// <summary>Set X program zero to current position (must be in jog mode).</summary>
	void						XZero(void);
	/// <summary>Set Y program zero to current position (must be in jog mode).</summary>
	void						YZero(void);
	/// <summary>Set Z program zero to current position (must be in jog mode).</summary>
	void						ZZero(void);

	/// <summary>Update while jogging.</summary>
	void						JogUpdate(void);
	/// <summary>Convert joystick X position to a linearized -1.0 to +1.0 value.</summary>
	/// <param name="joy_info">Joystick information structure.</param>
	/// <returns>Linearized position.</returns>
	double						LinearizeXJoystick(JOYINFO* joy_info);
	/// <summary>Convert joystick Y position to a linearized -1.0 to +1.0 value.</summary>
	/// <param name="joy_info">Joystick information structure.</param>
	/// <returns>Linearized position.</returns>
	double						LinearizeYJoystick(JOYINFO* joy_info);
	/// <summary>This function is called to position cutter. It can be called multiple times
	/// with the same parameter value, and it will return FALSE until the cutter is in 
	/// position and lowered.</summary>
	/// <param name="angle">New cutter angle.</param>
	/// <returns>True if cutter is in position and lowered, false if not.</returns>
	bool						PositionCutter(double angle);

	/// <summary>Set default units.</summary>
	/// <param name="units">New units.</param>
	void						SetDefaultUnits(int units) { m_default_units = units; }
	/// <summary>Get default units.</summary>
	/// <returns>Units.</returns>
	int							GetDefaultUnits(void) { return (int)m_default_units; }

	/// <summary>Set setup precision.</summary>
	/// <param name="units">New precision.</param>
	void						SetSetupPrecision(int prec) { m_setup_precision = prec; }
	/// <summary>Get setup precision.</summary>
	/// <returns>Precision.</returns>
	int							GetSetupPrecision(void) { return (int)m_setup_precision; }

	/// <summary>Set part program loaded flag.</summary>
	/// <param name="state">New flag state.</param>
	void						SetPartLoadedFlag(bool state) { m_part_loaded = state; }
	/// <summary>Get part program loaded flag.</summary>
	/// <returns>True if loaded, false if not.</returns>
	bool						GetPartLoadedFlag(void) { return m_part_loaded; }
	/// <summary>Set part program running flag.</summary>
	/// <param name="state">New flag state.</param>
	void						SetPartRunningFlag(bool state) { m_part_running = state; }
	/// <summary>Get part program running flag.</summary>
	/// <returns>True if running, false if not.</returns>
	bool						GetPartRunningFlag(void) { return m_part_running; }
	/// <summary>Set part program suspended flag.</summary>
	/// <param name="state">New flag state.</param>
	void						SetPartSuspendedFlag(bool state) { m_part_suspended = state; }
	/// <summary>Get part program suspended flag.</summary>
	/// <returns>True if suspended, false if not.</returns>
	bool						GetPartSuspendedFlag() { return m_part_suspended; }
	
	/// <summary>Set feedrate override.</summary>
	/// <param name="over">New override.</param>
	void						SetFeedRateOverride(double over) { m_feedrate_over = over; MtnCtrlr.SetFeedrateOverride(over); }
	/// <summary>Get feedrate override.</summary>
	/// <returns>Override.</returns>
	double						GetFeedRateOverride() { return m_feedrate_over; }
	/// <summary>Set rapid override.</summary>
	/// <param name="over">New override.</param>
	void						SetRapidOverride(double over) { m_rapid_over = over; MtnCtrlr.SetRapidOverride(over); }
	/// <summary>Get rapid override.</summary>
	/// <returns>Override.</returns>
	double						GetRapidOverride() { return m_rapid_over; }
	/// <summary>Set spindle override.</summary>
	/// <param name="over">New override.</param>
	void						SetSpindleOverride(double over) { m_spindle_over = over; MtnCtrlr.SetSpindleOverride(over); }
	/// <summary>Get spindle override.</summary>
	/// <returns>Override.</returns>
	double						GetSpindleOverride() { return m_spindle_over; }
	
	/// <summary>Get block skip enabled state.</summary>
	/// <returns>True if enabled, false if disabled.</returns>
	bool						GetBlockSkipStatus() { return m_block_skip; }
	/// <summary>Enable block skip.</summary>
	void						EnableBlockSkip(void) { m_block_skip = true; MtnCtrlr.EnableBlockSkip(0); }
	/// <summary>Disable block skip.</summary>
	void						DisableBlockSkip(void) { m_block_skip = false; MtnCtrlr.DisableBlockSkip(0); }
	
	/// <summary>Get block skip enabled state.</summary>
	/// <returns>True if enabled, false if disabled.</returns>
	bool						GetDryrunStatus(void) { return m_dry_run; }
	/// <summary>Enable dry run.</summary>
	void						EnableDryrun(void) { m_dry_run = true; MtnCtrlr.EnableDryRun(); }
	/// <summary>Disable dry run.</summary>
	void						DisableDryrun(void) { m_dry_run = false; MtnCtrlr.DisableDryRun(); }

private:
	/// <summary>Initialize Controller with setup data.</summary>
	/// <remarks>
	/// <para>Get motion controller in ascii mode, download a configuration file, issue Run 
	/// Configuration File command to process file.</para>
	/// </remarks>
	void						InitializeController(void);
	/// <summary>Initialize configuration.</summary>
	/// <remarks>
	/// <para>Create a configuration file, download it to motion controller, issue Run 
	/// Configuration File command to process file.</para>
	/// </remarks>
	void						InitializeConfiguration(void);
	/// <summary>Initialize work coordinates.</summary>
	/// <remarks>
	/// <para>Create a work coordinate file, download it to motion controller, issue Run 
	/// Work coordinat File command to process file.</para>
	/// </remarks>
	void						InitializeWorkCoordinates(void);
	/// <summary>Initialize tool data.</summary>
	/// <remarks>
	/// <para>Create a tool data file, download it to motion controller, issue Run 
	/// Tool data File command to process file.</para>
	/// </remarks>
	void						InitializeToolData(void);
	/// <summary>Configure motion controller.</summary>
	/// <param name="cfg_file">Configuration stream.</param>
	void						ConfigureController(std::fstream& cfg_file);

	/// <summary>Check if we're ready to run.</summary>
	/// <returns>True if ready, false if not.</returns>
	bool						RunReady(void);

	/// <summary>Save general data in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveGeneral(const char* file_path);
	/// <summary>Restore general data from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreGeneral(const char* file_path);

	/// <summary>Save feed data in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveFeed(const char* file_path);
	/// <summary>Restore feed data from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreFeed(const char* file_path);

	/// <summary>Save work coordinate data in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveWorkCoor(const char* file_path);
	/// <summary>Restore work coordinate data from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreWorkCoor(const char* file_path);

	/// <summary>Save tool data in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveToolData(const char* file_path);
	/// <summary>Restore tool data from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreToolData(const char* file_path);

	/// <summary>Save tool offset data in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveOffsets(const char* file_path);
	/// <summary>Restore tool offset data from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreOffsets(const char* file_path);

	/// <summary>Save jog settings in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveJogging(const char* file_path);
	/// <summary>Restore jog settings from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreJogging(const char* file_path);

	/// <summary>Save homing settings in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveHoming(const char* file_path);
	/// <summary>Restore homing settings from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreHoming(const char* file_path);

	/// <summary>Save external controls in machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						SaveExternalControls(const char* file_path);
	/// <summary>Restore external controls from machine file.</summary>
	/// <param name="file_path">Filename and path of machine file.</param>
	void						RestoreExternalControls(const char* file_path);
	
public:
	MotionController			MtnCtrlr;						///< Primary motion controller object
	Axis						XAxis;							///< X axis object
	Axis						YAxis;							///< Y axis object
	Axis						ZAxis;							///< Z axis object
	Axis						UAxis;							///< U axis object
	Axis						VAxis;							///< V axis object
	Axis						WAxis;							///< W axis object
	Spindle						m_spindle;						///< Spindle axis object
	Cutter						m_cutter;						///< cutter axis object
	
	WorkCoord					m_work_coords[WORKCOOR_SIZE];	///< work coordinates
	Tool						m_tools[TOOL_SIZE];				///< tools
	
	OffsetTable					DOffsetTable;
	OffsetTable					HOffsetTable;

	CAppInt						MachineType;
	CAppInt						ProgramStyle;
	CDimUnit					PartPrgmEnglishDimUnit;
	CPerUnit					PartPrgmEnglishPerUnit;
	CPerUnit					PartPrgmMetricPerUnit;
	CDimUnit					PartPrgmMetricDimUnit;
	
	CAppInt						StartButtonChannel;				///< start button I/O channel number
	CAppInt						BlockButtonChannel;				///< block button I/O channel number 
	CAppInt						FHoldButtonChannel;				///< feed hold button I/O channel number
	CAppInt						StartIndicatorChannel;			///< start indicator I/O channel number
	CAppInt						BlockIndicatorChannel;			///< block indicator I/O channel number
	CAppInt						FHoldIndicatorChannel;			///< feed hold indicator I/O channel number
	CAppInt						EStopInputChannel;				///< estop button I/O channel number
	CAppInt						ExtEStopInputChannel;			///< external estop button I/O channel number
	CAppInt						DriveFaultInputChannel;			///< drive fault input I/O channel number
	CAppInt						BlockSkipSwitchChannel;			///< block skip switch I/O channel number
	CAppInt						DryrunSwitchChannel;			///< dry run switch button I/O channel number
	
private:
	bool						m_block_skip;					///< block skip enabled state
	int							m_button_state;					///< button state 
	bool						m_calibrating_joystick;			///< true when we're calibrating the joystick
	bool						m_cutter_enable_jog;			///< cutter enable while jogging flag
	CAppInt						m_default_units;				///< default units
	bool						m_dry_run;						///< dry run enabled state
	CSpeed						m_feed_rate;					///< feed rate
	CAcceleration				m_feed_accel;					///< feed acceleration
	CAcceleration				m_feed_decel;					///< feed deceleration
	CSpeed						m_feed_rate_max;				///< feed rate maximum
	CDimension					m_feed_angle_max;				///< feed angle maximum
	double						m_feedrate_over;				///< feedrate override setting
	bool						m_homed;						///< machine homed state
	CFrameWnd*					m_homing_frame;					///< our homing window frame
	CAppInt						m_homing_macro;					///< homing macro number
	CAppInt						m_homing_msg_suppress;			///< suppress homing messages flag
	HomingView*					m_homing_view;					///< our homing window view
	CAcceleration				m_jog_accel;					///< jog acceleration
	CAcceleration				m_jog_decel;					///< jog deeceleration
	CSpeed						m_jog_max_rate;					///< jog max rate
	unsigned int				m_jog_state;					///< Jogging state
	CAppInt						m_joy_deadband;					///< joystick deadband
	CAppInt						m_joy_use_pc;					///< true to use pc joystick, false for no
	CAppDouble					m_joy_x_center;					///< joystick x position center
	CAppInt						m_joy_x_invert;					///< joystick x invert flag
	CAppDouble					m_joy_x_lower;					///< joystick x lower limit
	CAppDouble					m_joy_x_upper;					///< joystick x upper limit
	CAppDouble					m_joy_y_center;					///< joystick y position center
	CAppInt						m_joy_y_invert;					///< joystick y invert flag
	CAppDouble					m_joy_y_lower;					///< joystick y lower limit
	CAppDouble					m_joy_y_upper;					///< joystick y upper limit
	CFrameWnd*					m_mdi_frame;					///< our MDI window frame
	int							m_mode;							///< Machine operating mode
	CFrameWnd*					m_output_frame;					///< our output window frame
	COutputDisplay*				m_output_view;					///< our output window view
	bool						m_part_loaded;					///< part program loaded flag
	int							m_part_prog_view_mode;			///< part program view mode
	int							m_part_program_file_number;		///< loaded part program file number
	CString						m_part_program_first_line;		///< first line of the part program
	CString						m_part_program_name;			///< part program name
	bool						m_part_running;					///< part program running flag
	bool						m_part_suspended;				///< part program suspended flag
	int							m_position_readout_mode;		///< position readout mode
	double						m_rapid_over;					///< rapid rate override setting
	CAppInt						m_setup_precision;				///< setup precision
	double						m_spindle_over;					///< spindle override setting
	CFrameWnd*					m_status_frame;					///< our status window frame
	CStatusDisplay*				m_status_view;					///< our status window view

	// Generated message map functions
protected:
	//{{AFX_MSG(CMachine)
	afx_msg void OnFileLoad();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

#endif			// MACHINE_H
