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

// Cutter states
#define CUTTER_STATE_UNKNOWN	0
#define CUTTER_STATE_RAISED		1
#define CUTTER_STATE_LOWERED	2

// Cutter predefined directions (units of "rotations")
#define CUTTER_UNDEF_DIR	0.0
#define CUTTER_XPLUS_DIR	0.0
#define CUTTER_YPLUS_DIR	0.25
#define CUTTER_XMINUS_DIR	0.50
#define CUTTER_YMINUS_DIR	0.75

// Strings used for machine file entries
#define CUTTER_SECTION				"CUTTER"

#define CUTTER_SCALE_ENTRY			"SCALE"
#define CUTTER_OFFSET_ENTRY			"OFFSET"
#define CUTTER_RAISE_MCODE_ENTRY	"RAISEMCODE"
#define CUTTER_LOWER_MCODE_ENTRY	"LOWERMCODE"
#define CUTTER_RAISE_MACRO_ENTRY	"RAISEMACRO"
#define CUTTER_LOWER_MACRO_ENTRY	"LOWERMACRO"
#define CUTTER_SPEED_ENTRY			"SPEED"
#define CUTTER_ACCEL_ENTRY			"ACCEL"
#define CUTTER_DECEL_ENTRY			"DECEL"

/// <summary>
/// Cutter - Machine Cutter Class
/// </summary>
class Cutter : CObject
{
public:
	/// <summary>Constructor.</summary>
	Cutter(void);
	/// <summary>Destructor.</summary>
	~Cutter(void) {}
	
	/// <summary>Generate configuration text for cutter and place in file.</summary>
	/// <param name="cfg_file">Stream to use.</param>
	void						Configure(std::fstream& cfg_file);
	/// <summary>Initialize the cutter object.</summary>
	/// <param name="axis_num">Cutter axxis number.</param>
	void						Initialize(int axis_num);
	/// <summary>Save the cutter settings to a machine file.</summary>
	/// <param name="ini_file">Machine file name and path.</param>
	void						SaveData(const char* ini_file);
	/// <summary>Restore the cutter settings from a machine file.</summary>
	/// <param name="ini_file">Machine file name and path.</param>
	void						RestoreData(const char* ini_file);

	/// <summary>Set cutter axis number.</summary>
	/// <param name="axis_num">New axis number.</param>
	void						SetAxis(int axis_num) { m_axis = axis_num; }
	/// <summary>Get cutter axis number.</summary>
	/// <returns>Axis number or zero if not assigned.</returns>
	int							GetAxis() { return (int)m_axis; }

	/// <summary>Set cutter command target.</summary>
	/// <param name="target">New target.</param>
	void						SetCommandTarget(double target) { m_target = target; }
	/// <summary>Get cutter command target.</summary>
	/// <returns>Target.</returns>
	double						GetCommandTarget() { return m_target; }
	
	/// <summary>Set cutter raised/lowered state.</summary>
	/// <param name="state">New state.</param>
	void						SetState(int state) {m_state = state;}
	/// <summary>Get cutter raised/lowered state.</summary>
	/// <returns>State.</returns>
	int							GetState() { return m_state; }
	
	/// <summary>Enable/disable cutter.</summary>
	/// <param name="state">Non-zero to enable, zero to disable.</param>
	void						EnableAxis(int state);
	/// <summary>Set cutter acceleration.</summary>
	/// <param name="accel">Acceleration.</param>
	void						SetAcceleration(double accel);
	/// <summary>Set cutter deceleration.</summary>
	/// <param name="decel">Deceleration.</param>
	void						SetDeceleration(double decel);
	/// <summary>Set cutter operating mode.</summary>
	/// <param name="master">Master axis.</param>
	/// <param name="mode">operating mode.</param>
	void						SetOperatingMode(WORD master, WORD mode);
	/// <summary>Set cutter velocity.</summary>
	/// <param name="vel">Velocity.</param>
	void						SetVelocity(double vel);
	/// <summary>Set cutter velocity override.</summary>
	/// <param name="vel">Velocity override.</param>
	void						SetVelocityOverride(double vel);
	/// <summary>Move axis to absolute position.</summary>
	/// <param name="position">Position.</param>
	void						MoveAbsolute(double position);
	/// <summary>Move axis a relative amount.</summary>
	/// <param name="distance">Distance to move.</param>
	void						MoveRelative(double distance);
	/// <summary>Stop the cutter.</summary>
	void						Stop(void);
	
	/// <summary>Get cutter status.</summary>
	/// <returns>Status word.</returns>
	long						GetStatus(void);
	/// <summary>Get state of specific cutter 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, int bit);
	/// <summary>Get cutter position.</summary>
	/// <returns>Position.</returns>
	double						GetPosition(void);
	/// <summary>Get cutter optimal position.</summary>
	/// <returns>Optimal position.</returns>
	double						GetOptimal(void);
	/// <summary>Get cutter target position.</summary>
	/// <returns>Target position.</returns>
	double						GetTarget(void);

	/// <summary>Raise the cutter.</summary>
	void						Raise(void);
	/// <summary>Raise the cutter.</summary>
	void						Lower(void);
		
	/// <summary>Get cutter format string for display.</summary>
	/// <returns>Format string.</returns>
	const char*					GetReadoutFormat() { return (const char*)m_readout_format; }

public:
	CScale						Scale;							///< Cutter scaling
	CDimension					Offset;							///< Cutter offset
	CAppInt						RaiseMCode;						///< Used for motion controller CNC configuration
	CAppInt						LowerMCode;						///< Used for motion controller CNC configuration
	CAppInt						RaiseMacro;						///< Used for Jog mode operation
	CAppInt						LowerMacro;						///< Used for Jog mode operation
	CSpeed						Speed;							///< cutter default speed
	CAcceleration				Accel;							///< cutter default acceleration
	CAcceleration				Decel;							///< cutter default deceleration
	
private:
	CAppInt						m_axis;							///< Cutter axis number
	CString						m_readout_format;				///< Format string for this axes' position readout
	int							m_state;						///< Raised or lowered, maintained during jogging
	double						m_target;						///< Maintained during jogging
};

#endif			// CUTTER_H
