//
//  cutter.cpp - machine cutter implementation
//
//  $Id: cutter.cpp 53 2014-02-07 19:39:59Z brian $
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#include "stdafx.h"

Cutter::Cutter(void)
{
	// Initialize member Application Variables so they can save and restore themselves	
	m_axis.Init(0, CUTTER_SECTION, CTRLR_AXIS_NUM_ENTRY);
	RaiseMCode.Init(0, CUTTER_SECTION, CUTTER_RAISE_MCODE_ENTRY);
	LowerMCode.Init(0, CUTTER_SECTION, CUTTER_LOWER_MCODE_ENTRY);
	RaiseMacro.Init(0, CUTTER_SECTION, CUTTER_RAISE_MACRO_ENTRY);
	LowerMacro.Init(0, CUTTER_SECTION, CUTTER_LOWER_MACRO_ENTRY);
	Scale.Init(REVOLUTION_UNIT, 0.0, CUTTER_SECTION,CUTTER_SCALE_ENTRY);
	Offset.Init(REVOLUTION_UNIT, 0.0, CUTTER_SECTION,CUTTER_OFFSET_ENTRY);
	Speed.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, CUTTER_SECTION,CUTTER_SPEED_ENTRY);
	Accel.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, CUTTER_SECTION,CUTTER_ACCEL_ENTRY);
	Decel.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, CUTTER_SECTION,CUTTER_DECEL_ENTRY);

	SetCommandTarget(0.0);
	SetState(CUTTER_STATE_UNKNOWN);
		
	// Provide a default readout format string	
	m_readout_format = "%#+ 14f";
}

void Cutter::Initialize(int axis_num)
{
	m_axis = axis_num;
	RaiseMCode = 0;
	LowerMCode = 0;
	RaiseMacro = 0;
	LowerMacro = 0;
	Scale.Set(REVOLUTION_UNIT,1.0);
	Offset.Set(REVOLUTION_UNIT,0.0);
	Speed.Set(REVOLUTION_UNIT,DEFAULT_PER_UNIT,0.0);
	Accel.Set(REVOLUTION_UNIT,DEFAULT_PER_UNIT,0.0);
	Decel.Set(REVOLUTION_UNIT,DEFAULT_PER_UNIT,0.0);
}

void Cutter::SaveData(const char* ini_file)
{
	int iSUPrec;
	CMachine* machine = theApp.GetMachine();
	iSUPrec = machine->GetSetupPrecision();
	
	// Clear section for this Cutter
	m_axis.Erase(ini_file);

	// Save data
	m_axis.Save(ini_file);
	Scale.Save(ini_file, iSUPrec);
	Offset.Save(ini_file, iSUPrec);
	RaiseMCode.Save(ini_file);
	LowerMCode.Save(ini_file);
	RaiseMacro.Save(ini_file);
	LowerMacro.Save(ini_file);
	Speed.Save(ini_file, iSUPrec);
	Accel.Save(ini_file, iSUPrec);
	Decel.Save(ini_file, iSUPrec);
}


void Cutter::RestoreData(const char* ini_file)
{
	m_axis.Restore(ini_file);
	Scale.Restore(ini_file);
	Offset.Restore(ini_file);
	RaiseMCode.Restore(ini_file);
	LowerMCode.Restore(ini_file);
	RaiseMacro.Restore(ini_file);
	LowerMacro.Restore(ini_file);
	Speed.Restore(ini_file);
	Accel.Restore(ini_file);
	Decel.Restore(ini_file);
}

