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

// Strings used for machine file entries
#define CTRLR_AXIS_NUM_ENTRY				"CTRLRAXISNUM"
#define SLAVE_AXIS_NUM_ENTRY				"SLAVEAXISNUM"
#define SCALE_ENTRY							"SCALE"
#define MACHINE_OFFSET_ENTRY				"MACHINEOFFSET"
#define PROGRAM_OFFSET_ENTRY				"PROGRAMOFFSET"

#define RAPID_RATE_ENTRY					"RAPIDRATE"
#define RAPID_ACCEL_ENTRY					"RAPIDACCEL"
#define RAPID_DECEL_ENTRY					"RAPIDDECEL"
#define ACCELERATION_ENTRY					"ACCELERATION"
#define DECELERATION_ENTRY					"DECELERATION"
#define UPPER_LIMIT_ENTRY					"UPPERLIMIT"
#define LOWER_LIMIT_ENTRY					"LOWERLIMIT"
#define HOMING_MACRO_ENTRY					"HOMINGMACRO"

/// <summary>
/// Axis - Machine axis class
/// </summary>
class Axis : CObject
{
public:

	/// <summary>Constructor.</summary>
	/// <param name="id">Axis ID.</param>
	/// <param name="mnemonic">Axis mnemonic.</param>
	Axis(int id, int mnemonic);
	/// <summary>Destructor.</summary>
	~Axis(void) {}

	/// <summary>Initialize a Axis object.</summary>
	/// <param name="axis_num">Axis number.</param>
	void						Initialize(int axis_num);
	/// <summary>Save the Axis settings to an INI file.</summary>
	/// <param name="ini_file">INI file name and path.</param>
	void						SaveData(const char* ini_file);
	/// <summary>Restore the Axis settings from an INI file.</summary>
	/// <param name="ini_file">INI file name and path.</param>
	void						RestoreData(const char* ini_file);
	/// <summary>Generate configuration text for axis and place in file.</summary>
	/// <param name="cfg_file">Stream to use.</param>
	void						Configure(std::fstream& cfg_file);

	/// <summary>Get the axis mnemonic character.</summary>
	/// <returns>Mnemonic.</returns>
	char						GetMnemonic() { return m_mnemonic; }
	/// <summary>Set the axis number.</summary>
	/// <param name="axis_num">Axis number.</param>
	void						SetAxis(int axis_num) { m_axis = axis_num; }
	/// <summary>Get the axis number.</summary>
	/// <returns>Axis number.</returns>
	int							GetAxis() { return (int)m_axis; }
	/// <summary>Set the slave axis number.</summary>
	/// <param name="axis_num">Slave axis number.</param>
	void						SetSlaveAxis(int axis_num) { m_slave_axis = axis_num; }
	/// <summary>Get the slave axis number.</summary>
	/// <returns>Slave axis number.</returns>
	int							GetSlaveAxis() { return (int)m_slave_axis; }
	
	/// <summary>Set the axis scale length and units.</summary>
	/// <param name="units">Dimension units for scale.</param>
	/// <param name="scale">Length value for scale.</param>
	void						SetScale(DIM_UNIT units, double scale) { Scale.Set(units, scale); }
	/// <summary>Get the axis scale length in specified units.</summary>
	/// <param name="units">Dimension units for scale.</param>
	/// <returns>Scale length, in specified units.</returns>
	double						GetScale(DIM_UNIT units) { return Scale.Get(units); }
	
	/// <summary>Set current position as Program Zero for the axis.</summary>
	void						SetProgramZero(void);
	
	/// <summary>Set axis direction.</summary>
	/// <param name="dir">Axis direction.</param>
	void						Direction(WORD dir);
	/// <summary>Enable/disable axis.</summary>
	/// <param name="state">Non-zero to enable, zero to disable.</param>
	void						EnableAxis(int state);
	/// <summary>Start axis moving (must be in velocity mode).</summary>
	void						Go(void);
	/// <summary>Move axis to absolute position.</summary>
	/// <param name="pos">Position.</param>
	void						MoveAbsolute(double pos);
	/// <summary>Move axis a relative amount.</summary>
	/// <param name="dist">Distance to move.</param>
	void						MoveRelative(double dist);
	/// <summary>Set axis acceleration.</summary>
	/// <param name="accel">Acceleration.</param>
	void						SetAcceleration(double accel);
	/// <summary>Set axis deceleration.</summary>
	/// <param name="decel">Deceleration.</param>
	void						SetDeceleration(double decel);
	/// <summary>Set axis operating mode.</summary>
	/// <param name="master">Master axis.</param>
	/// <param name="mode">Operating mode.</param>
	void						SetOperatingMode(WORD master, WORD mode);
	/// <summary>Set axis velocity.</summary>
	/// <param name="vel">Velocity.</param>
	void						SetVelocity(double vel);
	/// <summary>Set axis velocity override.</summary>
	/// <param name="vel">Velocity override.</param>
	void 						SetVelocityOverride(double vel);
	/// <summary>Stop a moving axis.</summary>
	void						Stop(void);
	
	/// <summary>Get axis status.</summary>
	/// <returns>Status word.</returns>
	long						GetStatus(void);
	/// <summary>Get state of specific axis status bit.</summary>
	/// <param name="status">Status word to examine.</param>
	/// <param name="bit">Bit of interest.</param>
	/// <returns>True if status bit is set, false if not.</returns>
	long						DecodeStatus(DWORD status, long bit);
	/// <summary>Get axis position.</summary>
	/// <returns>Position.</returns>
	double						GetPosition(void);
	/// <summary>Get axis optimal position.</summary>
	/// <returns>Optimal position.</returns>
	double						GetOptimal(void);
	/// <summary>Get axis target position.</summary>
	/// <returns>Target position.</returns>
	double						GetTarget(void);
	
	const char *GetReadoutFormat() {return((const char *)ReadoutFormat);};

public:
	CScale						Scale;							///< scaling
	CDimension					MachineOffset;					///< machine offset
	CDimension					ProgramOffset;					///< program offset
	CSpeed						RapidRate;						///< rapid rate
	CAcceleration				RapidAccel;						///< rapid acceleration
	CAcceleration				RapidDecel;						///< rapid deceleration
	CDimension					LowerLimit;						///< lower limit
	CDimension					UpperLimit;						///< upper limit
	
	CString ReadoutFormat;		// Format string for this axes' position readout

private:
	CAppInt						m_axis;							///< axis number
	int							m_id;							///< axis id
	char						m_mnemonic;						///< axis mnemonic
	CAppInt						m_slave_axis;					///< slave axis number
};

#endif			// AXIS_H