void Cutter::Configure(std::fstream& cfg_file)
{
	// Place comment in configuration file
	cfg_file << ";" << " Cutter configuration" << std::endl;
	
	// Generate configuration string for motion controller
	cfg_file << "CUTTERAXIS=" << GetAxis() << std::endl;
	
	if (GetAxis())		// Only configure cutter if it exist
	{
		cfg_file << "CUTTERRAISEMCODE=" << (int)RaiseMCode << std::endl;
		cfg_file << "CUTTERLOWERMCODE=" << (int)LowerMCode << std::endl;
		
		// Configuration data in both english and metric units
		for (int units = ENGLISH; units <= METRIC; units++)
		{
			cfg_file << (const char*)UnitsName[units] << std::endl;

			DIM_UNIT DimUnit = theApp.GetMachine()->PartPrgmEnglishDimUnit.Get();
			PER_UNIT PerUnit = theApp.GetMachine()->PartPrgmEnglishPerUnit.Get();

			cfg_file << "CUTTERSCALE=" << Scale.Get(REVOLUTION_UNIT) << std::endl;
			cfg_file << "CUTTEROFFSET=" << Offset.Get(REVOLUTION_UNIT) << std::endl;
			cfg_file << "CUTTERRATECONV=" << 1.0 / PerUnitMultiplier[PerUnit] << std::endl;
			cfg_file << "CUTTERSPEED=" << Speed.Get(REVOLUTION_UNIT,PerUnit) << std::endl;
			cfg_file << "CUTTERACCEL=" << Accel.Get(REVOLUTION_UNIT,PerUnit) << std::endl;
			cfg_file << "CUTTERDECEL=" << Decel.Get(REVOLUTION_UNIT,PerUnit) << std::endl;
			
			if (units == theApp.GetMachine()->GetDefaultUnits())
			{
				double scale = Scale.Get(DimUnit);
				if (scale > 100000000.0)
					m_readout_format = "%#+ 14.9f";
				else if (scale > 10000000.0)
					m_readout_format = "%#+ 14.8f";
				else if (scale > 1000000.0)
					m_readout_format = "%#+ 14.7f";
				else if (scale > 100000.0)
					m_readout_format = "%#+ 14.6f";
				else if (scale > 10000.0)
					m_readout_format = "%#+ 14.5f";
				else if (scale > 1000.0)
					m_readout_format = "%#+ 14.4f";
				else if (scale > 100.0)
					m_readout_format = "%#+ 14.3f";
				else if (scale > 10.0)
					m_readout_format = "%#+ 14.2f";
				else if (scale > 1.0)
					m_readout_format = "%#+ 14.1f";
				else
					m_readout_format = "%#+ 14.0f";
			}
		}
	}
}

void Cutter::Raise()
{
	if ((int)RaiseMacro)
		theApp.GetMachine()->MtnCtrlr.MacroCall((int)RaiseMacro);
	SetState(CUTTER_STATE_RAISED);
}

void Cutter::Lower()
{
	if ((int)LowerMacro)
		theApp.GetMachine()->MtnCtrlr.MacroCall((int)LowerMacro);
	SetState(CUTTER_STATE_LOWERED);
}

void Cutter::SetOperatingMode(WORD master, WORD mode)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.SetOperatingMode(m_axis, master, mode);
}

void Cutter::EnableAxis(int state)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.EnableAxis(m_axis, state);
}

void Cutter::SetVelocity(double vel)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.SetVelocity(m_axis, vel);
}

void Cutter::SetVelocityOverride(double vel)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.SetVelocityOverride(m_axis, vel);
}

void Cutter::SetAcceleration(double accel)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.SetAcceleration(m_axis, accel);
}

void Cutter::SetDeceleration(double decel)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.SetDeceleration(m_axis, decel);
}

void Cutter::MoveAbsolute(double position)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.MoveAbsolute(m_axis, position);
}

void Cutter::MoveRelative(double distance)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.MoveRelative(m_axis, distance);
}

void Cutter::Stop(void)
{
	if (m_axis)
		theApp.GetMachine()->MtnCtrlr.Stop(m_axis);
}

long Cutter::GetStatus(void)
{
	if (m_axis)
		return(theApp.GetMachine()->MtnCtrlr.GetStatus(m_axis));
	else
		return(0);
}
	
long Cutter::DecodeStatus(DWORD status, int bit)
{
	if (m_axis)
		return theApp.GetMachine()->MtnCtrlr.DecodeStatus(status, bit);
	else
		return 0;
}
	
double Cutter::GetPosition(void)
{
	if (m_axis)
		return theApp.GetMachine()->MtnCtrlr.GetPosition(m_axis);
	else
		return 0.0;
}

double Cutter::GetOptimal(void)
{
	if (m_axis)
		return theApp.GetMachine()->MtnCtrlr.GetOptimal(m_axis);
	else
		return 0.0;
}

double Cutter::GetTarget(void)
{
	if (m_axis)
		return theApp.GetMachine()->MtnCtrlr.GetTarget(m_axis);
	else
		return 0.0;
}
