<reponame>kd-boss/CAT
// generated by Fast Light User Interface Designer (fluid) version 1.0307


#include "FT891.h"
#include <fmt/core.h>
#include <iostream>

using namespace boost;
using namespace std;
using namespace asio;
using namespace Yaesu::FT891::Commands;
using namespace std::placeholders;
using namespace boost;

std::string dummydata = "aslkdfk;";

void OnSaveMemory(Fl_Button* o, void* v)
{
	((FT891*)v)->SaveMemoryChannels();
}

void FT891::SaveMemoryChannels()
{
	
	m_channels = m_editor->m_channels;
	this->MemoryChannelSave = true;
	for(auto i = m_channels.begin(); i < m_channels.end(); i++)
	{
	
		if(i->Mode != Yaesu::FT891::Commands::MemoryChannelModeValue::FM|| i->Mode != Yaesu::FT891::Commands::MemoryChannelModeValue::FM_N)
		{
			i->CTCSS = Yaesu::FT891::Commands::CTCSSState::CTCSS_OFF;
			i->Operation = Yaesu::FT891::Commands::OperationType::Simplex;
		}
		if(i->TagString.length() > 0)
		{
			auto msg = MemoryWriteTag::Set(*i);
			m_port.writeString(msg);
		}
		else
		{
			Yaesu::FT891::Commands::MemoryChannelWriteValue mv;
			mv.Mode = i->Mode;
			mv.Operation = i->Operation;
			mv.Clarifier = i->Clarifier;
			mv.ClarifierFreq = i->ClarifierFreq;
			mv.CTCSS = i->CTCSS;
			mv.MemoryChannel = i->MemoryChannel;
			mv.VFOAFreq = i->VFOAFreq;
			auto msg = MemoryChannelWrite::Set(mv);
			m_port.writeString(msg);
		}
		
	}
	
	delete win;
}

void FT891::PowerDown()
{
	//Tell it to turn off..
	string buff = PowerSwitch::Set(PowerSwitchValue::OFF);
	m_port.writeString(buff);
	std::this_thread::sleep_for(std::chrono::milliseconds(1400)); // wait at least one second but not more than two. 
	//and put it back in the error state to complete turning it off. (this isn't in the CAT manual, but is required.) 
	m_port.writeString(dummydata);
}

void FT891::PowerUp()
{
	//put it in the error state by giving it dummy data.   
	m_port.writeString(dummydata);
	std::this_thread::sleep_for(std::chrono::milliseconds(1400)); //wait at least one second but not more than two. 
	//tell it to turn on. 
	string buff = PowerSwitch::Set(PowerSwitchValue::ON);
	m_port.writeString(buff);

}

void FT891::ReadPowerSwitch()
{
	string buff;	
	//write dummy data to the rig to put it in the error state
	buff = dummydata;
	m_port.writeString(buff);
	 
	std::this_thread::sleep_for(std::chrono::milliseconds(1400));
	//request the power switch state
	auto pstate = PowerSwitch::Read();
	m_port.writeString(pstate);
}

void FT891::CalcMode(ModeValue v)
{
	switch(v)
	{
		case ModeValue::CW:
		case ModeValue::CW_BFOA:
			MicGain->hide();
			VOX->hide();
			PRC->hide();
			ProcessorLevel->hide();
			Keyer->show();
			KeyerSpeed->show();
			KeyerPitch->show();
			BreakIn->show();
			m_port.writeString(Keyer::Read());
			m_port.writeString(KeyPitch::Read());	
			m_port.writeString(BreakIn::Read());
			this->redraw();
		break;
		default:
			MicGain->show();
			ProcessorLevel->show();
			VOX->show();
			PRC->show();
			KeyerSpeed->hide();
			Keyer->hide();
			KeyerPitch->hide();
			BreakIn->hide();
		break;
	}

	switch(v)
	{
			case ModeValue::SSB_BFOA:
				switch(SSBbfo)
				{
					case BfoValue::USB:
					OperatingMode->value(0);
					currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::USB;
					break;
					case BfoValue::LSB:
					OperatingMode->value(1);
					currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::LSB;
					break;
					case BfoValue::AUTO:
					 OperatingMode->value(2);
					 if(VFOAFreq >= 10000000)
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::USB;
					 else
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::LSB;
					break;
				}
			
				break;
			case ModeValue::SSB_BFOB:
				switch(SSBbfo)
				{
					case BfoValue::USB:
						OperatingMode->value(0);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::USB;
					break;
					case BfoValue::LSB:
						OperatingMode->value(1);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::LSB;
					break;
					case BfoValue::AUTO:
					{
						OperatingMode->value(2);
						if(VFOAFreq >= 10000000)
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::USB;
					 	else
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::LSB;
					}
					break;
				}
				
				break;
			case ModeValue::CW:
				switch(CWBfo)
				{
					case BfoValue::USB:
						OperatingMode->value(3);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW;
					break;
					case BfoValue::LSB:
						OperatingMode->value(4);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW_R;
					break;
					case BfoValue::AUTO:
						OperatingMode->value(5);
						if(VFOAFreq >= 10000000)
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW_R;
					 	else
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW;
					break;
				}
								
				break;
			case ModeValue::CW_BFOA:
				switch(CWBfo)
				{
					case BfoValue::USB:
						OperatingMode->value(4);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW_R;
					break;
					case BfoValue::LSB:
						OperatingMode->value(3);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW;
					break;
					case BfoValue::AUTO:
						OperatingMode->value(5);
						OperatingMode->value(5);
						if(VFOAFreq >= 10000000)
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW_R;
					 	else
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::CW;
					break;
				}    
				
				break;
			case ModeValue::FM:
				OperatingMode->value(6);     
				currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::FM;
				break;
			case ModeValue::FM_N:
				OperatingMode->value(7);     
				currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::FM_N;
				break;
			case ModeValue::AM:
				OperatingMode->value(8);     
				currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::AM;
				break;
			case ModeValue::AM_N:
				OperatingMode->value(9);     
				currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::AM_N;
				break;
			case ModeValue::DATA_BFOB:
				switch(DATABfo)
				{
					case DataBfoValue::USB:
						OperatingMode->value(10);     
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::DATA_LSB;
					break;
					case DataBfoValue::LSB:
						OperatingMode->value(11);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::DATA_USB;
					break;
				}
				
				break;
			case ModeValue::DATA_BFOA:
				switch(DATABfo)
				{
					case DataBfoValue::USB:
						OperatingMode->value(11);     
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::DATA_LSB;
					break;
					case DataBfoValue::LSB:
						OperatingMode->value(10);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::DATA_USB;
					break;
				}
			     
				break;
			case ModeValue::RTTY_BFOB:
				switch(RTTYBfo)
				{
					case DataBfoValue::USB:
						OperatingMode->value(12);    
						 currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::RTTY_LSB;
					break;
					case DataBfoValue::LSB:
						OperatingMode->value(13);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::RTTY_USB;
					break;
				}     
				break;
			case ModeValue::RTTY_BFOA:
				switch(RTTYBfo)
				{
					case DataBfoValue::USB:
						OperatingMode->value(13);     
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::RTTY_USB;
					break;
					case DataBfoValue::LSB:
						OperatingMode->value(12);
						currentMemoryMode = Yaesu::FT891::Commands::MemoryChannelModeValue::RTTY_LSB;
					break;
				}   
				break;
		}
		OperatingMode->redraw();
}

UIMode FT891::GetUIMode()
{
		UIMode v;
		switch(OperatingMode->value())
		{
			case 0:
			case 1:
			case 2:
			v = UIMode::SSB;
			break;
			case 3:
			case 4:
			case 5:
			v = UIMode::CW;
			case 12:
			case 13:
			v = UIMode::RTTY;
			break;
		}
		return v;
}

void FT891::CalculateWidth(Yaesu::FT891::Commands::WidthValue wv)
{
	UIMode v = GetUIMode();
	Width->clear();
	switch(v)
	{
		case UIMode::SSB:	
				if(NarrowState == NarrowValue::ON)
				{
					Width->add("200Hz", 0, OnChoice, this, 0);
					Width->add("400Hz", 0, OnChoice, this, 0);
					Width->add("600Hz", 0, OnChoice, this, 0);
					Width->add("850Hz", 0, OnChoice, this, 0);
					Width->add("1100Hz", 0, OnChoice, this, 0);
					Width->add("1350Hz", 0, OnChoice, this, 0);
					Width->add("1500Hz", 0, OnChoice, this, 0);
					Width->add("1650Hz", 0, OnChoice, this, 0);
					Width->add("1800Hz", 0, OnChoice, this, 0);
					
					Width->value(wv.WidthCommand - 1);					
				}
				else
				{							
					Width->add("1800Hz", 0, OnChoice, this, 0);
					Width->add("1950Hz", 0, OnChoice, this, 0);
					Width->add("2100Hz", 0, OnChoice, this, 0);
					Width->add("2200Hz", 0, OnChoice, this, 0);
					Width->add("2300Hz", 0, OnChoice, this, 0);
					Width->add("2400Hz", 0, OnChoice, this, 0);
					Width->add("2500Hz", 0, OnChoice, this, 0);
					Width->add("2600Hz", 0, OnChoice, this, 0);
					Width->add("2700Hz", 0, OnChoice, this, 0);
					Width->add("2800Hz", 0, OnChoice, this, 0);
					Width->add("2900Hz", 0, OnChoice, this, 0);
					Width->add("3000Hz", 0, OnChoice, this, 0);
					Width->add("3200Hz", 0, OnChoice, this, 0);
					int val = wv.WidthCommand - 9;
					val = val >= 0 ? val : 0;
					val = val <= 12 ? val : 12;
					Width->value(val);					
				}						
		break;
		case UIMode::CW:
				if(NarrowState == NarrowValue::ON)
				{						
					Width->add("50Hz", 0, OnChoice, this, 0);
					Width->add("100Hz", 0, OnChoice, this, 0);
					Width->add("150Hz", 0, OnChoice, this, 0);
					Width->add("200Hz", 0, OnChoice, this, 0);
					Width->add("250Hz", 0, OnChoice, this, 0);
					Width->add("300Hz", 0, OnChoice, this, 0);
					Width->add("350Hz", 0, OnChoice, this, 0);
					Width->add("400Hz", 0, OnChoice, this, 0);
					Width->add("450Hz", 0, OnChoice, this, 0);			
					Width->add("500Hz", 0, OnChoice, this, 0);
					
					Width->value(wv.WidthCommand - 1);					
				} 
				else 
				{				
					Width->add("500Hz", 0, OnChoice, this, 0);
					Width->add("800Hz", 0, OnChoice, this, 0);
					Width->add("1200Hz", 0, OnChoice, this, 0);
					Width->add("1400Hz", 0, OnChoice, this, 0);
					Width->add("1700Hz", 0, OnChoice, this, 0);
					Width->add("2000Hz", 0, OnChoice, this, 0);
					Width->add("2400Hz", 0, OnChoice, this, 0);
					Width->add("3000Hz", 0, OnChoice, this, 0);	
					
					Width->value(wv.WidthCommand - 10);					
				}			
		break;
		case UIMode::RTTY:
				if(NarrowState == NarrowValue::ON)
				{						
					Width->add("50Hz", 0, OnChoice, this, 0);
					Width->add("100Hz", 0, OnChoice, this, 0);
					Width->add("150Hz", 0, OnChoice, this, 0);
					Width->add("200Hz", 0, OnChoice, this, 0);
					Width->add("250Hz", 0, OnChoice, this, 0);
					Width->add("300Hz", 0, OnChoice, this, 0);
					Width->add("350Hz", 0, OnChoice, this, 0);
					Width->add("400Hz", 0, OnChoice, this, 0);
					Width->add("450Hz", 0, OnChoice, this, 0);			
					Width->add("500Hz", 0, OnChoice, this, 0);
					
					Width->value(wv.WidthCommand - 1);					
				} 
				else 
				{
					Width->add("500Hz", 0, OnChoice, this, 0);
					Width->add("800Hz", 0, OnChoice, this, 0);
					Width->add("1200Hz", 0, OnChoice, this, 0);
					Width->add("1400Hz", 0, OnChoice, this, 0);
					Width->add("1700Hz", 0, OnChoice, this, 0);
					Width->add("2000Hz", 0, OnChoice, this, 0);
					Width->add("2400Hz", 0, OnChoice, this, 0);
					Width->add("3000Hz", 0, OnChoice, this, 0);	
					
					Width->value(wv.WidthCommand - 10);					
				}			
		break;
	}
	Width->redraw();	
	
}

void FT891::SetBand()
{
	if((VFOAFreq >= 1800000) & (VFOAFreq <= 2000000))
	{
		Band->value((int)Band::m160);
	}
	else if((VFOAFreq >= 3500000) & (VFOAFreq <= 4000000))
	{
		Band->value((int)Band::m80);
	}
	else if((VFOAFreq >= 5300000) & (VFOAFreq <= 5405000)) 
	{
		Band->value((int)Band::m60);
	}
	else if((VFOAFreq >= 7000000) & (VFOAFreq <= 7300000))
	{
		Band->value((int)Band::m40);
	}
	else if((VFOAFreq >= 10100000) & (VFOAFreq <= 10150000))
	{
		Band->value((int)Band::m30);
	}
	else if((VFOAFreq >= 14000000) & (VFOAFreq <= 14350000))
	{
		Band->value((int)Band::m20);
	}
	else if((VFOAFreq >= 18068000) & (VFOAFreq <= 18168000))
	{
		Band->value((int)Band::m17);
	}
	else if((VFOAFreq >= 21000000) & (VFOAFreq <= 21450000))
	{
		Band->value((int)Band::m15);
	}
	else if((VFOAFreq >= 24890000) & (VFOAFreq <= 24990000))
	{
		Band->value((int)Band::m12);
	}
	else if((VFOAFreq >= 28000000) & (VFOAFreq <= 29700000))
	{
		Band->value((int)Band::m10);
	}
	else if((VFOAFreq >= 50000000) & (VFOAFreq <= 54000000))
	{
		Band->value((int)Band::m6);
	}
	else
	{
		Band->value((int)Band::GEN);
	}
}

void FT891::readCallback(const char* c, int v)
{
	Fl::lock();
	buff.append(c,v);
	std::string delim = ";";
	size_t pos = 0;
	try
	{
	while((pos = buff.find(delim)) != string::npos)
	{
		string cmd = buff.substr(0, (pos + 1));
		cmd.erase(0,cmd.find_first_not_of('\0'));
		
		buff = buff.erase(0,pos + 1);
		string cmdtype;
		if(cmd.length() >= 2)
		{
			cmdtype = cmd.substr(0,2);
		}
		else
		{
			std::cout << "malformed  data: " << cmd << std::endl;
			continue;
		}

		if(cmdtype == "?;")
		{
			if(MemoryChannelEdit)
			{
				currentMemory = static_cast<Yaesu::FT891::Commands::MemoryChannelValue>(static_cast<int>(currentMemory) + 1);
				if(static_cast<int>(currentMemory) != 118)
				{
					cmd = Yaesu::FT891::Commands::MemoryWriteTag::Read(currentMemory);
					m_port.writeString(cmd);
				}
				else
				{
					MemoryChannelEdit = false;
				}
			}
			#ifdef DEBUG
			cout << cmdtype << endl;
			#endif
			
			continue;
		}
		else if(cmdtype == "IF")
		{
			
			InformationValue iv = INFORMATION::Answer(cmd);
			
			switch(iv.VFO)
			{
				
				case  VFOChannelTypeValue::Memory:		
					if(static_cast<int>(iv.MemoryChannel) < 500)
					{							
						labelText = fmt::format("M{:02}",static_cast<int>(iv.MemoryChannel));
						ChannelLabel->label(labelText.c_str());										
					}
					else
					{
						labelText = fmt::format("{:d}",static_cast<int>(iv.MemoryChannel));
						ChannelLabel->label(labelText.c_str());										
					}
				break;
				case VFOChannelTypeValue::MemoryTune:
					ChannelLabel->label("MT");
				break;
				case VFOChannelTypeValue::QuickMemoryBank:
					ChannelLabel->label("QMB");					
				break;
				case VFOChannelTypeValue::PMS:
					ChannelLabel->label("PMS");
				break;
				case VFOChannelTypeValue::VFO:				
					ChannelLabel->label("A");					
				break;
			} 

			ChannelLabel->redraw();
			VFOAFreq = iv.VFOAFreq;
			SetBand();
			ClarifierValue = iv.ClarifierFreq;
			if(iv.Clarifier == ClarifierState::ON) //+ offeset
			{
				CLAR->color(FL_GREEN);
				Clarifier->value(iv.ClarifierFreq);
				switch(static_cast<ClarSelectValue>(ClarifierType->value()))
				{
					case ClarSelectValue::RX:
					case ClarSelectValue::TRX:
						iv.VFOAFreq = iv.VFOAFreq + iv.ClarifierFreq;
					break;				    
				}
			}			
			string dispval = fmt::format("{:d}.{:03}.{:03}", (iv.VFOAFreq - (iv.VFOAFreq % 1000000)) / 1000000, ((iv.VFOAFreq % 1000000) - (iv.VFOAFreq % 1000)) / 1000, (iv.VFOAFreq % 1000));						
			VFOA->value(dispval.c_str());
			
			CalcMode(iv.Mode);
			VFOA->redraw();
			#ifdef DEBUG
			cout << dispval << endl;
			#endif
			
		
			continue;
		}
		else if(cmdtype == "CF")
		{
			ClarifierState = Yaesu::FT891::Commands::Clarifier::Answer(cmd);
			continue;
		}
		else if(cmdtype == "TX")
		{
			
			tVFOAFreq = 0;
			switch(TXW::Answer(cmd))
			{
				case TXWValue::ON:
					switch(static_cast<ClarSelectValue>(ClarifierType->value()))
					{
						case ClarSelectValue::TX:
						case ClarSelectValue::TRX:
							tVFOAFreq = VFOAFreq + ClarifierValue;
							dispval = fmt::format("{:d}.{:03}.{:03}", (tVFOAFreq - (tVFOAFreq % 1000000)) / 1000000, ((tVFOAFreq % 1000000) - (tVFOAFreq % 1000)) / 1000, (tVFOAFreq % 1000));						
							VFOA->value(dispval.c_str());			
						break;				    
					}
				break;
				case TXWValue::OFF:
					
					switch(static_cast<ClarSelectValue>(ClarifierType->value()))
					{
						case ClarSelectValue::RX:
						case ClarSelectValue::TRX:
							tVFOAFreq = VFOAFreq + ClarifierValue;
							dispval = fmt::format("{:d}.{:03}.{:03}", (tVFOAFreq - (tVFOAFreq % 1000000)) / 1000000, ((tVFOAFreq % 1000000) - (tVFOAFreq % 1000)) / 1000, (tVFOAFreq % 1000));						
							VFOA->value(dispval.c_str());			
						break;				    
						case ClarSelectValue::TX:
							dispval = fmt::format("{:d}.{:03}.{:03}", (VFOAFreq - (VFOAFreq % 1000000)) / 1000000, ((VFOAFreq % 1000000) - (VFOAFreq % 1000)) / 1000, (VFOAFreq % 1000));						
							VFOA->value(dispval.c_str());
						break;
					}
				break;
			}
			continue;
		}
		else if(cmdtype == "RA")
		{
			RfAttenuatorState v = RFAttenuator::Answer(cmd);
			switch(v)
			{
				case RfAttenuatorState::OFF:
					ATT->color(FL_BACKGROUND_COLOR);
				break;
				case RfAttenuatorState::ON:
					ATT->color(FL_GREEN);
				break;
			}
			ATT->redraw();
			continue;
		}
		else if(cmdtype == "RL")
		{
			int i = NoiseReductionLevel::Answer(cmd);
			DNRAlgo->value(i);
			DNRAlgo->redraw();
			continue;
		}
		else if(cmdtype == "NB")
		{
			NoiseBlankerStatusValue v = NoiseBlankerStatus::Answer(cmd);
			switch(v)
			{
				case NoiseBlankerStatusValue::OFF:
					NB->color(FL_BACKGROUND_COLOR);
				break;
				case NoiseBlankerStatusValue::ON:
					NB->color(FL_GREEN);
					m_port.writeString(NoiseBlankerLevel::Read());
				break;
			}
			NB->redraw();
			continue;
		}
		else if(cmdtype == "NL")
		{
			NoiseBlankerLevel->value(NoiseBlankerLevel::Answer(cmd));
			NoiseBlankerLevel->redraw();
			continue;
		}
		else if(cmdtype == "PA")
		{
			PreAmpValue v = PreAmp::Answer(cmd);
			switch(v)
			{
				case PreAmpValue::AMP:
				IPO->color(FL_BACKGROUND_COLOR);
				break;
				case PreAmpValue::IPO:
				IPO->color(FL_GREEN);
				break;
			}
			IPO->redraw();
			continue;
		}
		else if(cmdtype == "NR")
		{
			NoiseReductionValue v = NoiseReduction::Answer(cmd);
			switch(v)
			{
				case NoiseReductionValue::OFF:
					btnDNR->color(FL_BACKGROUND_COLOR);
				
				break;
				case NoiseReductionValue::ON:
					btnDNR->color(FL_GREEN);					
					m_port.writeString(NoiseReductionLevel::Read());				
				break;
			}
			btnDNR->redraw();	
			continue;		
		}
		else if(cmdtype == "OI")
		{
			OppositeInformationValue iv = OppositeBandInformation::Answer(cmd);
			VFOBFreq = iv.VFOBFreq;
			string dispval = fmt::format("{:d}.{:03}.{:03}", (iv.VFOBFreq - (iv.VFOBFreq % 1000000)) / 1000000, ((iv.VFOBFreq % 1000000) - (iv.VFOBFreq % 1000)) / 1000, (iv.VFOBFreq % 1000));						
			VFOB->value(dispval.c_str());
			
			//CalcMode(iv.Mode);
			VFOB->redraw();
			Fl::awake();
			continue;
		}
		else if(cmdtype == "FA")
		{
			VFOA->value(fmt::format("{:d}.{:03}.{:03}", (VFOAFreq - (VFOAFreq % 1000000)) / 1000000, ((VFOAFreq % 1000000) - (VFOAFreq % 1000)) / 1000, (VFOAFreq % 1000)).c_str());
			VFOA->redraw();		
			m_port.writeString(INFORMATION::Read());
			#ifdef DEBUG
			cout << VFOA->value() << std::endl;
			#endif
			continue;
		}
		else if(cmdtype == "FB")
		{
			VFOBFreq = VFO_B_FREQ::Answer(cmd);
			VFOB->value(fmt::format("{:d}.{:03}.{:03}", (VFOBFreq - (VFOBFreq % 1000000)) / 1000000, ((VFOBFreq % 1000000) - (VFOBFreq % 1000)) / 1000, (VFOBFreq % 1000)).c_str());						
			VFOB->redraw();	
			#ifdef DEBUG				
			cout << VFOB->value() << endl;
			#endif
			continue;
		}
		else if(cmdtype == "MT")
		{

			MemoryChannelTagValue tv = Yaesu::FT891::Commands::MemoryWriteTag::Answer(cmd);
			tv.MemoryChannel = currentMemory;
			if(std::find_if(m_channels.begin(), m_channels.end(),[tv](auto e){ return e.MemoryChannel == tv.MemoryChannel;}) == m_channels.end()){
				m_channels.push_back(tv);
				currentMemory = static_cast<MemoryChannelValue>(((int)currentMemory)+ 1);
				std::string cmd = Yaesu::FT891::Commands::MemoryWriteTag::Read(currentMemory);
				m_port.writeString(cmd);
			}
			
			continue;
		}
		else if(cmdtype == "ML")
		{
			MonitorLevelValue v = MonitorLevel::Answer(cmd);
			switch(v.f)
			{
				case MonitorFunction::MontiorOnOff:
				  if(v.val.eVal == MonitorOnOffValue::OFF){
				  	MON->color(FL_BACKGROUND_COLOR);
				
			
					MonitorLevel->redraw();
					MonitorLevel->redraw_label();
					#ifdef DEBUG
					cout << "MON OFF" << endl;
					#endif
				  }
				  else{
					MON->color(FL_GREEN);
					
				
					MonitorLevel->redraw();
					MonitorLevel->redraw_label();
					#ifdef DEBUG
					cout << "MON ON" << endl;
					#endif
				  }
				break;
				case MonitorFunction::MontiorLevel:
					MonitorLevel->value(v.val.iVal);
				break;
			}		
			continue;	
		}
		else if(cmdtype == "FS")
		{
			VFOFastStepValue v = FAST_STEP::Answer(cmd);
			switch(v)
			{
				case VFOFastStepValue::ON:
					FST->color(FL_GREEN);
					m_port.writeString(KeyerSpeed::Read());
				break;
				case VFOFastStepValue::OFF:
					FST->color(FL_BACKGROUND_COLOR);
				break;
			}
			continue;
		}
		else if(cmdtype == "AG")
		{
			VolumeLevel = VolumeLevel::Answer(cmd);
			Volume->value(VolumeLevel);
			Volume->redraw();
			continue;
		}
		else if(cmdtype == "AC")
		{
			switch(AntennaTunerControl::Answer(cmd))
			{
				case TunerState::OFF:
					TNR->color(FL_BACKGROUND_COLOR);
				break;
				case TunerState::ON:
					TNR->color(FL_GREEN);
				break;
				case TunerState::Start:
					TNR->color(FL_GREEN);
				break;
			}
			TNR->redraw();
			continue;
		}
		else if(cmdtype == "PR")
		{
			SpeechProcessorSetting sp = SpeechProcessor::Answer(cmd);
			switch(sp.state)
			{
				case SpeechProcessorState::ON:
					PRC->color(FL_GREEN);
					m_port.writeString(SpeechProcessorLevel::Read());
					PRC->redraw();
				break;
				case SpeechProcessorState::OFF:
					PRC->color(FL_BACKGROUND_COLOR);
					PRC->redraw();
				break;
			}
			switch(sp.type)
			{
				case SpeechProcessorType::Processor:
				{
					
					break;
				}
				case SpeechProcessorType::ParametricEqualizer:
				{

					break;
				}					
			}
			continue;
		}
		else if (cmdtype == "PL")
		{
			ProcessorLevel->value(SpeechProcessorLevel::Answer(cmd));
			ProcessorLevel->redraw();
			continue;
		}
		else if(cmdtype == "NA")
		{
			NarrowState = Narrow::Answer(cmd);
			switch(NarrowState)
			{
				case NarrowValue::ON:
					NAR->color(FL_GREEN);
					NAR->redraw();							
					m_port.writeString(Width::Read());
				break;
				case NarrowValue::OFF:
					NAR->color(FL_BACKGROUND_COLOR);
					NAR->redraw();					
					m_port.writeString(Width::Read());
				break;	
			}
			continue;
		}
		else if(cmdtype == "PS")
		{
			PowerButton->value(PowerSwitch::Answer(cmd));
			
			if(PowerButton->value())
			{
				Init();
				this->redraw();
			}
			else
			{
				this->redraw();				
			}

		
			#ifdef DEBUG
			cout << cmd << endl;
			#endif
			continue;
		}
		else if(cmdtype == "BY")
		{
			BusyState state = Busy::Answer(cmd);
			
			#ifdef DEBUG
			cout << cmd << endl;
			#endif
			continue;
		}		
		else if(cmdtype == "GT")
		{
			AGCReadVal = AGC_FUNCTION::Answer(cmd);	

			continue;
		}
		else if(cmdtype == "MD")
		{
		    mv = OperatingMode::Answer(cmd);			
			CalcMode(mv);
			continue;
		}
		else if(cmdtype == "SH")
		{
			WidthVal = Width::Answer(cmd);	
			CalculateWidth(WidthVal);
			continue;
		}
		else if(cmdtype == "PC")
		{
			PowerControlValue = PowerControl::Answer(cmd);
			PowerButton->value(PowerControlValue);
			PowerButton->redraw();					
			continue;			
		}
		else if(cmdtype == "MS") //meterSw
		{
			MeterTypeValue = MeterSW::Answer(cmd);
			DisplayMode->value(static_cast<int>(MeterTypeValue));
			DisplayMode->redraw();
			
			continue;
		}
		else if(cmdtype == "MG")
		{			
			MicGainValue = MicGain::Answer(cmd);
			MicGain->value(MicGainValue);
			MicGain->redraw();				
			continue;
		}
		else if(cmdtype == "RG")
		{			
			RFGainValue = RFGain::Answer(cmd);
			RFGain->value(RFGainValue);						
			continue;		
		}
		else if(cmdtype == "SQ")
		{
			SquelchLevelValue = SquelchLevel::Answer(cmd);
			Squelch->value(SquelchLevelValue);
			Squelch->redraw();				
			continue;
		}
		else if(cmdtype == "KS")
		{
			KeyerSpeedValue = KeyerSpeed::Answer(cmd);
			KeyerSpeed->value(static_cast<int>(KeyerSpeedValue));	
			KeyerSpeed->redraw();
			continue;
		}
		else if(cmdtype == "KR")
		{
			KeyerValue v = Keyer::Answer(cmd);
			switch(v)
			{
				case KeyerValue::ON:				
					Keyer->color(FL_GREEN);
					KeyerSpeed->set_active();					
					m_port.writeString(KeyerSpeed::Read());
				break;
				case KeyerValue::OFF:
					Keyer->color(FL_BACKGROUND_COLOR);
					KeyerSpeed->clear_active();
				break;
			}
			Keyer->redraw();
			KeyerSpeed->redraw();
			continue;
		}
		else if(cmdtype == "KP")
		{
			KeyPitchValue v = KeyPitch::Answer(cmd);
			KeyerPitch->value( (300 + (static_cast<int>(v) * 10)));		
			KeyerPitch->redraw();
			continue;
		}
		else if(cmdtype == "BI")
		{
			BreakInState s = BreakIn::Answer(cmd);
			switch(s)
			{
				case BreakInState::OFF:
					BreakIn->color(FL_BACKGROUND_COLOR);
				break;
				case BreakInState::ON:
					BreakIn->color(FL_GREEN);
				break;
			}
			BreakIn->redraw();
			continue;
		}
		else if(cmdtype == "VX")
		{
			VoxStatusValue v = VoxStatus::Answer(cmd);
			switch(v)
			{				
				case VoxStatusValue::ON:
					VOX->color(FL_GREEN);
					m_port.writeString(VoxGain::Read());
					m_port.writeString(VoxDelayTime::Read());
				break;
				case VoxStatusValue::OFF:
					VOX->color(FL_BACKGROUND_COLOR);
				break;
			}
			VOX->redraw();
			continue;
		}	
		else if(cmdtype == "MC")
		{
			Yaesu::FT891::Commands::MemoryChannelValue v = Yaesu::FT891::Commands::MemoryChannel::Answer(cmd);
			int memval = static_cast<int>(v);
			continue;
		}
		else if(cmdtype == "VG")
		{
			VoxGainLevelValue = VoxGain::Answer(cmd);
			VoxGainLevel->value(VoxGainLevelValue);
			continue;
		}
		else if(cmdtype == "VD")
		{
			VoxDelayTimeValue = VoxDelayTime::Answer(cmd);
			VoxDelayTime->value(VoxDelayTimeValue);
			continue;
		}
		else if(cmdtype == "LK")
		{
			switch(VFODialLock::Answer(cmd))
			{
				case DialLockValue::ON:
					LOCK->color(FL_GREEN);
				break;
				case DialLockValue::OFF:
					LOCK->color(FL_BACKGROUND_COLOR);
				break;
			}
			LOCK->redraw();
			continue;
		}
		else if(cmdtype == "ST")
		{
			switch(Split::Answer(cmd))
			{
				case SplitValue::OFF:
					SPL->color(FL_BACKGROUND_COLOR);
				break;
				case SplitValue::ON:
					SPL->color(FL_GREEN);
				break;
				case SplitValue::ON_5KU:
					SPL->color(FL_BLUE);
				break;
			}
			SPL->redraw();
			continue;
		}
		else if(cmdtype == "KM")
		{
			KeyerMemoryValue v = KeyerMemory::Answer(cmd);
			switch(v.ChannelNumber)
			{
				case 1:
					CWMemory1Value = v;
					CWMemoryValue1->value(CWMemory1Value.Message.c_str());
					CWMemoryValue1->redraw();
				break;
				case 2:
					CWMemory2Value = v;
					CWMemoryValue2->value(CWMemory2Value.Message.c_str());
					CWMemoryValue2->redraw();
				break;
				case 3:
					CWMemory3Value = v;
					CWMemoryValue3->value(CWMemory3Value.Message.c_str());
					CWMemoryValue3->redraw();
				break;
				case 4:
					CWMemory4Value =  v;
					CWMemoryValue4->value(CWMemory4Value.Message.c_str());
					CWMemoryValue4->redraw();
				break;
				case 5:
					CWMemory5Value = v;
					CWMemoryValue5->value(CWMemory5Value.Message.c_str());
					CWMemoryValue5->redraw();
				break;
			}
			continue;
		}
		else if(cmdtype == "EX") // menu
		{
			#ifdef DEBUG
			cout << cmd << endl;
			#endif
			MenuFunction mf = (MenuFunction)std::stoi(cmd.substr(2,4));
			int val = 0;
			switch(mf)
			{
				
				case MenuFunction::AM_PTT_SELECT:
					AMPTTSelectValue = Menu::AnswerAMPTTSelect(cmd);
					AMPTTSelect->value(static_cast<int>(AMPTTSelectValue));
					AMPTTSelect->redraw();
				break;
				case MenuFunction::SSB_PTT_SELECT:
					SSBPTTSelectValue = Menu::AnswerSSBPTTSelect(cmd);
					SSBPTTSelect->value(static_cast<int>(SSBPTTSelectValue));
					SSBPTTSelect->redraw();
				break;
				case MenuFunction::PKT_PTT_SELECT:
					PktPTTSelectValue = Menu::AnswerPktPTTSelect(cmd);
					PktPTTSelect->value(static_cast<int>(PktPTTSelectValue));
					PktPTTSelect->redraw();
				break;
				case MenuFunction::DATA_PTT_SELECT:
					DATAPTTSelectValue = Menu::AnswerDATAPTTSelect(cmd);
					DATAPTTSelect->value(static_cast<int>(DATAPTTSelectValue));
					DATAPTTSelect->redraw();
				break;
				case MenuFunction::SSB_BFO:
					SSBbfo = Menu::AnswerSSBBFO(cmd);
				break;
				
				case MenuFunction::CW_BFO:
					CWBfo = Menu::AnswerCWBFO(cmd);
				break;
				
				case MenuFunction::RTTY_BFO:
					RTTYBfo = Menu::AnswerRTTYBFO(cmd);
				break;
				
				case MenuFunction::DATA_BFO:
					DATABfo = Menu::AnswerDATABFO(cmd);
				break;
				
				case MenuFunction::DIMMER_BACKLIT:
					dimmerBacklightval = Menu::AnswerBackliteDimmer(cmd);
					Backlight->value(dimmerBacklightval);
					Backlight->redraw();	
				break;
				
				case MenuFunction::HF_PWR:				
					hfPowerval = Menu::AnswerHfPwr(cmd);
					HFPower->value(hfPowerval);
					HFPower->redraw();					
				break;
				
				case MenuFunction::HF_AM_PWR:
					HFAmPowerval = Menu::AnswerHfAmPwr(cmd);
					HFAMPower->value(HFAmPowerval);
					HFAMPower->redraw();					
				break;
				
				case MenuFunction::HF_SSB_PWR:
					HFSsbPowerval = Menu::AnswerHfSsbPwr(cmd);
					HFSSBPower->value(HFSsbPowerval);
					HFSSBPower->redraw();					
				break;
				
				case MenuFunction::VHF_PWR:
					vhfpowerval = Menu::Answer50mPwr(cmd);
					VHFPower->value(vhfpowerval);
					VHFAMPower->redraw();					
				break;
				
				case MenuFunction::SSB_POWER_50M:
					vhfssbpowerval = Menu::Answer50mSsbPwr(cmd);
					VHFSSBPower->value(vhfssbpowerval);
					VHFSSBPower->redraw();					
				break;
				
				case MenuFunction::AM_POWER_50M:
					vhfampowerval = Menu::Answer50mAmPwr(cmd);
					VHFAMPower->value(vhfampowerval);
					VHFAMPower->redraw();					
				break;

				case MenuFunction::LCD_CONTRAST:
					lcdcontrastval = Menu::AnswerLcdContrast(cmd);
					LCDContrast->value(lcdcontrastval);
					LCDContrast->redraw();
				break;

				case MenuFunction::DIMMER_LCD:
					dimmerval = Menu::AnswerLcdDimmer(cmd); 
					LCD->value(dimmerval);
					LCD->redraw();
				break;
				case MenuFunction::DIMMER_TX_BUSY:
					dimmmertxbusyval = Menu::AnswerTxBusyDimmer(cmd); 
					TxBusy->value(dimmmertxbusyval);
					TxBusy->redraw();
				break;
				
				case MenuFunction::AM_LCUT_FREQ:
					AMLCUTFreqValue = Menu::AnswerAMLowCutFreq(cmd);
					AMLCUTFreq->value(static_cast<int>(AMLCUTFreqValue));
					AMLCUTFreq->redraw();
				break;

				case MenuFunction::AM_LCUT_SLOPE:
					AMLCUTSlopeValue = Menu::AnswerAMLowCutSlope(cmd);
					AMLCUTSlope->value(static_cast<int>(AMLCUTSlopeValue));
					AMLCUTSlope->redraw();
				break;

				case MenuFunction::AM_OUT_LEVEL:
					AMOutLevelValue = Menu::AnswerAMOutLevel(cmd);
					AMOutLevel->value(AMOutLevelValue);
					AMOutLevel->redraw();
				break;

				case MenuFunction::CW_LCUT_FREQ:
					CWLCUTFreqValue = Menu::AnswerCWLowCutFreq(cmd);
					CWLCUTFreq->value(static_cast<int>(CWLCUTFreqValue));
					CWLCUTFreq->redraw();
				break;

				case MenuFunction::CW_LCUT_SLOPE:
					CWLCUTSlopeValue = Menu::AnswerCWLowCutSlope(cmd);
					CWLCUTSlope->value(static_cast<int>(CWLCUTSlopeValue));
					CWLCUTSlope->redraw();
				break;

				case MenuFunction::CW_OUT_LEVEL:
					CWOutLevelValue = Menu::AnswerCWOutLevel(cmd);
					CWOutLevel->value(CWOutLevelValue);
					CWOutLevel->redraw();
				break;
				
				case MenuFunction::RTTY_LCUT_FREQ:
					RTTYLCUTFreqValue = Menu::AnswerRTTYLowCutFreq(cmd);
					RTTYLCUTFreq->value(static_cast<int>(RTTYLCUTFreqValue));
					RTTYLCUTFreq->redraw();
				break;

				case MenuFunction::RTTY_LCUT_SLOPE:
					RTTYLCUTSlopeValue = Menu::AnswerRTTYLowCutSlope(cmd);
					RTTYLCUTSlope->value(static_cast<int>(RTTYLCUTSlopeValue));
					RTTYLCUTSlope->redraw();
				break;

				case MenuFunction::RTTY_OUT_LEVEL:
					RTTYOutLevelValue = Menu::AnswerRTTYOutLevel(cmd);
					RTTYOutLevel->value(RTTYOutLevelValue);
					RTTYOutLevel->redraw();
				break;

				case MenuFunction::DATA_LCUT_FREQ:
					DATALCUTFreqValue = Menu::AnswerDATALowCutFreq(cmd);
					DATALCUTFreq->value(static_cast<int>(DATALCUTFreqValue));
					DATALCUTFreq->redraw();
				break;

				case MenuFunction::DATA_LCUT_SLOPE:
					DATALCUTSlopeValue = Menu::AnswerDATALowCutSlope(cmd);
					DATALCUTSlope->value(static_cast<int>(DATALCUTSlopeValue));
					DATALCUTSlope->redraw();
				break;

				case MenuFunction::DATA_OUT_LEVEL:
					DATAOutLevelValue = Menu::AnswerDATAOutLevel(cmd);
					DATAOutLevel->value(DATAOutLevelValue);
					DATAOutLevel->redraw();
				break;

				case MenuFunction::SSB_LCUT_FREQ:
					SSBLCUTFreqValue = Menu::AnswerSSBLowCutFreq(cmd);
					SSBLCUTFreq->value(static_cast<int>(SSBLCUTFreqValue));
					SSBLCUTFreq->redraw();
				break;

				case MenuFunction::SSB_LCUT_SLOPE:
					SSBLCUTSlopeValue = Menu::AnswerSSBLowCutSlope(cmd);
					SSBLCUTSlope->value(static_cast<int>(SSBLCUTSlopeValue));
					SSBLCUTSlope->redraw();
				break;

				case MenuFunction::SSB_OUT_LEVEL:
					SSBOutLevelValue = Menu::AnswerSSBOutLevel(cmd);
					SSBOutLevel->value(SSBOutLevelValue);
					SSBOutLevel->redraw();
				break;
				
				case MenuFunction::CLAR_SELECT:
					ClarifierTypeValue = Menu::AnswerClarSelect(cmd);
					ClarifierType->value(static_cast<int>(ClarifierTypeValue));
					ClarifierType->redraw();
				break;
				case MenuFunction::EQ1_FREQ:
					MicCenterFreq1Value = Menu::AnswerEQ1Freq(cmd);
					MicCenterFreq1->value(static_cast<int>(MicCenterFreq1Value));
					MicCenterFreq1->redraw();
					
				break;
				case MenuFunction::EQ1_BWTH:			
					MicBandWidth1Value = Menu::AnswerEQ1Bwth(cmd);		
					MicBandWidth1->value(MicBandWidth1Value);
					MicBandWidth1->redraw();
				break;
				case MenuFunction::EQ1_LEVEL:
					MicEq1LevelValue = Menu::AnswerEQ1Level(cmd);
					MicEQLevel1->value(MicEq1LevelValue);
					MicEQLevel1->redraw();
				break;
				case MenuFunction::EQ2_FREQ:
					MicCenterFreq2Value = Menu::AnswerEQ2Freq(cmd);
					MicCenterFreq2->value(static_cast<int>(MicCenterFreq2Value));
					MicCenterFreq2->redraw();
				break;
				case MenuFunction::EQ2_BWTH:
				    MicBandWidth2Value = Menu::AnswerEQ2Bwth(cmd);
					MicBandWidth2->value(MicBandWidth2Value);
					MicBandWidth2->redraw();
				break;
				case MenuFunction::EQ2_LEVEL:
					MicEq2LevelValue = Menu::AnswerEQ2Level(cmd);
					MicEQLevel2->value(MicEq2LevelValue);
					MicEQLevel2->redraw();
				break;
				case MenuFunction::EQ3_FREQ:
					MicCenterFreq3Value = Menu::AnswerEQ3Freq(cmd);
					MicCenterFreq3->value(static_cast<int>(MicCenterFreq3Value));
					MicCenterFreq3->redraw();
					m_port.writeString(Menu::ReadEQ3Level());
					m_port.writeString(Menu::ReadEQ3Bwth());
				break;
				case MenuFunction::EQ3_BWTH:
					MicBandWidth3Value = Menu::AnswerEQ3Bwth(cmd);
					MicBandWidth3->value(MicBandWidth3Value);
					MicBandWidth3->redraw();
				break;
				case MenuFunction::EQ3_LEVEL:
					MicEq3LevelValue = Menu::AnswerEQ3Level(cmd);
					MicEQLevel3->value(MicEq3LevelValue);
					MicEQLevel3->redraw();
				break;
				case MenuFunction::P_EQ1_FREQ:
					MicPCenterFreq1Value = Menu::AnswerPEQ1Freq(cmd);
					MicPCenterFreq1->value(static_cast<int>(MicPCenterFreq1Value));
					MicPCenterFreq1->redraw();
				break;
				case MenuFunction::P_EQ1_BWTH:
					MicPBandWidth1Value = Menu::AnswerPEQ1Bwth(cmd);
					MicPBandWidth1->value(MicPBandWidth1Value);
					MicPBandWidth1->redraw();
				break;
				case MenuFunction::P_EQ1_LEVEL:
					MicPEq1LevelValue = Menu::AnswerPEQ1Level(cmd);
					MicPEQLevel1->value(MicPEq1LevelValue);
					MicPEQLevel1->redraw();
				break;
				case MenuFunction::P_EQ2_FREQ:
					MicPCenterFreq2Value = Menu::AnswerPEQ2Freq(cmd);
					MicPCenterFreq2->value(static_cast<int>(MicPCenterFreq2Value));
					MicPCenterFreq2->redraw();
				break;
				case MenuFunction::P_EQ2_BWTH:
					MicPBandWidth2Value = Menu::AnswerPEQ2Bwth(cmd);
					MicPBandWidth2->value(MicPBandWidth2Value);
					MicPBandWidth2->redraw();
				break;
				case MenuFunction::P_EQ2_LEVEL:
					MicPEq2LevelValue = Menu::AnswerPEQ2Level(cmd);
					MicPEQLevel2->value(MicPEq2LevelValue);
					MicPEQLevel2->redraw();
				break;
				case MenuFunction::P_EQ3_FREQ:
					MicPCenterFreq3Value = Menu::AnswerPEQ3Freq(cmd);
					MicPCenterFreq3->value(static_cast<int>(MicPCenterFreq3Value));
					MicPCenterFreq3->redraw();

				break;
				case MenuFunction::P_EQ3_BWTH:
					MicPBandWidth3Value = Menu::AnswerPEQ3Bwth(cmd);
					MicPBandWidth3->value(MicPBandWidth3Value);
					MicPBandWidth3->redraw();
				break;
				case MenuFunction::P_EQ3_LEVEL:
					MicPEq3LevelValue = Menu::AnswerPEQ3Level(cmd);
					MicPEQLevel3->value(MicPEq3LevelValue);
					MicPEQLevel3->redraw();
				break;
				case MenuFunction::APO:
					APOVal = Menu::AnswerApo(cmd);
					APO->value(static_cast<int>(APOVal));
					APO->redraw();
				break;
				case MenuFunction::FAN_CONTROL:
					FanControlVal = Menu::AnswerFanControl(cmd);
					FanControl->value(static_cast<int>(FanControlVal));
					FanControl->redraw();
				break;
				case MenuFunction::MEM_GROUP:
					MemoryGroupValue = Menu::AnswerMemGroup(cmd);
					MemGroup->value(static_cast<int>(MemoryGroupValue));
					MemGroup->redraw();
				break;
				case MenuFunction::FM_SETTING:
					FMSettingValue = Menu::AnswerFMSetting(cmd);
					FMSetting->value(static_cast<int>(FMSettingValue));
					FMSetting->redraw();
				break;
				case MenuFunction::REC_SETTING:
					RecSettingValue = Menu::AnswerRecSetting(cmd);
					RECSetting->value(static_cast<int>(RecSettingValue));
					RECSetting->redraw();
				break;
				case MenuFunction::ATAS_SETTING:
					ATASSettingValue = Menu::AnswerATASSetting(cmd);
					ATASSetting->value(static_cast<int>(ATASSettingValue));
					ATASSetting->redraw();
				break;
				case MenuFunction::TX_TOT:
					TXTOTValue = Menu::AnswerTXTOT(cmd);
					TXTot->value(TXTOTValue);
					TXTot->redraw();
				break;
				case MenuFunction::MIC_SCAN:
					MicScanValue = Menu::AnswerMicScan(cmd);
					MicScan->value(static_cast<int>(MicScanValue));
					MicScan->redraw();
				break;
				case MenuFunction::MIC_SCAN_RESUME:
					MicScanResumeVal = Menu::AnswerMicScanResume(cmd);
					MicScanResume->value(static_cast<int>(MicScanResumeVal));
					MicScanResume->redraw();
				break;
				case MenuFunction::CW_BK_IN_TYPE:
					CWBreakInTypeValue = Menu::AnswerCWBreakInType(cmd);
					CWBreakInType->value(static_cast<int>(CWBreakInTypeValue));
					CWBreakInType->redraw();
				break;
				case MenuFunction::CW_WAVE_SHAPE: 
				{
					CwWaveShapeVal = Menu::AnswerCWWaveShape(cmd);					
					CWWaveShape->value(static_cast<int>(CwWaveShapeVal) - 1);
					CWWaveShape->redraw();
				}
				break;
				case MenuFunction::CW_FREQ_DISPLAY:
					CWFreqDisplayVal = Menu::AnswerCWFreqDisplay(cmd);
					CWFreqDisplay->value(static_cast<int>(CWFreqDisplayVal));
					CWFreqDisplay->redraw();
				break;
				case MenuFunction::PC_KEYING:
					PCKeyingVal = Menu::AnswerPCKeying(cmd);
					PCKeying->value(static_cast<int>(PCKeyingVal));
					PCKeying->redraw();
				break;
				case MenuFunction::QSK_DELAY_TIME:
					QSKDelayTimeVal = Menu::AnswerQSKDelayTime(cmd);
					QSKDelayTime->value(static_cast<int>(QSKDelayTimeVal));
					QSKDelayTime->redraw();
				break;
				case MenuFunction::DATA_MODE:
					DataModeVal = Menu::AnswerDataMode(cmd);
					DataMode->value(static_cast<int>(DataModeVal));
					DataMode->redraw();
				break;
				case MenuFunction::PSK_TONE:
					PSKToneVal = Menu::AnswerPSKTone(cmd);
					PSKTone->value(static_cast<int>(PSKToneVal));
					PSKTone->redraw();
				break;
				case MenuFunction::AGC_FAST_DELAY:
					AGCFastDelayValue = Menu::AnswerAgcFastDelay(cmd);
					AGCFastDelay->value(AGCFastDelayValue);
					AGCFastDelay->redraw();
				break;
				case MenuFunction::AGC_MID_DELAY:
					AGCMidDelayValue = Menu::AnswerAgcMidDelay(cmd);
					AGCMidDelay->value(AGCMidDelayValue);
					AGCMidDelay->redraw();
				break;
				case MenuFunction::AGC_SLOW_DELAY:
					AGCSlowDelayValue = Menu::AnswerAgcSlowDelay(cmd);
					AGCSlowDelay->value(AGCSlowDelayValue);
					AGCSlowDelay->redraw();
				break;
				case MenuFunction::KEYER_TYPE:
					KeyerTypeVal = Menu::AnswerKeyerType(cmd);
					KeyerType->value(static_cast<int>(KeyerTypeVal));
					KeyerType->redraw();
				break;
				case MenuFunction::KEYER_DOT_DASH_ORDER:
					KeyerDotDashVal = Menu::AnswerKeyerDotDash(cmd);
					KeyerDotDash->value(static_cast<int>(KeyerDotDashVal));
					KeyerDotDash->redraw();
				break;
				case MenuFunction::CW_WEIGHT:
					CWWeightValue = Menu::AnswerCwWeight(cmd) - 25;
					CWWeight->value(CWWeightValue);
					CWWeight->redraw();
				break;
				case MenuFunction::CW_MEMORY_1:
					CWMemory1Val = 	Menu::AnswerCWMemory1(cmd);
					CWMemory1Setting->value(static_cast<int>(CWMemory1Val));
					CWMemory1Setting->redraw();
				break;
				case MenuFunction::CW_MEMORY_2:
					CWMemory2Val = Menu::AnswerCWMemory2(cmd);
					CWMemory2Setting->value(static_cast<int>(CWMemory2Val));
					CWMemory2Setting->redraw();
				break;
				case MenuFunction::CW_MEMORY_3:
					CWMemory3Val = Menu::AnswerCWMemory3(cmd);
					CWMemory3Setting->value(static_cast<int>(CWMemory3Val));
					CWMemory3Setting->redraw();
				break;
				case MenuFunction::CW_MEMORY_4:
					CWMemory4Val = Menu::AnswerCWMemory4(cmd);
					CWMemory4Setting->value(static_cast<int>(CWMemory4Val));
					CWMemory4Setting->redraw();
				break;
				case MenuFunction::CW_MEMORY_5:
					CWMemory5Val = Menu::AnswerCWMemory5(cmd);
					CWMemory5Setting->value(static_cast<int>(CWMemory5Val));
					CWMemory5Setting->redraw();
				break;
				case MenuFunction::CAT_RATE:
					CatRateSelectValue = Menu::AnswerCatRate(cmd);
					CatRateSelect->value(static_cast<int>(CatRateSelectValue));
					CatRateSelect->redraw();
				break;
				case MenuFunction::CAT_TOT:
					CatTOTSelectValue = Menu::AnswerCatTOT(cmd);
					CatTOTSelect->value(static_cast<int>(CatTOTSelectValue));
					CatTOTSelect->redraw();
				break;
			}
			continue;
		}
		else if(cmdtype == "RI")
		{
			Yaesu::FT891::Commands::RadioInfoVal val = RadioInformation::Answer(cmd);
			switch(val.Type)
			{
				case InformationType::TX_LED:
					if(val.Value == InformationState::ON)
						StatusLED->color(FL_RED);
					else
						StatusLED->color(FL_BACKGROUND_COLOR);
				break;
				case InformationType::RX_LED:
					if(val.Value == InformationState::ON)
						StatusLED->color(FL_BLUE);
					else
						StatusLED->color(FL_BACKGROUND_COLOR);
				break;
				case InformationType::HI_SWR:
					if(val.Value == InformationState::ON)
					{
						///m_port.writeString(Yaesu::FT891::Commands::TXW::Set(TXWValue::OFF));
						StatusLED->color(fl_rgb_color(255,165,0));						
					}
					else
						StatusLED->color(FL_BACKGROUND_COLOR);
				break;
				case InformationType::PLAY:
					if(val.Value == InformationState::ON)
					{
						StatusLED->color(FL_BLACK);
						StatusLED->color2(FL_BLUE);
						StatusLED->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER);
						StatusLED->label("►");
					}
					else
					{
						StatusLED->color(FL_BACKGROUND2_COLOR);
						StatusLED->color2(FL_BACKGROUND2_COLOR);
						StatusLED->label("");
					}
				break;
				case InformationType::REC:
					if(val.Value == InformationState::ON)
					{
						StatusLED->color(FL_GREEN);
					}
					else
					{
						StatusLED->color(FL_BACKGROUND_COLOR);
					}
				break;
			}
			StatusLED->redraw();
			Fl::redraw();
		}
		else if(cmdtype == "RM")
		{
			MeterVal val = ReadMeter::Answer(cmd);
			switch(val.Type)
			{
				
				case ReadMeterType::S:
					SMeterLevel = val.Value;
				break;
				case ReadMeterType::COMP:
					CompLevel = val.Value;
				break;
				case ReadMeterType::ALC:
					ALCLevel = val.Value;
				break;
				case ReadMeterType::PO:
					POLevel = val.Value;
				break;
				case ReadMeterType::SWR:
					SwrLevel = val.Value;
				break;
				case ReadMeterType::ID:
					IDLevel = val.Value;
				break;	
				case ReadMeterType::AutoA:
					
				break;
				case ReadMeterType::AutoB:
				 	switch((MeterType)this->DisplayMode->value())
					 {
						 case MeterType::COMP:
							CompLevel = val.Value;
						 break;
						 case MeterType::ALC:
							ALCLevel = val.Value;
						 break;
						 case MeterType::PO:
							POLevel = val.Value;
						 break;
						 case MeterType::SWR:
							SwrLevel = val.Value;
						 break;
						 case MeterType::ID:
							IDLevel = val.Value;
						 break;
					 }
				break;				
			}
		}
		else
		{	
			#ifdef DEBUG	
				cout << "Unhandled: " <<  cmd << endl;
			#endif
			continue;
		}	
	}
	
		this->flush(true);	    
		Fl::unlock();
		Fl::awake();
	}
	catch(std::exception& e)
	{
		std::cout << e.what() << std::endl;
	}
}

void OnLightButtonClick(Fl_Light_Button* o, void* v)
{
	FT891* window = reinterpret_cast<FT891*>(v);
	window->OnPowerButtonClick(o, v);
}

void OnScrollBar(Fl_Value_Slider* o, void* v)
{
	FT891* window = (FT891*)v;
	window->OnScroll(o, v);
}

void OnChoice(Fl_Widget* pitem, void* v)
{
	FT891* pwin = (FT891*)v;
	pwin->SetMeterType(pitem,v);
}

void OnRoll(Fl_Value_Slider* o , void* v)
{
	FT891* pwin = (FT891*)v;
	pwin->OnRoll(o,v);
}

void OnOperatingMode(Fl_Widget* o, void* v)
{
    FT891* window = (FT891*)v;
	window->SetOperatingMode();
}

void OnCounter(Fl_Widget* o,void* v)
{
	FT891* window = (FT891*)v;
	window->OnCounter((Fl_Counter*)o,v);
}

void FT891::OnCounter(Fl_Counter* c, void* v)
{
	if(Clarifier->value() == 0)
	{
		ClarifierValue = 0;
		m_port.writeString(ClarClear::Set());
	}
	else if(Clarifier->value() > ClarifierValue)
	{
		int current = Clarifier->value();
		m_port.writeString(RxClarifierPlusOffset::Set(std::abs(ClarifierValue - current)));
	}
	else
	{
		int current = Clarifier->value();
		m_port.writeString(ClarDown::Set(std::abs(ClarifierValue - current)));
	}
}

void FT891::SetOperatingMode()
{
	int val = OperatingMode->value();

	switch(val)
	{
		case 3:
		case 4:
		case 5:
			MicGain->hide();
			KeyerSpeed->show();
			if(VOX->color() == FL_GREEN)
			{
				m_port.writeString(VoxStatus::Set(VoxStatusValue::OFF));
			}	
			VOX->hide();
			//VoxGainLevel->hide();
			//VoxDelayTime->hide();
			Keyer->show();
			KeyerPitch->show();
			BreakIn->show();
			PRC->hide();			
		break;
		default:
			MicGain->show();
			KeyerSpeed->hide();	
			Keyer->hide();
			VOX->show();
			PRC->show();
			BreakIn->hide();
			KeyerPitch->hide();
		break;
	}

	switch(val)
	{
		case 0://"USB", 0, O
			m_port.writeString(Menu::SetSSBBFO(BfoValue::USB));
			m_port.writeString(OperatingMode::Set(ModeValue::SSB_BFOA));
			
		break;
		case 1://"LSB", 0, O
			m_port.writeString(Menu::SetSSBBFO(BfoValue::LSB));
			m_port.writeString(OperatingMode::Set(ModeValue::SSB_BFOA));
			
		break;
		case 2:	//"SSB-AUTO",	
			m_port.writeString(Menu::SetSSBBFO(BfoValue::AUTO));
			m_port.writeString(OperatingMode::Set(ModeValue::SSB_BFOA));
		
		break;
		case 3://"CW-L",0,On
			m_port.writeString(Menu::SetCWBFO(BfoValue::LSB));
			m_port.writeString(OperatingMode::Set(ModeValue::CW_BFOA));
		
		break;
		case 4://"CW-U", 0 ,
			m_port.writeString(Menu::SetCWBFO(BfoValue::USB));
			m_port.writeString(OperatingMode::Set(ModeValue::CW_BFOA));
			
		break;
		case 5://"CW-AUTO", 
			m_port.writeString(Menu::SetCWBFO(BfoValue::AUTO));
			m_port.writeString(OperatingMode::Set(ModeValue::CW_BFOA));
	
		break;
		case 6:	//"FM",0,OnOp		
			
			m_port.writeString(OperatingMode::Set(ModeValue::FM));
			
		break;
		case 7://"FM-N",0, O
			//m_port.writeString(Narrow::Set(NarrowValue::ON));
			m_port.writeString(OperatingMode::Set(ModeValue::FM_N));
		
		break;
		case 8:	//"AM",0,OnOp		
			//m_port.writeString(Narrow::Set(NarrowValue::OFF));
			m_port.writeString(OperatingMode::Set(ModeValue::AM));
		
		break;
		case 9://"AM-N",0,On
			//m_port.writeString(Narrow::Set(NarrowValue::ON));
			m_port.writeString(OperatingMode::Set(ModeValue::AM_N));
			
		break;
		case 10:			
			m_port.writeString(Menu::SetDATABFO(DataBfoValue::USB));
			m_port.writeString(OperatingMode::Set(ModeValue::DATA_BFOA));
					
		break;
		case 11:			
			m_port.writeString(Menu::SetDATABFO(DataBfoValue::LSB));
			m_port.writeString(OperatingMode::Set(ModeValue::DATA_BFOB));
		
		break;
		case 12:
			m_port.writeString(Menu::SetRTTYBFO(DataBfoValue::USB));
			m_port.writeString(OperatingMode::Set(ModeValue::RTTY_BFOA));
			
		break;
		case 13:
			m_port.writeString(Menu::SetRTTYBFO(DataBfoValue::LSB));
			m_port.writeString(OperatingMode::Set(ModeValue::RTTY_BFOB));
		
		break;
	}
}

void FT891::SetMeterType(Fl_Widget* pitem, void*)
{
	if(DisplayMode == pitem){
		m_port.writeString(MeterSW::Set((MeterType)DisplayMode->value()));
	}
	else if(pitem == Width)
	{
		UIMode m = GetUIMode();
					
		WidthValue v;
		v.State = WidthState::ON;
		bool Narrow = NAR->color() == FL_GREEN;
		switch(m)
		{
		case UIMode::SSB:
				v.WidthCommand = (Narrow? 1 : 9) + Width->value();
		break;
		case UIMode::CW:						
		case UIMode::RTTY:													
			    v.WidthCommand = (Narrow? 1 : 10) + Width->value();
		break;
		}
		m_port.writeString(Width::Set(v));
						
	}
	else if(pitem == Band)
	{
		m_port.writeString(BandSelect::Set((Yaesu::FT891::Commands::Band) Band->value()));
	}
	else if(pitem == AMLCUTFreq)
	{
		m_port.writeString(Menu::SetAMLowCutFreq((FreqLowCutValue)AMLCUTFreq->value()));
	}
	else if(pitem == AMLCUTSlope)
	{
		m_port.writeString(Menu::SetAMLowCutSlope((FreqSlopeValue)AMLCUTSlope->value()));
	}
	else if(pitem == AMHCUTFreq)
	{
		m_port.writeString(Menu::SetAMHighCutFreq((FreqHighCutValue)AMHCUTFreq->value()));
	}
	else if(pitem == AMHCUTSlope)
	{
		m_port.writeString(Menu::SetAMHighCutSlope((FreqSlopeValue)AMHCUTSlope->value()));
	}
	else if(pitem == CWLCUTFreq)
	{
		m_port.writeString(Menu::SetCWLowCutFreq((FreqLowCutValue)CWLCUTFreq->value()));
	}
	else if(pitem == CWLCUTSlope)
	{
		m_port.writeString(Menu::SetCWLowCutSlope((FreqSlopeValue)CWLCUTSlope->value()));
	}
	else if(pitem == CWHCUTFreq)
	{
		m_port.writeString(Menu::SetCWHighCutFreq((FreqHighCutValue)CWHCUTFreq->value()));
	}
	else if(pitem == CWHCUTSlope)
	{
		m_port.writeString(Menu::SetCWHighCutSlope((FreqSlopeValue)CWHCUTSlope->value()));
	}
	else if(pitem == RTTYLCUTFreq)
	{
		m_port.writeString(Menu::SetRTTYLowCutFreq((FreqLowCutValue)RTTYLCUTFreq->value()));
	}
	else if(pitem == RTTYLCUTSlope)
	{
		m_port.writeString(Menu::SetRTTYLowCutSlope((FreqSlopeValue)RTTYLCUTSlope->value()));
	}
	else if(pitem == RTTYHCUTFreq)
	{
		m_port.writeString(Menu::SetRTTYHighCutFreq((FreqHighCutValue)RTTYHCUTFreq->value()));
	}
	else if(pitem == RTTYHCUTSlope)
	{
		m_port.writeString(Menu::SetRTTYHighCutSlope((FreqSlopeValue)RTTYHCUTSlope->value()));
	}
		else if(pitem == DATALCUTFreq)
	{
		m_port.writeString(Menu::SetDATALowCutFreq((FreqLowCutValue)DATALCUTFreq->value()));
	}
	else if(pitem == DATALCUTSlope)
	{
		m_port.writeString(Menu::SetDATALowCutSlope((FreqSlopeValue)DATALCUTSlope->value()));
	}
	else if(pitem == DATAHCUTFreq)
	{
		m_port.writeString(Menu::SetDATAHighCutFreq((FreqHighCutValue)DATAHCUTFreq->value()));
	}
	else if(pitem == DATAHCUTSlope)
	{
		m_port.writeString(Menu::SetDATAHighCutSlope((FreqSlopeValue)DATAHCUTSlope->value()));
	}
		else if(pitem == SSBLCUTFreq)
	{
		m_port.writeString(Menu::SetSSBLowCutFreq((FreqLowCutValue)SSBLCUTFreq->value()));
	}
	else if(pitem == SSBLCUTSlope)
	{
		m_port.writeString(Menu::SetSSBLowCutSlope((FreqSlopeValue)SSBLCUTSlope->value()));
	}
	else if(pitem == SSBHCUTFreq)
	{
		m_port.writeString(Menu::SetSSBHighCutFreq((FreqHighCutValue)SSBHCUTFreq->value()));
	}
	else if(pitem == SSBHCUTSlope)
	{
		m_port.writeString(Menu::SetSSBHighCutSlope((FreqSlopeValue)SSBHCUTSlope->value()));
	}
	else if(pitem == TunerType)
	{
		m_port.writeString(Menu::SetTunerSelect(static_cast<TunerSelectValue>(TunerType->value())));
	}
	else if(pitem == ClarifierType)
	{
		m_port.writeString(Menu::SetClarSelect(static_cast<ClarSelectValue>(ClarifierType->value())));
	}
	else if(pitem == MicCenterFreq1)
	{
		m_port.writeString(Menu::SetEQ1Freq(static_cast<EQ1FreqValue>(MicCenterFreq1->value())));
	}
	else if(pitem == MicCenterFreq2)
	{
		m_port.writeString(Menu::SetEQ2Freq(static_cast<EQ2FreqValue>(MicCenterFreq2->value())));
	}
	else if(pitem == MicCenterFreq3)
	{
		m_port.writeString(Menu::SetEQ3Freq(static_cast<EQ3FreqValue>(MicCenterFreq3->value())));
	}
	else if(pitem == MicPCenterFreq1)
	{
		m_port.writeString(Menu::SetPEQ1Freq(static_cast<EQ1FreqValue>(MicPCenterFreq1->value())));
	}
	else if(pitem == MicPCenterFreq2)
	{
		m_port.writeString(Menu::SetPEQ2Freq(static_cast<EQ2FreqValue>(MicPCenterFreq2->value())));
	}
	else if(pitem == MicPCenterFreq3)
	{
		m_port.writeString(Menu::SetPEQ3Freq(static_cast<EQ3FreqValue>(MicPCenterFreq3->value())));
	}
	else if(pitem == APO)
	{
		m_port.writeString(Menu::SetApo(static_cast<APOValue>(APO->value())));
	}
	else if(pitem == FanControl)
	{
		m_port.writeString(Menu::SetFanControl(static_cast<FanControlValue>(FanControl->value())));
	}
	else if(pitem == MemGroup)
	{
		m_port.writeString(Menu::SetMemGroup(static_cast<EnableDisableValue>(MemGroup->value())));
	}
	else if(pitem == FMSetting)
	{
		m_port.writeString(Menu::SetFMSetting(static_cast<EnableDisableValue>(FMSetting->value())));
	}
	else if(pitem == RECSetting)
	{
		m_port.writeString(Menu::SetRecSetting(static_cast<EnableDisableValue>(RECSetting->value())));
	}
	else if(pitem == ATASSetting)
	{
		m_port.writeString(Menu::SetATASSetting(static_cast<EnableDisableValue>(ATASSetting->value())));
	}
	else if(pitem == TXTot)
	{
		m_port.writeString(Menu::SetTxTOT(TXTot->value()));
	}
	else if(pitem == MicScan)
	{
		m_port.writeString(Menu::SetMicScan(static_cast<EnableDisableValue>(MicScan->value())));
	}
	else if(pitem == MicScanResume)
	{
		m_port.writeString(Menu::SetMicScanResume(static_cast<MicScanResumeValue>(MicScanResume->value())));
	}
	else if(pitem == CWBreakInType)
	{
	   	m_port.writeString(Menu::SetCWBreakkInType(static_cast<CwBreakInType>(CWBreakInType->value())));
	}
	else if(pitem == CWWaveShape)
	{
		m_port.writeString(Menu::SetCWWaveShape(static_cast<CwWaveShapeValue>(CWWaveShape->value() + 1)));
	}
	else if(pitem == CWFreqDisplay)
	{
		m_port.writeString(Menu::SetCWFreqDisplay(static_cast<CwFreqDisplayValue>(CWFreqDisplay->value())));
	}
	else if(pitem == PCKeying)
	{
		m_port.writeString(Menu::SetPCKeying(static_cast<PCKeyingValue>(PCKeying->value())));
	}
	else if(pitem == QSKDelayTime)
	{
		m_port.writeString(Menu::SetQSKDelayTime(static_cast<QskDelayTimeValue>(QSKDelayTime->value())));
	}
	else if(pitem == DataMode)
	{
		m_port.writeString(Menu::SetDataMode(static_cast<DataModeValue>(DataMode->value())));
	}
	else if(pitem == PSKTone)
	{
		m_port.writeString(Menu::SetPSKTone(static_cast<PSKToneValue>(PSKTone->value())));
	}
	else if(pitem == KeyerType)
	{
		string s = Menu::SetKeyerType(static_cast<KeyerTypeValue>(KeyerType->value()));
		m_port.writeString(s);
	}
	else if(pitem == KeyerDotDash)
	{
		m_port.writeString(Menu::SetKeyerDotDash(static_cast<KeyerDotDashValue>(KeyerDotDash->value())));		
	}
	else if(pitem == CWWeight)
	{
		m_port.writeString(Menu::SetCwWeight(CWWeight->value() + 25));
	}
	else if(pitem == CWMemory1Setting)
	{
		m_port.writeString(Menu::SetCWMemory1(static_cast<CWMemoryTypeValue>(CWMemory1Setting->value())));
	}
	else if(pitem == CWMemory2Setting)
	{
		m_port.writeString(Menu::SetCWMemory2(static_cast<CWMemoryTypeValue>(CWMemory2Setting->value())));
	}
	else if(pitem == CWMemory3Setting)
	{
		m_port.writeString(Menu::SetCWMemory3(static_cast<CWMemoryTypeValue>(CWMemory3Setting->value())));
	}
	else if(pitem == CWMemory4Setting)
	{
		m_port.writeString(Menu::SetCWMemory4(static_cast<CWMemoryTypeValue>(CWMemory4Setting->value())));
	}
	else if(pitem == CWMemory5Setting)
	{
		m_port.writeString(Menu::SetCWMemory5(static_cast<CWMemoryTypeValue>(CWMemory5Setting->value())));
	}
	else if(pitem == AMPTTSelect)
	{
		m_port.writeString(Menu::SetAMPTTSelect(static_cast<PTTSelectValue>(AMPTTSelect->value())));
	}
	else if(pitem == SSBPTTSelect)
	{
		m_port.writeString(Menu::SetSSBPTTSelect(static_cast<PTTSelectValue>(SSBPTTSelect->value())));
	}
	else if(pitem == DATAPTTSelect)
	{
		m_port.writeString(Menu::SetDATAPTTSelect(static_cast<PTTSelectValue>(DATAPTTSelect->value())));
	}
	else if(pitem == PCKeying)
	{
		m_port.writeString(Menu::SetPCKeying(static_cast<PCKeyingValue>(PCKeying->value())));
	}
	else if(pitem == PktPTTSelect)
	{
		m_port.writeString(Menu::SetPktPTTSelect(static_cast<PTTSelectValue>(PktPTTSelect->value())));
	}
	else if(pitem == CatRateSelect)
	{
		m_port.writeString(Menu::SetCatRate(static_cast<CatRateValue>(CatRateSelect->value())));
	}
	else if(pitem == CatTOTSelect)
	{
		m_port.writeString(Menu::SetCatTOT(static_cast<CatTOTValue>(CatTOTSelect->value())));
	}
    
}

void FT891::OnScroll(Fl_Value_Slider* o, void* v)
{
	FT891* window = (FT891*)v;
	int val = o->value();

	if (o == HFPower)
	{
		m_port.writeString(Menu::SetHfPwr(val));
	}
	else if (o == HFSSBPower)
	{
		m_port.writeString(Menu::SetHfSsbPwr(val));
	}
	else if (o == HFAMPower)
	{
		m_port.writeString(Menu::SetHfAmPwr(val));
	}
	else if (o == VHFPower)
	{
		m_port.writeString(Menu::Set50mPwr(val));
	}
	else if (o == VHFSSBPower)
	{
		m_port.writeString(Menu::Set50mSsbPwr(val));
	}
	else if (o == VHFAMPower)
	{
		m_port.writeString(Menu::Set50mAmPwr(val));
	}
	else if (o == Backlight)
	{
		m_port.writeString(Menu::SetBackliteDimmer(val));
	}
	else if(o == MicGain)
	{
		m_port.writeString(MicGain::Set(val));
	}
	else if(o == RFGain)
	{
		m_port.writeString(RFGain::Set(RFGain->value()));
	}
	else if(o == Squelch)
	{
		m_port.writeString(SquelchLevel::Set(Squelch->value()));
	}
	else if(o == MonitorLevel)
	{
		MonitorLevelValue v;
		v.f = MonitorFunction::MontiorLevel;
		v.val.iVal = MonitorLevel->value();
		m_port.writeString(MonitorLevel::Set(v));
	}
	else if(o == KeyerSpeed)
	{
		m_port.writeString(KeyerSpeed::Set((KeyerSpeedVal)KeyerSpeed->value()));
	}
	else if(o == Volume)
	{
		m_port.writeString(VolumeLevel::Set(Volume->value()));
	}
	else if(o == DNRAlgo)
	{
		m_port.writeString(NoiseReductionLevel::Set(DNRAlgo->value()));
	}
	else if(o == LCD)
	{
		string s = Menu::SetLcdDimmer(LCD->value());
		m_port.writeString(s);
	}
	else if(o == ProcessorLevel)
	{
		string s = SpeechProcessorLevel::Set((int)ProcessorLevel->value());
		m_port.writeString(s);
	}
	else if(o == NoiseBlankerLevel)
	{
		string s = NoiseBlankerLevel::Set((int)NoiseBlankerLevel->value());
		m_port.writeString(s);
	}
	else if(o == LCDContrast)
	{
		string s = Menu::SetLcdContrast((int)LCDContrast->value());
		m_port.writeString(s);
	}
	else if(o == TxBusy)
	{
		string s = Menu::SetTxBusyDimmer((int)TxBusy->value());
		m_port.writeString(s);
	}
	else if(o == AMOutLevel)
	{
		string s = Menu::SetAMOutLevel((int) AMOutLevel->value());
		m_port.writeString(s);
	}
	else if(o == CWOutLevel)
	{
		string s = Menu::SetCWOutLevel((int) CWOutLevel->value());
		m_port.writeString(s);
	}
	else if(o == RTTYOutLevel)
	{
		string s = Menu::SetRTTYOutLevel((int) RTTYOutLevel->value());
		m_port.writeString(s);
	}
	else if(o == DATAOutLevel)
	{
		string s = Menu::SetDATAOutLevel((int) DATAOutLevel->value());
		m_port.writeString(s);
	}
	else if(o == SSBOutLevel)
	{
		string s = Menu::SetSSBOutLevel((int) SSBOutLevel->value());
		m_port.writeString(s);
	}
	else if(o == BeepLevel)
	{
		string s = Menu::SetBeepLevel((int) BeepLevel->value());
		m_port.writeString(s);
	}
	else if(o == MicEQLevel1)
	{
		string s = Menu::SetEQ1Level(MicEQLevel1->value());
		m_port.writeString(s);
	}
	else if(o == MicBandWidth1)
	{
		string s = Menu::SetEQ1Bwth(MicBandWidth1->value());
		m_port.writeString(s);
	}
	else if(o == MicEQLevel2)
	{
		string s = Menu::SetEQ2Level(MicEQLevel2->value());
		m_port.writeString(s);
	}
	else if(o == MicBandWidth2)
	{
		string s = Menu::SetEQ2Bwth(MicBandWidth2->value());
		m_port.writeString(s);
	}
	else if(o == MicEQLevel3)
	{
		string s = Menu::SetEQ3Level(MicEQLevel3->value());
		m_port.writeString(s);
	}
	else if(o == MicBandWidth3)
	{
		string s = Menu::SetEQ3Bwth(MicBandWidth3->value());
		m_port.writeString(s);
	}
	else if(o == MicPEQLevel1)
	{
		string s = Menu::SetPEQ1Level(MicPEQLevel1->value());
		m_port.writeString(s);
	}
	else if(o == MicPBandWidth1)
	{
		string s = Menu::SetPEQ1Bwth(MicPBandWidth1->value());
		m_port.writeString(s);
	}
	else if(o == MicPEQLevel2)
	{
		string s = Menu::SetPEQ2Level(MicPEQLevel2->value());
		m_port.writeString(s);
	}
	else if(o == MicPBandWidth2)
	{
		string s = Menu::SetPEQ2Bwth(MicPBandWidth2->value());
		m_port.writeString(s);
	}
	else if(o == MicPEQLevel3)
	{
		string s = Menu::SetPEQ3Level(MicPEQLevel3->value());
		m_port.writeString(s);
	}
	else if(o == MicPBandWidth3)
	{
		string s = Menu::SetPEQ3Bwth(MicPBandWidth3->value());
		m_port.writeString(s);
	}
	else if(o == AGCFastDelay)
	{
		string s = Menu::SetAgcFastDelay(AGCFastDelay->value());
		m_port.writeString(s);
	}
	else if(o == AGCMidDelay)
	{
		string s = Menu::SetAgcMidDelay(AGCMidDelay->value());
		m_port.writeString(s);
	}
	else if(o == AGCSlowDelay)
	{
		string s = Menu::SetAgcSlowDelay(AGCSlowDelay->value());
		m_port.writeString(s);
	}

}

void FT891::OnRoll(Fl_Value_Slider* o , void* v)
{
	m_port.writeString(KeyPitch::Set((KeyPitchValue) ((o->value() - 300)/10)));	
	o->redraw();
}

void OnBox(Fl_Button* o, void* v)
{
	FT891* window = (FT891*)v;
	window->OnBox(o,v);
}

void FT891::OnBox(Fl_Button* o , void* v)
{
	FT891* window = (FT891*)v;
	if(o == window->NAR)
	{
		if(window->NAR->color() == FL_GREEN)
		{
			NAR->color(FL_BACKGROUND_COLOR);
			NarrowState = NarrowValue::OFF;			
			m_port.writeString(Narrow::Set(NarrowState));	
		}
		else
		{
			NAR->color(FL_GREEN);
			NarrowState = NarrowValue::ON;
			m_port.writeString(Narrow::Set(NarrowState));
		}
		NAR->redraw();
	}
	else if(o == window->ATT)
	{
		if(window->ATT->color() == FL_GREEN)
		{
			ATT->color(FL_BACKGROUND_COLOR);
			m_port.writeString(RFAttenuator::Set(RfAttenuatorState::OFF));
		}
		else
		{
			
			ATT->color(FL_GREEN);
			m_port.writeString(RFAttenuator::Set(RfAttenuatorState::ON));
		}
		
	}
	else if(o == window->IPO)
	{
		if(window->IPO->color() == FL_GREEN)
		{
			IPO->color(FL_BACKGROUND_COLOR);
			m_port.writeString(PreAmp::Set(PreAmpValue::AMP));
		}
		else
		{
			IPO->color(FL_GREEN);
			m_port.writeString(PreAmp::Set(PreAmpValue::IPO));
		}		
	}
	else if(o == window->btnDNR)
	{
		if(btnDNR->color() == FL_GREEN)
		{
			btnDNR->color(FL_BACKGROUND_COLOR);			
			m_port.writeString(NoiseReduction::Set(NoiseReductionValue::OFF));
		
		}
		else
		{
			btnDNR->color(FL_GREEN);
			m_port.writeString(NoiseReduction::Set(NoiseReductionValue::ON));

			m_port.writeString(NoiseReductionLevel::Read());
		}
	}
	else if(o == NB)
	{
		if(NB->color() == FL_GREEN)
		{
			NB->color(FL_BACKGROUND_COLOR);
			m_port.writeString(NoiseBlankerStatus::Set(NoiseBlankerStatusValue::OFF));
		}
		else
		{
			
			NB->color(FL_GREEN);
			m_port.writeString(NoiseBlankerStatus::Set(NoiseBlankerStatusValue::ON));
		}
	}
	else if(o == FST)
	{
		if(FST->color() == FL_GREEN)
		{
			FST->color(FL_BACKGROUND_COLOR);
			m_port.writeString(FAST_STEP::Set(VFOFastStepValue::OFF));
		}
		else
		{
			FST->color(FL_GREEN);
			m_port.writeString(FAST_STEP::Set(VFOFastStepValue::ON));
		}
	}
	else if(o == MON)
	{
		MonitorLevelValue v;
		v.f = MonitorFunction::MontiorOnOff;
		if(MON->color() == FL_GREEN)
		{
			MON->color(FL_BACKGROUND_COLOR);
			v.val.eVal = MonitorOnOffValue::OFF;
			m_port.writeString(MonitorLevel::Set(v));			
		}
		else
		{
			MON->color(FL_GREEN);
			v.val.eVal = MonitorOnOffValue::ON;
			m_port.writeString(MonitorLevel::Set(v));
		}
	}
	else if(o == PRC)
	{
		SpeechProcessorSetting s;
		if(PRC->color() != FL_GREEN)
		{
			PRC->color(FL_GREEN);
			s.state = SpeechProcessorState::ON;
			s.type = SpeechProcessorType::Processor;
			std::string val = SpeechProcessor::Set(s);
			m_port.writeString(val);
		}
		else
		{
			PRC->color(FL_BACKGROUND_COLOR);
			s.state = SpeechProcessorState::OFF;
			s.type = SpeechProcessorType::Processor;
			std::string val = SpeechProcessor::Set(s);
			m_port.writeString(val);
		}
	}
	else if(o == Keyer)
	{
		if(Keyer->color() == FL_GREEN)
		{
			Keyer->color(FL_BACKGROUND_COLOR);
			m_port.writeString(Yaesu::FT891::Commands::Keyer::Set(KeyerValue::OFF));
			KeyerSpeed->clear_active();
			KeyerSpeed->redraw();
		}
		else
		{
			Keyer->color(FL_GREEN);
			m_port.writeString(Keyer::Set(KeyerValue::ON));
			m_port.writeString(KeyerSpeed::Read());
			KeyerSpeed->set_active();
			KeyerSpeed->redraw();
		}
	}
	else if(o == BreakIn)
	{
		if(BreakIn->color() == FL_GREEN)
		{
			BreakIn->color(FL_BACKGROUND_COLOR);
			m_port.writeString(BreakIn::Set(BreakInState::OFF));
		}
		else
		{
			BreakIn->color(FL_GREEN);
			m_port.writeString(BreakIn::Set(BreakInState::ON));
		}
	}
	else if(o == VOX)
	{
		if(VOX->color() == FL_GREEN)
		{
			VOX->color(FL_BACKGROUND_COLOR);
			m_port.writeString(VoxStatus::Set(VoxStatusValue::OFF));	
		}
		else
		{
			VOX->color(FL_GREEN);	
			m_port.writeString(VoxStatus::Set(VoxStatusValue::ON));
			
		}
	}
	else if(o == AB)
	{
		string s = SwapVfo::Set();
		m_port.writeString(s);
		
	}
	else if(o == UP)
	{
		string s = BandUP::Set();
		m_port.writeString(s);
	}
	else if(o == DOWN)
	{
		string s = BandDown::Set();
		m_port.writeString(s);
	}
	else if(o == McUp)
	{
		string s = Up::Set();
		m_port.writeString(s);
		s = Yaesu::FT891::Commands::INFORMATION::Read();
		m_port.writeString(s);
	}
	else if(o == McDn)
	{
		string s = Mic_Down::Set();
		m_port.writeString(s);
		s = Yaesu::FT891::Commands::INFORMATION::Read();
		m_port.writeString(s);
	}
	else if(o == LOCK)
	{
		if(LOCK->color() == FL_BACKGROUND_COLOR)
		{
			string s = Yaesu::FT891::Commands::VFODialLock::Set(DialLockValue::ON);
			m_port.writeString(s);
			LOCK->color(FL_GREEN);
		}
		else
		{
			string s = Yaesu::FT891::Commands::VFODialLock::Set(DialLockValue::OFF);
			m_port.writeString(s);
			LOCK->color(FL_BACKGROUND_COLOR);
		}
	}
	else if(o == SPL)
	{
		if(SPL->color() == FL_BLUE)
		{
			SplitValue = SplitValue::OFF;
			string s = Split::Set(SplitValue);
			m_port.writeString(s);
			SPL->color(FL_BACKGROUND_COLOR);
			VFOBFreq = VFOBFreq - 5000;
			m_port.writeString(VFO_B_FREQ::Set(VFOBFreq));
		}
		else if(SPL->color() == FL_GREEN)
		{
			SplitValue = SplitValue::ON_5KU;
			string s = Split::Set(SplitValue);
			m_port.writeString(s);
			SPL->color(FL_BLUE);
		}
		else if(SPL->color() == FL_BACKGROUND_COLOR)
		{
			SplitValue = SplitValue::ON;
			string s = Split::Set(SplitValue);
			m_port.writeString(s);
			SPL->color(FL_GREEN);
		}
		SPL->redraw();
	}
	else if(o == TNR)
	{
		if(TNR->color() == FL_GREEN)
		{
			TNR->color(FL_BACKGROUND_COLOR);
			string s = AntennaTunerControl::Set(TunerState::OFF);
			m_port.writeString(s);
		}
		else if(TNR->color() == FL_BACKGROUND_COLOR)
		{
			TNR->color(FL_GREEN);
			string s = AntennaTunerControl::Set(TunerState::ON);
			m_port.writeString(s);
		}
		TNR->redraw();
	}
	else if(o == ATTune)
	{
		if(TNR->color() == FL_GREEN)
		{
			string s = AntennaTunerControl::Set(TunerState::Start);
			m_port.writeString(s);
		}
	}
	else if(o == V_M)
	{			
		string s = VFO_A_toMemoryChannel::Set();
		m_port.writeString(s);	
	}
	else if(o == VA_M)
	{
		if(m_channels.size() == 0){
			fl_alert("Reading Memory Channels, this may take a moment.");
			MemoryChannelEdit = true;		
			currentMemory = MemoryChannelValue::_1;		
			std::string s = Yaesu::FT891::Commands::MemoryWriteTag::Read(currentMemory);
			m_port.writeString(s);
			while(MemoryChannelEdit)
				Fl::wait();
		}
		
		if(!MemoryChannelEdit)
		{
			
			Yaesu::FT891::Commands::MemoryChannelTagValue* next = new Yaesu::FT891::Commands::MemoryChannelTagValue();
			next->VFOAFreq = this->VFOAFreq;
			next->Clarifier = ClarifierState;
			next->ClarifierFreq = this->Clarifier->value();
			next->Mode = this->currentMemoryMode;
			next->Operation = static_cast<Yaesu::FT891::Commands::OperationType>(SplitValue);
			next->TAG = Yaesu::FT891::Commands::TagValue::OFF;
			next->TagString = "";
			win = new Fl_Double_Window(1200,700, "Memory Editor");
			m_editor = new MemoryEditor(10 ,20,1080,700-20,m_channels,next,"");					    		
			Fl_Button* save = new Fl_Button(1100,20,80,50,"Save");
			save->callback((Fl_Callback*)&::OnSaveMemory, this);
			Fl_Button* cancel = new Fl_Button(1100,77,80,50,"Cancel");
			win->set_modal();
			win->resizable(win);				
    		win->show();			
		}		
	}
	else if(o == M_VA)
	{
		string s = MemoryChannelToVFOA::Set();

		m_port.writeString(s);

		MemoryChannelEdit = true;
		m_channels.clear();
		m_port.writeString(MemoryWriteTag::Read((MemoryChannelValue)1));
		while(MemoryChannelEdit)
			Fl::wait();

		if(!MemoryChannelEdit)
		{
			win = new Fl_Double_Window(1200,700, "Memory Editor");
			m_editor = new MemoryEditor(10 ,20,1080,700-20,m_channels,"");					    					
			Fl_Button* cancel = new Fl_Button(1100,77,80,50,"Cancel");
			
			win->set_modal();
			win->resizable(win);				
    		win->show();
			
		}

		
	}
	else if(o == QMBS)
	{
		string s = QMBStore::Set();
		m_port.writeString(s);
	}
	else if(o == QMBR)
	{
		string s = QMBRecall::Set();
		m_port.writeString(s);
	}
	else if(o == CLAR)
	{
		if(CLAR->color() == FL_GREEN)
		{
			ClarifierState = ClarifierState::OFF;
			CLAR->color(FL_BACKGROUND_COLOR);
			m_port.writeString(Clarifier::Set(ClarifierState::OFF));
		}
		else
		{
			ClarifierState = ClarifierState::ON;
			CLAR->color(FL_GREEN);
			m_port.writeString(Clarifier::Set(ClarifierState::ON));
		}
	}
	else if(o == PlayCWMessage1)
	{
		std::string val;
		val = CWKeyingPlayback::Set(KeyerMemoryChannel::Message1);		
		m_port.writeString(val);
	}
	else if(o == PlayCWMessage2)
	{	
		m_port.writeString(CWKeyingPlayback::Set(KeyerMemoryChannel::Message2));		
	}
	else if(o == PlayCWMessage3)
	{
		m_port.writeString(CWKeyingPlayback::Set(KeyerMemoryChannel::Message3));
	}
	else if(o == PlayCWMessage4)
	{
		m_port.writeString(CWKeyingPlayback::Set(KeyerMemoryChannel::Message4));
	}
	else if(o == PlayCWMessage5)
	{
		m_port.writeString(CWKeyingPlayback::Set(KeyerMemoryChannel::Message5));
	}

}

void OnEnter(Fl_Input* o ,void* v)
{
	FT891* ptr = (FT891*)v;
    ptr->OnTextEnter(FL_ENTER,o);
}

void OnMessageText(Fl_Input* o, void* v)
{
	FT891* ptr = (FT891*)v;
	ptr->OnMessageUpdate(o);
}


int FT891::OnTextEnter(int key, Fl_Input* editor)
{
	string sfreq = editor->value();
	int pos = 1;
	while((pos = sfreq.find_first_of(".")) != string::npos)
	{
		sfreq = sfreq.erase(pos,1);
	}
	int freq = std::stoi(sfreq);
	string s ;
	if(editor == VFOA)
	{
		s = VFO_A_FREQ::Set(freq);
	}
	else if(editor == VFOB)
	{
		s = VFO_B_FREQ::Set(freq);
	}
	m_port.writeString(s);
	return key;
}

void FT891::OnMessageUpdate(Fl_Input* editor)
{
	KeyerMemoryValue val;
	val.Message = std::string(editor->value()).substr(0,50);

	
	if(editor == CWMemoryValue1)
		val.ChannelNumber = 1;
	else if(editor == CWMemoryValue2)
		val.ChannelNumber = 2;
	else if(editor == CWMemoryValue3)
		val.ChannelNumber = 3;
	else if(editor == CWMemoryValue4)
		val.ChannelNumber = 4;
	else if(editor == CWMemoryValue5)
		val.ChannelNumber = 5;
	
	m_port.writeString(KeyerMemory::Set(val));
}

void FT891::BuildGeneralGroup(int w, int h)
{
  int y = 60;
  int boxwidth = 45;
  int sliderWidth = 45;
  int sliderGap = 20 + sliderWidth;
  GeneralG = new Fl_Group(0, y, w, (h - y), "General");

	PowerButton = new Fl_Light_Button(15, 5 + y, 80, 30, "Power");
	PowerButton->selection_color(FL_RED);
	PowerButton->callback((Fl_Callback*)OnLightButtonClick, this);

	QMBS = new Fl_Button(PowerButton->x() + PowerButton->w() + 5, PowerButton->y() + PowerButton->h() - 20, boxwidth,20, "QM►");
	QMBS->box(FL_BORDER_BOX);
	QMBS->align(FL_ALIGN_CENTER);
	QMBS->callback((Fl_Callback*)&::OnBox, this);
	
	QMBR = new Fl_Button(QMBS->x() + QMBS->w() + 5, QMBS->y(), boxwidth,20, "QM◄");
	QMBR->box(FL_BORDER_BOX);
	QMBR->align(FL_ALIGN_CENTER);
	QMBR->callback((Fl_Callback*)&::OnBox, this);

	M_VA = new Fl_Button(QMBR->x() + QMBR->w() + 5, QMBR->y(),QMBR->w(), QMBR->h(), "M►V");
	M_VA->box(FL_BORDER_BOX);
	M_VA->align(FL_ALIGN_CENTER);
	M_VA->color(FL_BACKGROUND_COLOR);
	M_VA->callback((Fl_Callback*)&::OnBox, this);

	VA_M = new Fl_Button(M_VA->x() + M_VA->w() + 5, M_VA->y(),M_VA->w(), M_VA->h(), "V►M");
	VA_M->box(FL_BORDER_BOX);
	VA_M->align(FL_ALIGN_CENTER);
	VA_M->color(FL_BACKGROUND_COLOR);
	VA_M->callback((Fl_Callback*)&::OnBox, this);

	V_M = new Fl_Button(VA_M->x() + VA_M->w() + 5, VA_M->y(),VA_M->w(), VA_M->h(), "V/M");
	V_M->box(FL_BORDER_BOX);
	V_M->align(FL_ALIGN_CENTER);
	V_M->color(FL_BACKGROUND_COLOR);
	V_M->callback((Fl_Callback*)&::OnBox, this);

	AB = new Fl_Button(V_M->x() + V_M->w() + 5, V_M->y(), boxwidth, 20,"A/B");
	AB->box(FL_BORDER_BOX);
	AB->align(FL_ALIGN_CENTER);
	AB->color(FL_BACKGROUND_COLOR);
	AB->callback((Fl_Callback*)&::OnBox, this);

	StatusLED = new Fl_Box(AB->x() + AB->w() + 5, AB->y(), boxwidth, 20);
	StatusLED->box(FL_BORDER_BOX);
	StatusLED->show();

	TNR = new Fl_Button(15, PowerButton->y() + PowerButton->h() + 5, boxwidth, 20 ,"TNR");
	TNR->box(FL_BORDER_BOX);
	TNR->align(FL_ALIGN_CENTER);
	TNR->callback((Fl_Callback*)&::OnBox, this);

	VOX = new Fl_Button(15, TNR->y() + 25, boxwidth, 20, "VOX" );
	VOX->box(FL_BORDER_BOX);
	VOX->align(FL_ALIGN_CENTER);
	VOX->callback((Fl_Callback*)&::OnBox, this);

	Keyer = new Fl_Button(VOX->x(), VOX->y(),boxwidth, 20, "KYR");
	Keyer->box(FL_BORDER_BOX);
	Keyer->align(FL_ALIGN_CENTER);
	Keyer->callback((Fl_Callback*)&::OnBox, this);
	Keyer->hide();

	PRC = new Fl_Button(15, VOX->y() + 25, boxwidth, 20 ,"PRC");
	PRC->box(FL_BORDER_BOX);
	PRC->align(FL_ALIGN_CENTER);
	PRC->callback((Fl_Callback*)&::OnBox, this);

	BreakIn = new Fl_Button(15, PRC->y(), boxwidth, 20, "BKI");
	BreakIn->box(FL_BORDER_BOX);
	BreakIn->align(FL_ALIGN_CENTER);
	BreakIn->callback((Fl_Callback*)&::OnBox, this);
	BreakIn->hide();

	MON = new Fl_Button(15, PRC->y() + 25, boxwidth, 20, "MON" );
	MON->box(FL_BORDER_BOX);
	MON->align(FL_ALIGN_CENTER);
	MON->callback((Fl_Callback*)&::OnBox, this);

	SPL = new Fl_Button(15, MON->y() + 25, boxwidth, 20, "SPL" );
	SPL->box(FL_BORDER_BOX);
	SPL->align(FL_ALIGN_CENTER);
	SPL->callback((Fl_Callback*)&::OnBox, this);
	
	int slidery =  h - 320 - 15;
	int sliderHeight = 320;

	Volume = new Fl_Value_Slider(15,slidery, sliderWidth, sliderHeight, "Volume" );
	Volume->align(FL_ALIGN_TOP);
	Volume->minimum(255.0);
	Volume->maximum(0.00);
	Volume->value(1.00);
	Volume->step(1.0);
	Volume->callback((Fl_Callback*)OnScrollBar, this);

	RFGain = new Fl_Value_Slider(Volume->x() +  sliderGap, h - 320 - 15, sliderWidth,320, "RF Gain");
	RFGain->align(FL_ALIGN_TOP);
	RFGain->minimum(30.0);
	RFGain->maximum(0.00);
	RFGain->value(0.00);
	RFGain->step(1.0);
	RFGain->callback((Fl_Callback*)OnScrollBar, this);

	Squelch = new Fl_Value_Slider(RFGain->x()  + sliderGap, h - 320 - 15, sliderWidth, 320, "Squelch");
	Squelch->align(FL_ALIGN_TOP);
	Squelch->minimum(100);
	Squelch->maximum(0.00);
	Squelch->value(0.00);
	Squelch->step(1.0);
	Squelch->callback((Fl_Callback*)OnScrollBar, this);

	MicGain = new Fl_Value_Slider(Squelch->x() +  sliderGap,h - 320 - 15, sliderWidth, 320, "MicGain");
	MicGain->align(FL_ALIGN_TOP);
	MicGain->minimum(100.0);
	MicGain->maximum(0.00);
	MicGain->value(0.00);
	MicGain->step(1.0);
	MicGain->callback((Fl_Callback*)OnScrollBar, this);

	ProcessorLevel = new Fl_Value_Slider(MicGain->x() + sliderGap ,  slidery, sliderWidth, sliderHeight, "Comp");
	ProcessorLevel->align(FL_ALIGN_TOP);
	ProcessorLevel->minimum(100.0);
	ProcessorLevel->maximum(0.0);
	ProcessorLevel->value(0.00000);
	ProcessorLevel->step(1.0);
	ProcessorLevel->callback((Fl_Callback*)OnScrollBar, this);
	
	KeyerPitch = new Fl_Value_Slider(ProcessorLevel->x(), ProcessorLevel->y(), boxwidth , ProcessorLevel->h(), "Pitch");
	KeyerPitch->minimum(1050);
	KeyerPitch->maximum(300);
	KeyerPitch->step(10);
	KeyerPitch->align(FL_ALIGN_TOP);
	KeyerPitch->callback((Fl_Callback*)&::OnRoll,this);
	KeyerPitch->hide();

	KeyerSpeed = new Fl_Value_Slider(MicGain->x(),h - 320 - 15, sliderWidth, 320, "Speed");
	KeyerSpeed->align(FL_ALIGN_TOP);
	KeyerSpeed->minimum(60.0);
	KeyerSpeed->maximum(4.00);
	KeyerSpeed->value(4.00);
	KeyerSpeed->step(1.0);
	KeyerSpeed->callback((Fl_Callback*)OnScrollBar, this);
	KeyerSpeed->hide();

	MonitorLevel = new Fl_Value_Slider(ProcessorLevel->x() + sliderGap,h - 320 - 15, sliderWidth, 320, "MON");
	MonitorLevel->align(FL_ALIGN_TOP);
	MonitorLevel->minimum(100.0);
	MonitorLevel->maximum(0.00);
	MonitorLevel->value(0.00);
	MonitorLevel->step(1.0);
	MonitorLevel->callback((Fl_Callback*)OnScrollBar, this);

	DNRAlgo = new Fl_Value_Slider(MonitorLevel->x() + sliderGap,  h - 320 - 15, sliderWidth, 320, "DNR");
	DNRAlgo->align(FL_ALIGN_TOP);
	DNRAlgo->minimum(15);
	DNRAlgo->maximum(1);
	DNRAlgo->value(0.00000);
	DNRAlgo->step(1.0);
	DNRAlgo->callback((Fl_Callback*)OnScrollBar, this);

	NoiseBlankerLevel = new Fl_Value_Slider(DNRAlgo->x() + sliderGap,  h - 320 - 15, sliderWidth, 320, "NBLVL");
	NoiseBlankerLevel->align(FL_ALIGN_TOP);
	NoiseBlankerLevel->minimum(10);
	NoiseBlankerLevel->maximum(0);
	NoiseBlankerLevel->value(0.00000);
	NoiseBlankerLevel->step(1.0);
	NoiseBlankerLevel->callback((Fl_Callback*)OnScrollBar, this);
	
	VoxGainLevel = new Fl_Value_Slider(NoiseBlankerLevel->x() + sliderGap ,h - 320 - 15, sliderWidth, 320, "VoxLevel" );
	VoxGainLevel->align(FL_ALIGN_TOP);
	VoxGainLevel->minimum(100.0);
	VoxGainLevel->maximum(0.0);
	VoxGainLevel->value(0.00000);
	VoxGainLevel->step(1.0);
	VoxGainLevel->callback((Fl_Callback*)OnScrollBar, this);
	
	VoxDelayTime = new Fl_Value_Slider(VoxGainLevel->x() + sliderGap,h - 320 - 15, sliderWidth, 320, "VoxDelay" );
	VoxDelayTime->align(FL_ALIGN_TOP);
	VoxDelayTime->minimum(3000.0);
	VoxDelayTime->maximum(30.0);
	VoxDelayTime->value(30.0);
	VoxDelayTime->step(10.0);
	VoxDelayTime->callback((Fl_Callback*)OnScrollBar, this);

	OperatingMode = new Fl_Choice(Keyer->x() + Keyer->w() + 5, Keyer->y(), 80, 30, "");
  	OperatingMode->add("USB", 0, OnOperatingMode,this,0);
	OperatingMode->add("LSB", 0, OnOperatingMode,this,0);
	OperatingMode->add("SSB-AUTO",0, OnOperatingMode,this,0);
  	OperatingMode->add("CW-L",0,OnOperatingMode,this,0);
	OperatingMode->add("CW-U", 0 , OnOperatingMode, this, 0);
	OperatingMode->add("CW-AUTO", 0 , OnOperatingMode, this, 0);
	OperatingMode->add("FM",0,OnOperatingMode,this,0);
	OperatingMode->add("FM-N",0, OnOperatingMode,this,0);
	OperatingMode->add("AM",0,OnOperatingMode,this,0);
	OperatingMode->add("AM-N",0,OnOperatingMode,this,0);
	OperatingMode->add("DATA-U",0,OnOperatingMode,this, 0);
	OperatingMode->add("DATA-L",0,OnOperatingMode,this,0);
	OperatingMode->add("RTTY-U",0,OnOperatingMode,this,0);
	OperatingMode->add("RTTY-L",0,OnOperatingMode,this,0);

	DisplayMode = new Fl_Choice(OperatingMode->x(), OperatingMode->y() + OperatingMode->h() + 5, 80, 30, "");
	DisplayMode->add("COMP", 0, OnChoice, this, 0);
	DisplayMode->add("ALC", 0, OnChoice, this, 0);
	DisplayMode->add("PO", 0, OnChoice, this, 0);
	DisplayMode->add("SWR", 0, OnChoice, this, 0);
	DisplayMode->add("IDD", 0, OnChoice, this, 0);	

	VFOA = new Fl_Input(OperatingMode->x() + OperatingMode->w() + 5, TNR->y() , 100, 30, "");
	VFOA->textfont(FL_TIMES_BOLD);
	VFOA->textsize(20);
	VFOA->callback((Fl_Callback*)&::OnEnter,this);
	VFOA->when(FL_WHEN_ENTER_KEY_ALWAYS);
	
	VFOB = new Fl_Input(VFOA->x(), VFOA->y() + VFOA->h() + 5, 100, 30, "");
	VFOB->textfont(FL_TIMES_BOLD);
	VFOB->textsize(20);
	VFOB->callback((Fl_Callback*)&::OnEnter,this);
	VFOB->when(FL_WHEN_ENTER_KEY_ALWAYS);
	
	int col = AB->x();

	IPO = new Fl_Button(col, TNR->y(), boxwidth,20, "IPO");
	IPO->box(FL_BORDER_BOX);
	IPO->align(FL_ALIGN_CENTER);
	IPO->callback((Fl_Callback*)&::OnBox, this);
	
	ATT = new Fl_Button(IPO->x(), IPO->y() + IPO->h() + 5, boxwidth,20, "ATT");
	ATT->box(FL_BORDER_BOX);
	ATT->align(FL_ALIGN_CENTER);
	ATT->callback((Fl_Callback*)&::OnBox, this);

	NAR = new Fl_Button(ATT->x(), ATT->y() + ATT->h() + 5, boxwidth,20, "NAR");
	NAR->box(FL_BORDER_BOX);
	NAR->align(FL_ALIGN_CENTER);
	NAR->color(FL_BACKGROUND_COLOR);
	NAR->callback((Fl_Callback*)&::OnBox, this);

	NB = new Fl_Button(NAR->x(), NAR->y() + NAR->h() + 5, boxwidth,20, "NB");
	NB->box(FL_BORDER_BOX);
	NB->align(FL_ALIGN_CENTER);
	NB->color(FL_BACKGROUND_COLOR);
	NB->callback((Fl_Callback*)&::OnBox, this);

	FST = new Fl_Button(NB->x(), NB->y() + NB->h() + 5, boxwidth,20, "FST");
	FST->box(FL_BORDER_BOX);
	FST->align(FL_ALIGN_CENTER);
	FST->color(FL_BACKGROUND_COLOR);
	FST->callback((Fl_Callback*)&::OnBox, this);
	
	Width = new Fl_Choice(col + FST->w() + 5,ATT->y(),80,30,"Width");
	Width->align(FL_ALIGN_TOP);

	Band = new Fl_Choice(col + FST->w() + 5, Width->y() + 45, 80,30,"Band");
	Band->add("1.8", 0, OnChoice, this, 0);
	Band->add("3.5", 0, OnChoice, this, 0);
	Band->add("5.0", 0, OnChoice, this, 0);
	Band->add("7.0", 0, OnChoice, this, 0);
	Band->add("10", 0, OnChoice, this, 0);
	Band->add("14", 0, OnChoice, this, 0);
	Band->add("18", 0, OnChoice, this, 0);
	Band->add("21", 0, OnChoice, this, 0);
	Band->add("24", 0, OnChoice, this, 0);
	Band->add("28", 0, OnChoice, this, 0);
	Band->add("50", 0, OnChoice, this, 0);
	Band->add("GEN", 0, OnChoice, this, 0);
	Band->align(FL_ALIGN_TOP);

	UP = new Fl_Button(Band->x(), Band->y() + Band->h() + 5, boxwidth, 20,"▲");
	UP->box(FL_BORDER_BOX);
	UP->align(FL_ALIGN_CENTER);
	UP->color(FL_BACKGROUND_COLOR);
	UP->callback((Fl_Callback*)&::OnBox, this);

	DOWN = new Fl_Button(UP->x() + UP->w() + 5, UP->y() , boxwidth, 20,"▼");
	DOWN->box(FL_BORDER_BOX);
	DOWN->align(FL_ALIGN_CENTER);
	DOWN->color(FL_BACKGROUND_COLOR);
	DOWN->callback((Fl_Callback*)&::OnBox, this);

	LOCK = new Fl_Button(Width->x() + Width->w(), Width->y(), boxwidth, 20,"Lock");
	LOCK->box(FL_BORDER_BOX);
	LOCK->align(FL_ALIGN_CENTER);
	LOCK->color(FL_BACKGROUND_COLOR);
	LOCK->callback((Fl_Callback*)&::OnBox, this);

	btnDNR = new Fl_Button(LOCK->x(), LOCK->y() + LOCK->h() + 5, boxwidth,20, "DNR");
	btnDNR->box(FL_BORDER_BOX);
	btnDNR->align(FL_ALIGN_CENTER);
	btnDNR->color(FL_BACKGROUND_COLOR);
	btnDNR->callback((Fl_Callback*)&::OnBox, this);
	
	CLAR = new Fl_Button(btnDNR->x(), btnDNR->y() + btnDNR->h() + 5, boxwidth,20, "CLAR");
	CLAR->box(FL_BORDER_BOX);
	CLAR->align(FL_ALIGN_CENTER);
	CLAR->color(FL_BACKGROUND_COLOR);
	CLAR->callback((Fl_Callback*)&::OnBox, this);

	ChannelLabel = new Fl_Box(TNR->x() + TNR->w() + 5, TNR->y(),
							  VFOA->x() - (TNR->x() + TNR->w() + 10),
							  TNR->h(),"A");

	McUp = new Fl_Button(LOCK->x() + LOCK->w() + 5, LOCK->y(), boxwidth, 20,"▲");
	McUp->box(FL_BORDER_BOX);
	McUp->align(FL_ALIGN_CENTER);
	McUp->color(FL_BACKGROUND_COLOR);
	McUp->callback((Fl_Callback*)&::OnBox, this);

	McDn = new Fl_Button(McUp->x(), McUp->y() + McUp->h() + 5, boxwidth, 20,"▼");
	McDn->box(FL_BORDER_BOX);
	McDn->align(FL_ALIGN_CENTER);
	McDn->color(FL_BACKGROUND_COLOR);
	McDn->callback((Fl_Callback*)&::OnBox, this);

	ClarifierType = new Fl_Choice(McUp->x() + McUp->w() + 5, McUp->y(), boxwidth * 2, 30, "Clarifier");
	ClarifierType->align(FL_ALIGN_TOP);
	ClarifierType->add("RX", 0, OnChoice, this, 0);
	ClarifierType->add("TX", 0, OnChoice, this, 0);
	ClarifierType->add("TRX", 0, OnChoice, this, 0);

	Clarifier = new Fl_Counter(ClarifierType->x(), ClarifierType->y() + ClarifierType->h() + 5, boxwidth * 2, 20, "RIT/XIT");
	Clarifier->box(FL_BORDER_BOX);
	Clarifier->align(FL_ALIGN_CENTER);
	Clarifier->color(FL_BACKGROUND_COLOR);
	Clarifier->bounds(-9999,9999);	
	Clarifier->step(1,10);
	Clarifier->value(0);
	Clarifier->callback((Fl_Callback*)&::OnCounter,this );

	ATTune = new Fl_Button(DOWN->x() + DOWN->w() + 5, DOWN->y(), boxwidth, 20, "Tune");
	ATTune->box(FL_BORDER_BOX);
	ATTune->align(FL_ALIGN_CENTER);
	ATTune->color(FL_BACKGROUND_COLOR);
	ATTune->callback((Fl_Callback*)&::OnBox, this);

	TunerType = new Fl_Choice(ATTune->x() + ATTune->w() + 5, ATTune->y(), boxwidth * 2, 30,"TUN/LIN");
	TunerType->align(FL_ALIGN_TOP);
	TunerType->add("OFF", 0, OnChoice, this, 0);
	TunerType->add("EXT", 0, OnChoice, this, 0);
	TunerType->add("ATAS", 0, OnChoice, this, 0);
	TunerType->add("LAMP", 0, OnChoice, this, 0);
	TunerType->value(0);

	GeneralG->show();
	GeneralG->end();
}

void FT891::BuildPowerGroup(int w, int h)
{
  int y = 60;
  OutputPowerG = new Fl_Group(0, y, w, (h - y), "Output Power");
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;
	HFPowerG = new Fl_Group(0, sliderTop - 80, (w / 2), (h - y), "HF Power");
	HFPowerG->box(FL_BORDER_BOX);
	HFPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "Power");
	HFPower->minimum(100);
	HFPower->maximum(5);
	HFPower->value(0.00000);
	HFPower->step(1.0);
	HFPower->callback((Fl_Callback*)OnScrollBar, this);
	HFPower->align(FL_ALIGN_TOP);
	iStart += (w / 2) / 4 + 45 / 2;
	HFSSBPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "SSB Power");
	HFSSBPower->minimum(100);
	HFSSBPower->maximum(5);
	HFSSBPower->value(0.00000);
	HFSSBPower->step(1.0);
	HFSSBPower->callback((Fl_Callback*)OnScrollBar, this);
	HFSSBPower->align(FL_ALIGN_TOP);
	iStart += (w / 2) / 4 + 45 / 2;
	HFAMPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "AM Power");
	HFAMPower->minimum(40);
	HFAMPower->maximum(5);
	HFAMPower->value(0.00000);
	HFAMPower->step(1.0);
	HFAMPower->callback((Fl_Callback*)OnScrollBar, this);
	HFAMPower->align(FL_ALIGN_TOP);
	HFPowerG->end();
	iStart += 55;
	VHFPowerG = new Fl_Group((w / 2), sliderTop - 80, (w / 2), (h - y), "VHFPower");
	iStart = (w / 2);
	iStart += 15;
	VHFPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "Power");
	VHFPower->minimum(100);
	VHFPower->maximum(5);
	VHFPower->value(0.00000);
	VHFPower->step(1.0);
	VHFPower->callback((Fl_Callback*)OnScrollBar, this);
	VHFPower->align(FL_ALIGN_TOP);
	iStart += (((w / 2) / 4) + 45 / 2);
	VHFSSBPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "SSB Power");
	VHFSSBPower->minimum(100);
	VHFSSBPower->maximum(5);
	VHFSSBPower->value(0.00000);
	VHFSSBPower->step(1.0);
	VHFSSBPower->callback((Fl_Callback*)OnScrollBar, this);
	VHFSSBPower->align(FL_ALIGN_TOP);
	iStart += (((w / 2) / 4) + 45 / 2);
	VHFAMPower = new Fl_Value_Slider(iStart, sliderTop, sliderWidth, sliderHeight, "AM Power");
	VHFAMPower->minimum(40);
	VHFAMPower->maximum(5);
	VHFAMPower->value(0.00000);
	VHFAMPower->step(1.0);
	VHFAMPower->callback((Fl_Callback*)OnScrollBar, this);
	VHFAMPower->align(FL_ALIGN_TOP);
	VHFPowerG->box(FL_BORDER_BOX);
	VHFPowerG->show();
	VHFPowerG->end();
	OutputPowerG->box(FL_BORDER_BOX);
	OutputPowerG->show();
	OutputPowerG->end();
}

void FT891::BuildCWSettings(int w , int h)
{
	int y = 60;
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;	
  	int sliderGap = 20 + sliderWidth;
	int choiceWidth = (sliderWidth * 2) + 5;
	int choiceHeight = 30;
	int choiceX = iStart;

	
	CWSettingsTab = new Fl_Group(0, y, w, (h - y), "CW Settings");

	y += choiceHeight;

	CWBreakInType = new Fl_Choice(choiceX, y , choiceWidth, choiceHeight, "CW Breakin Type");
	CWBreakInType->add("SEMI", 0, OnChoice, this, 0);
	CWBreakInType->add("FULL", 0, OnChoice, this, 0);
	CWBreakInType->align(FL_ALIGN_TOP);
	
	CWWaveShape = new Fl_Choice(CWBreakInType->x() + choiceWidth + 20, CWBreakInType->y() , choiceWidth, choiceHeight, "CW Wave Shape");	
	CWWaveShape->add("2 ms", 0, OnChoice, this, 0);
	CWWaveShape->add("4 ms", 0, OnChoice, this, 0);
	CWWaveShape->align(FL_ALIGN_TOP);

	CWFreqDisplay = new Fl_Choice(CWWaveShape->x() + choiceWidth + 20, CWWaveShape->y() , choiceWidth, choiceHeight, "CW Freq Display");
	CWFreqDisplay->add("FREQ", 0, OnChoice, this, 0);
	CWFreqDisplay->add("PITCH", 0, OnChoice, this, 0);
	CWFreqDisplay->align(FL_ALIGN_TOP);

	QSKDelayTime = new Fl_Choice(CWFreqDisplay->x() + choiceWidth + 20, CWFreqDisplay->y() , choiceWidth, choiceHeight, "QSK Delay");
	QSKDelayTime->add("15 msec", 0, OnChoice, this, 0);
	QSKDelayTime->add("20 msec", 0, OnChoice, this, 0);
	QSKDelayTime->add("25 msec", 0, OnChoice, this, 0);
	QSKDelayTime->add("30 msec", 0, OnChoice, this, 0);
	QSKDelayTime->align(FL_ALIGN_TOP);

	KeyerType = new Fl_Choice(QSKDelayTime->x() + choiceWidth + 20, QSKDelayTime->y(), choiceWidth, choiceHeight, "Key Type");
	KeyerType->add("OFF", 0, OnChoice, this, 0);
	KeyerType->add("BUG", 0, OnChoice, this, 0);
	KeyerType->add("A", 0, OnChoice, this, 0);
	KeyerType->add("B", 0, OnChoice, this, 0);
	KeyerType->add("Y", 0, OnChoice, this, 0);
	KeyerType->add("ACS", 0, OnChoice, this, 0);
	KeyerType->align(FL_ALIGN_TOP);

	KeyerDotDash = new Fl_Choice(KeyerType->x() + choiceWidth + 20, KeyerType->y(), choiceWidth, choiceHeight, "KeyerDotDash");
	KeyerDotDash->add("NOR");
	KeyerDotDash->add("REV");
	KeyerDotDash->align(FL_ALIGN_TOP);

	CWWeight = new Fl_Choice(CWBreakInType->x(), KeyerDotDash->y() + choiceHeight + 20, choiceWidth, choiceHeight,"CW Weight");
	for(int i = 25; i != 46;i++)
	{
		CWWeight->add(fmt::format("{:f}", (float)i/10).substr(0,3).c_str(), 0, OnChoice, this, 0);
	}
	CWWeight->align(FL_ALIGN_TOP);

	CWMemory1Setting = new Fl_Choice(CWWeight->x() + choiceWidth + 20, CWWeight->y(), choiceWidth, choiceHeight,"CW Memory 1");
	CWMemory1Setting->add("TEXT", 0, OnChoice, this, 0); 
	CWMemory1Setting->add("MESSAGE",0, OnChoice, this, 0);
	CWMemory1Setting->align(FL_ALIGN_TOP); 


	CWMemory2Setting = new Fl_Choice(CWMemory1Setting->x() + choiceWidth + 20, CWMemory1Setting->y(), choiceWidth, choiceHeight,"CW Memory 2");
	CWMemory2Setting->add("TEXT", 0, OnChoice, this, 0); 
	CWMemory2Setting->add("MESSAGE",0, OnChoice, this, 0);
	CWMemory2Setting->align(FL_ALIGN_TOP); 

	
	
	CWMemory3Setting = new Fl_Choice(CWMemory2Setting->x() + choiceWidth + 20, CWMemory2Setting->y(), choiceWidth, choiceHeight,"CW Memory 3");
	CWMemory3Setting->add("TEXT", 0, OnChoice, this, 0); 
	CWMemory3Setting->add("MESSAGE",0, OnChoice, this, 0);
	CWMemory3Setting->align(FL_ALIGN_TOP); 

	
	
	CWMemory4Setting = new Fl_Choice(CWMemory3Setting->x() + choiceWidth + 20, CWMemory3Setting->y(), choiceWidth, choiceHeight,"CW Memory 4");
	CWMemory4Setting->add("TEXT", 0, OnChoice, this, 0); 
	CWMemory4Setting->add("MESSAGE",0, OnChoice, this, 0);
	CWMemory4Setting->align(FL_ALIGN_TOP); 
	
	

	CWMemory5Setting = new Fl_Choice(CWMemory4Setting->x() + choiceWidth + 20, CWMemory4Setting->y(), choiceWidth, choiceHeight,"CW Memory 5");
	CWMemory5Setting->add("TEXT", 0, OnChoice, this, 0); 
	CWMemory5Setting->add("MESSAGE",0, OnChoice, this, 0);
	CWMemory5Setting->align(FL_ALIGN_TOP); 

	
	CWMemoryValue1 = new Fl_Input(60,CWMemory5Setting->y() + choiceHeight + choiceHeight, (4 * choiceWidth) + 20,choiceHeight,  "MEM 1");
	CWMemoryValue1->textfont(FL_TIMES_BOLD);
	CWMemoryValue1->textsize(20);
	CWMemoryValue1->callback((Fl_Callback*)&::OnMessageText,this);
	CWMemoryValue1->when(FL_WHEN_ENTER_KEY_ALWAYS);

	PlayCWMessage1 = new Fl_Button(CWMemory4Setting->x(), CWMemoryValue1->y(), choiceWidth, choiceHeight, "►");
	PlayCWMessage1->align(FL_ALIGN_CENTER);
	PlayCWMessage1->callback((Fl_Callback*)::OnBox, this);
	
	CWMemoryValue2 = new Fl_Input(60,CWMemoryValue1->y() + choiceHeight,  (4 * choiceWidth) + 20,choiceHeight, "MEM 2");
	CWMemoryValue2->textfont(FL_TIMES_BOLD);
	CWMemoryValue2->textsize(20);
	CWMemoryValue2->callback((Fl_Callback*)&::OnMessageText,this);
	CWMemoryValue2->when(FL_WHEN_ENTER_KEY_ALWAYS);

	PlayCWMessage2 = new Fl_Button(PlayCWMessage1->x() , CWMemoryValue2->y(), choiceWidth, choiceHeight, "►");
	PlayCWMessage2->align(FL_ALIGN_CENTER);
	PlayCWMessage2->callback((Fl_Callback*)::OnBox, this);

	CWMemoryValue3 = new Fl_Input(60,CWMemoryValue2->y() + choiceHeight,  (4 * choiceWidth) + 20,choiceHeight, "MEM 3");
	CWMemoryValue3->textfont(FL_TIMES_BOLD);
	CWMemoryValue3->textsize(20);
	CWMemoryValue3->callback((Fl_Callback*)&::OnMessageText,this);
	CWMemoryValue3->when(FL_WHEN_ENTER_KEY_ALWAYS);

	PlayCWMessage3 = new Fl_Button(PlayCWMessage2->x() , CWMemoryValue3->y(), choiceWidth, choiceHeight, "►");
	PlayCWMessage3->align(FL_ALIGN_CENTER);
	PlayCWMessage3->callback((Fl_Callback*)::OnBox, this);

	CWMemoryValue4 = new Fl_Input(60,CWMemoryValue3->y() + choiceHeight,  (4 * choiceWidth) + 20,choiceHeight, "MEM 4");
	CWMemoryValue4->textfont(FL_TIMES_BOLD);
	CWMemoryValue4->textsize(20);
	CWMemoryValue4->callback((Fl_Callback*)&::OnMessageText,this);
	CWMemoryValue4->when(FL_WHEN_ENTER_KEY_ALWAYS);

	PlayCWMessage4 = new Fl_Button(PlayCWMessage3->x() , CWMemoryValue4->y(), choiceWidth, choiceHeight, "►");
	PlayCWMessage4->align(FL_ALIGN_CENTER);
	PlayCWMessage4->callback((Fl_Callback*)::OnBox, this);

	CWMemoryValue5 = new Fl_Input(60,CWMemoryValue4->y() + choiceHeight,  (4 * choiceWidth) + 20,choiceHeight, "MEM 5");
	CWMemoryValue5->textfont(FL_TIMES_BOLD);
	CWMemoryValue5->textsize(20);
	CWMemoryValue5->callback((Fl_Callback*)&::OnMessageText,this);
	CWMemoryValue5->when(FL_WHEN_ENTER_KEY_ALWAYS);

	PlayCWMessage5 = new Fl_Button(PlayCWMessage4->x() , CWMemoryValue5->y(), choiceWidth, choiceHeight, "►");
	PlayCWMessage5->align(FL_ALIGN_CENTER);
	PlayCWMessage5->callback((Fl_Callback*)::OnBox, this);


	CWSettingsTab->show();
	CWSettingsTab->end();
}

void FT891::BuildLightingGroup(int w, int h)
{
	int y = 60;
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;	
  	int sliderGap = 20 + sliderWidth;
	int choiceWidth = (sliderWidth * 2) + 5;
	int choiceHeight = 30;
	int choiceX = iStart;

	Lighting = new Fl_Group(0, y, w, (h - y), "Misc");


	AGCFastDelay = new Fl_Value_Slider(iStart , slidery, sliderWidth, sliderHeight, "AGC Fast");
	AGCFastDelay->minimum(4000);
	AGCFastDelay->maximum(20);
	AGCFastDelay->step(20);
	AGCFastDelay->callback((Fl_Callback*)OnScrollBar, this);
	AGCFastDelay->align(FL_ALIGN_TOP);

	AGCMidDelay = new Fl_Value_Slider(AGCFastDelay->x() + sliderGap, slidery, sliderWidth,sliderHeight,"MID");
	AGCMidDelay->minimum(4000);
	AGCMidDelay->maximum(20);
	AGCMidDelay->step(20);
	AGCMidDelay->callback((Fl_Callback*)OnScrollBar, this);
	AGCMidDelay->align(FL_ALIGN_TOP);

	AGCSlowDelay = new Fl_Value_Slider(AGCMidDelay->x() + sliderGap, slidery, sliderWidth,sliderHeight,"SLOW");
	AGCSlowDelay->minimum(4000);
	AGCSlowDelay->maximum(20);
	AGCSlowDelay->step(20);
	AGCSlowDelay->callback((Fl_Callback*)OnScrollBar, this);
	AGCSlowDelay->align(FL_ALIGN_TOP);

	Backlight = new Fl_Value_Slider(AGCSlowDelay->x() + sliderGap, slidery, sliderWidth,sliderHeight,"Backlight");
	Backlight->align(FL_ALIGN_TOP);
	Backlight->minimum(15);
	Backlight->maximum(1);
	Backlight->value(0.00000);
	Backlight->step(1.0);
	Backlight->callback((Fl_Callback*)OnScrollBar, this);

	LCD = new Fl_Value_Slider(Backlight->x() + sliderGap,  slidery, sliderWidth, sliderHeight, "LDC");
	LCD->align(FL_ALIGN_TOP);
	LCD->minimum(15);
	LCD->maximum(1);
	LCD->value(0.00000);
	LCD->step(1.0);
	LCD->callback((Fl_Callback*)OnScrollBar, this);

	LCDContrast = new Fl_Value_Slider(LCD->x() + sliderGap,  slidery, sliderWidth, sliderHeight, "Contrast");
	LCDContrast->align(FL_ALIGN_TOP);
	LCDContrast->minimum(15);
	LCDContrast->maximum(1);
	LCDContrast->value(0.00000);
	LCDContrast->step(1.0);
	LCDContrast->callback((Fl_Callback*)OnScrollBar, this);

	TxBusy = new Fl_Value_Slider(LCDContrast->x() + sliderGap,  slidery, sliderWidth, sliderHeight, "TxBusy");
	TxBusy->align(FL_ALIGN_TOP);
	TxBusy->minimum(15);
	TxBusy->maximum(1);
	TxBusy->value(0.00000);
	TxBusy->step(1.0);
	TxBusy->callback((Fl_Callback*)OnScrollBar, this);

	BeepLevel = new Fl_Value_Slider(TxBusy->x() + sliderGap,  slidery, sliderWidth, sliderHeight, "Beep");
	BeepLevel->align(FL_ALIGN_TOP);
	BeepLevel->minimum(100);
	BeepLevel->maximum(0);
	BeepLevel->value(0.00000);
	BeepLevel->step(1.0);
	BeepLevel->callback((Fl_Callback*)OnScrollBar, this);

	
	Lighting->box(FL_BORDER_BOX);

	choiceX = BeepLevel->x() + 15;

	APO = new Fl_Choice(15, y + choiceHeight , choiceWidth, choiceHeight, "APO");
	APO->add("OFF", 0, OnChoice, this, 0);
	APO->add("1h", 0, OnChoice, this, 0);
	APO->add("2h", 0, OnChoice, this, 0);
	APO->add("3h", 0, OnChoice, this, 0);
	APO->add("4h", 0, OnChoice, this, 0);
	APO->add("6h", 0, OnChoice, this, 0);
	APO->add("8h", 0, OnChoice, this, 0);
	APO->add("10h", 0, OnChoice, this, 0);
	APO->add("12h", 0, OnChoice, this, 0);
	APO->align(FL_ALIGN_TOP);

	MemGroup = new Fl_Choice( APO->x() + choiceWidth + 20, APO->y(), choiceWidth, choiceHeight, "Mem Group");
	MemGroup->add("Disable", 0, OnChoice, this, 0);
	MemGroup->add("Enable", 0, OnChoice, this, 0);
	MemGroup->align(FL_ALIGN_TOP);

	FMSetting = new Fl_Choice( MemGroup->x() + choiceWidth + 20,MemGroup->y(), choiceWidth, choiceHeight, "FM Setting");
	FMSetting->add("Disable", 0, OnChoice, this, 0);
	FMSetting->add("Enable", 0, OnChoice, this, 0);
	FMSetting->align(FL_ALIGN_TOP);

	RECSetting = new Fl_Choice( FMSetting->x() + choiceWidth + 20,FMSetting->y(), choiceWidth, choiceHeight, "REC Setting");
	RECSetting->add("Disable", 0, OnChoice, this, 0);
	RECSetting->add("Enable", 0, OnChoice, this, 0);
	RECSetting->align(FL_ALIGN_TOP);

	ATASSetting  = new Fl_Choice(RECSetting->x() + choiceWidth + 20,RECSetting->y(), choiceWidth, choiceHeight, "ATAS Setting");
	ATASSetting->add("Disable", 0, OnChoice, this, 0);
	ATASSetting->add("Enable", 0, OnChoice, this, 0);
	ATASSetting->align(FL_ALIGN_TOP);

	FanControl = new Fl_Choice(ATASSetting->x()+ choiceWidth + 20, ATASSetting->y() , choiceWidth, choiceHeight, "Fan Control" );
	FanControl->add("Normal", 0, OnChoice, this, 0);
	FanControl->add("Contest", 0, OnChoice, this, 0);
	FanControl->align(FL_ALIGN_TOP);
	
	TXTot = new Fl_Choice(APO->x(), FanControl->y() + choiceHeight + 20, choiceWidth, choiceHeight, "TX TOT");
	for(int i = 0; i != 31; i++)
	{
		TXTot->add(fmt::format("{:02} min",i).c_str(),0, OnChoice, this, 0);
	}
	TXTot->align(FL_ALIGN_TOP);

	MicScan = new Fl_Choice(TXTot->x() + choiceWidth + 20, TXTot->y(), choiceWidth, choiceHeight, "Mic Scan");
	MicScan->add("Disable", 0, OnChoice, this, 0);
	MicScan->add("Enable", 0, OnChoice, this, 0);
	MicScan->align(FL_ALIGN_TOP);

	MicScanResume = new Fl_Choice(MicScan->x() + choiceWidth + 20, MicScan->y(), choiceWidth, choiceHeight, "Mic Scan Resume");		
	MicScanResume->add("Pause", 0, OnChoice, this, 0);
	MicScanResume->add("Time", 0, OnChoice, this, 0);
	MicScanResume->align(FL_ALIGN_TOP);

	
	


	DataMode = new Fl_Choice(MicScanResume->x() + choiceWidth + 20, MicScanResume->y() , choiceWidth, choiceHeight, "Data Mode");
	DataMode->add("PSK", 0, OnChoice, this, 0);
	DataMode->add("OTHERS", 0, OnChoice, this, 0);
	DataMode->align(FL_ALIGN_TOP);
	
	PSKTone = new Fl_Choice(DataMode->x() + choiceWidth + 20, DataMode->y() , choiceWidth, choiceHeight, "PSK Tone");
	PSKTone->add("1000 Hz", 0, OnChoice, this, 0);
	PSKTone->add("1500 Hz", 0, OnChoice, this, 0);
 	PSKTone->add("2000 Hz", 0, OnChoice, this, 0);
	PSKTone->align(FL_ALIGN_TOP);

	Lighting->show();
	Lighting->end();
}

void FT891::BuildRxEQGroup(int w, int h)
{
	int y = 60;
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;	
  	int sliderGap = 20 + sliderWidth;
	EQGroup = new Fl_Group(0, y, w, (h - y), "RX EQ");
    int choiceWidth = 80;
	int choiceHeight = 30;
	int choiceX = iStart + 40;
	AmSettings = new Fl_Group(1,y + 30, w/5 ,h  - choiceX - 30,"AM");
	AMLCUTFreq = new Fl_Choice(choiceX, AmSettings->y() + 15, choiceWidth,choiceHeight,"L Freq ");
	int hertz = 100;
	for(int i = 0 ; i < 20; i++ )
	{
		switch(i)
		{
			case 0:
			AMLCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			AMLCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}

	AMLCUTSlope = new Fl_Choice(choiceX,AMLCUTFreq->y() + 40,choiceWidth,choiceHeight, "L Slope");
	AMLCUTSlope->add("6db", 0, OnChoice, this, 0);
	AMLCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	AMHCUTFreq = new Fl_Choice(choiceX, AMLCUTSlope->y() + 40, choiceWidth,choiceHeight,"H Freq ");
	hertz = 700;
	for(int i = 0 ; i < 68; i++)
	{
		switch(i)
		{
			case 0:
			AMHCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			AMHCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}
	
	AMHCUTSlope = new Fl_Choice(choiceX,AMHCUTFreq->y() + 40, choiceWidth,choiceHeight, "H Slope");
	AMHCUTSlope->add("6db", 0, OnChoice, this, 0);
	AMHCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	AMOutLevel = new Fl_Value_Slider( AmSettings->x() + (AmSettings->w()/2) - (sliderWidth / 2) , AMHCUTSlope->y() + 65, sliderWidth,  -(AMHCUTSlope->y() - AmSettings->h()), "Out");
	AMOutLevel->align(FL_ALIGN_TOP);
	AMOutLevel->minimum(100);
	AMOutLevel->maximum(0);
	AMOutLevel->value(0.00000);
	AMOutLevel->step(1.0);
	AMOutLevel->callback((Fl_Callback*)OnScrollBar, this);

	AmSettings->box(FL_BORDER_BOX);
	AmSettings->end();


	CWSettings = new Fl_Group(AmSettings->x() + AmSettings->w(),y + 30, w/5 ,h  - choiceX - 30,"CW");
    choiceX = CWSettings->x() + (CWSettings->w() - choiceWidth) - 2;
	CWLCUTFreq = new Fl_Choice(choiceX, CWSettings->y() + 15, choiceWidth,choiceHeight,"L Freq ");
	hertz = 100;
	for(int i = 0 ; i < 20; i++ )
	{
		switch(i)
		{
			case 0:
			CWLCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			CWLCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}

	CWLCUTSlope = new Fl_Choice(choiceX,CWLCUTFreq->y() + 40,choiceWidth,choiceHeight, "L Slope");
	CWLCUTSlope->add("6db", 0, OnChoice, this, 0);
	CWLCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	CWHCUTFreq = new Fl_Choice(choiceX, CWLCUTSlope->y() + 40, choiceWidth,choiceHeight,"H Freq ");
	hertz = 700;
	for(int i = 0 ; i < 68; i++)
	{
		switch(i)
		{
			case 0:
			CWHCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			CWHCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}
	
	CWHCUTSlope = new Fl_Choice(choiceX,AMHCUTFreq->y() + 40, choiceWidth,choiceHeight, "H Slope");
	CWHCUTSlope->add("6db", 0, OnChoice, this, 0);
	CWHCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	CWOutLevel = new Fl_Value_Slider( CWSettings->x() + (CWSettings->w()/2) - (sliderWidth / 2) , CWHCUTSlope->y() + 65, sliderWidth,  -(CWHCUTSlope->y() - CWSettings->h()), "Out");
	CWOutLevel->align(FL_ALIGN_TOP);
	CWOutLevel->minimum(100);
	CWOutLevel->maximum(0);
	CWOutLevel->value(0.00000);
	CWOutLevel->step(1.0);
	CWOutLevel->callback((Fl_Callback*)OnScrollBar, this);

	CWSettings->box(FL_BORDER_BOX);
	CWSettings->end();

	RTTYSettings = new Fl_Group(CWSettings->x() + CWSettings->w(),y + 30, w/5 ,CWSettings->h(),"RTTY");
    choiceX = RTTYSettings->x() + (RTTYSettings->w() - choiceWidth) - 2;
	RTTYLCUTFreq = new Fl_Choice(choiceX, RTTYSettings->y() + 15, choiceWidth,choiceHeight,"L Freq ");
	hertz = 100;
	for(int i = 0 ; i < 20; i++ )
	{
		switch(i)
		{
			case 0:
			RTTYLCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			RTTYLCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}

	RTTYLCUTSlope = new Fl_Choice(choiceX,RTTYLCUTFreq->y() + 40,choiceWidth,choiceHeight, "L Slope");
	RTTYLCUTSlope->add("6db", 0, OnChoice, this, 0);
	RTTYLCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	RTTYHCUTFreq = new Fl_Choice(choiceX, RTTYLCUTSlope->y() + 40, choiceWidth,choiceHeight,"H Freq ");
	hertz = 700;
	for(int i = 0 ; i < 68; i++)
	{
		switch(i)
		{
			case 0:
			RTTYHCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			RTTYHCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}
	
	RTTYHCUTSlope = new Fl_Choice(choiceX,AMHCUTFreq->y() + 40, choiceWidth,choiceHeight, "H Slope");
	RTTYHCUTSlope->add("6db", 0, OnChoice, this, 0);
	RTTYHCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	RTTYOutLevel = new Fl_Value_Slider( RTTYSettings->x() + (RTTYSettings->w()/2) - (sliderWidth / 2) , RTTYHCUTSlope->y() + 65, sliderWidth,  -(RTTYHCUTSlope->y() - RTTYSettings->h()), "Out");
	RTTYOutLevel->align(FL_ALIGN_TOP);
	RTTYOutLevel->minimum(100);
	RTTYOutLevel->maximum(0);
	RTTYOutLevel->value(0.00000);
	RTTYOutLevel->step(1.0);
	RTTYOutLevel->callback((Fl_Callback*)OnScrollBar, this);

	RTTYSettings->box(FL_BORDER_BOX);
	RTTYSettings->end();

	DATASettings = new Fl_Group(RTTYSettings->x() + RTTYSettings->w(),y + 30, w/5 ,RTTYSettings->h(),"DATA");
    choiceX = DATASettings->x() + (DATASettings->w() - choiceWidth) - 2;
	DATALCUTFreq = new Fl_Choice(choiceX, DATASettings->y() + 15, choiceWidth,choiceHeight,"L Freq ");
	hertz = 100;
	for(int i = 0 ; i < 20; i++ )
	{
		switch(i)
		{
			case 0:
			DATALCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			DATALCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}

	DATALCUTSlope = new Fl_Choice(choiceX,DATALCUTFreq->y() + 40,choiceWidth,choiceHeight, "L Slope");
	DATALCUTSlope->add("6db", 0, OnChoice, this, 0);
	DATALCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	DATAHCUTFreq = new Fl_Choice(choiceX, DATALCUTSlope->y() + 40, choiceWidth,choiceHeight,"H Freq ");
	hertz = 700;
	for(int i = 0 ; i < 68; i++)
	{
		switch(i)
		{
			case 0:
			DATAHCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			DATAHCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}
	
	DATAHCUTSlope = new Fl_Choice(choiceX,AMHCUTFreq->y() + 40, choiceWidth,choiceHeight, "H Slope");
	DATAHCUTSlope->add("6db", 0, OnChoice, this, 0);
	DATAHCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	DATAOutLevel = new Fl_Value_Slider( DATASettings->x() + (DATASettings->w()/2) - (sliderWidth / 2) , DATAHCUTSlope->y() + 65, sliderWidth,  -(DATAHCUTSlope->y() - DATASettings->h()), "Out");
	DATAOutLevel->align(FL_ALIGN_TOP);
	DATAOutLevel->minimum(100);
	DATAOutLevel->maximum(0);
	DATAOutLevel->value(0.00000);
	DATAOutLevel->step(1.0);
	DATAOutLevel->callback((Fl_Callback*)OnScrollBar, this);

	DATASettings->box(FL_BORDER_BOX);
	DATASettings->end();


	SSBSettings = new Fl_Group(DATASettings->x() + DATASettings->w(),y + 30, w/5 ,DATASettings->h(),"SSB");
    choiceX = SSBSettings->x() + (SSBSettings->w() - choiceWidth) - 2;
	SSBLCUTFreq = new Fl_Choice(choiceX, SSBSettings->y() + 15, choiceWidth,choiceHeight,"L Freq ");
	hertz = 100;
	for(int i = 0 ; i < 20; i++ )
	{
		switch(i)
		{
			case 0:
			SSBLCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			SSBLCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}

	SSBLCUTSlope = new Fl_Choice(choiceX,SSBLCUTFreq->y() + 40,choiceWidth,choiceHeight, "L Slope");
	SSBLCUTSlope->add("6db", 0, OnChoice, this, 0);
	SSBLCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	SSBHCUTFreq = new Fl_Choice(choiceX, SSBLCUTSlope->y() + 40, choiceWidth,choiceHeight,"H Freq ");
	hertz = 700;
	for(int i = 0 ; i < 68; i++)
	{
		switch(i)
		{
			case 0:
			SSBHCUTFreq->add("OFF", 0, OnChoice, this, 0);
			break;
			default:
			SSBHCUTFreq->add(fmt::format("{:d}Hz",hertz).c_str(), 0, OnChoice, this, 0);
			hertz += 50;
			break;
		}
	}
	
	SSBHCUTSlope = new Fl_Choice(choiceX,AMHCUTFreq->y() + 40, choiceWidth,choiceHeight, "H Slope");
	SSBHCUTSlope->add("6db", 0, OnChoice, this, 0);
	SSBHCUTSlope->add("18db", 0, OnChoice, this, 0);
	
	SSBOutLevel = new Fl_Value_Slider( SSBSettings->x() + (SSBSettings->w()/2) - (sliderWidth / 2) , SSBHCUTSlope->y() + 65, sliderWidth,  -(SSBHCUTSlope->y() - SSBSettings->h()), "Out");
	SSBOutLevel->align(FL_ALIGN_TOP);
	SSBOutLevel->minimum(100);
	SSBOutLevel->maximum(0);
	SSBOutLevel->value(0.00000);
	SSBOutLevel->step(1.0);
	SSBOutLevel->callback((Fl_Callback*)OnScrollBar, this);

	SSBSettings->box(FL_BORDER_BOX);
	SSBSettings->end();

	EQGroup->end();
}

void FT891::BuildTXEQGroup(int w, int h)
{
	int y = 60;
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;	
  	int sliderGap = 20 + sliderWidth;
	
	TXEQGroup = new Fl_Group(0, y, w, (h - y), "TX EQ");
    
	int choiceWidth = (sliderWidth * 2) + 5;
	int choiceHeight = 30;
	int choiceX = iStart;

	MicEQGroup = new Fl_Group(0,TXEQGroup->y() + 30, TXEQGroup->w()/2, TXEQGroup->h() - 30, "MIC");
	MicEQGroup->box(FL_BORDER_BOX);
	MicCenterFreq1 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "Low Freq");
	MicCenterFreq1->add("OFF", 0, OnChoice, this, 0);
	MicCenterFreq1->add("100Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("200Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("300Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("400Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("500Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("600Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->add("700Hz", 0, OnChoice, this, 0);
	MicCenterFreq1->align(FL_ALIGN_TOP);

	MicEQLevel1 = new Fl_Value_Slider(choiceX, MicCenterFreq1->y() + MicCenterFreq1->h() + 25, sliderWidth,sliderHeight,"Level");
	MicEQLevel1->range(20, -20);
	MicEQLevel1->step(1.0);
	MicEQLevel1->callback((Fl_Callback*)::OnScrollBar,this);
	MicEQLevel1->align(FL_ALIGN_TOP);
	
	MicBandWidth1 = new Fl_Value_Slider(MicEQLevel1->x() + MicEQLevel1->w() + 5, MicEQLevel1->y(), sliderWidth,sliderHeight,"Width");
	MicBandWidth1->range(10, 1);
	MicBandWidth1->step(1.0);
	MicBandWidth1->callback((Fl_Callback*)::OnScrollBar,this);
	MicBandWidth1->align(FL_ALIGN_TOP);

	choiceX = choiceX + choiceWidth + 20;

	MicCenterFreq2 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "Mid Freq");
	MicCenterFreq2->align(FL_ALIGN_TOP);
	MicCenterFreq2->add("OFF", 0, OnChoice, this, 0);
	MicCenterFreq2->add("700Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("800Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("900Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1000Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1100Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1200Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1300Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1400Hz", 0, OnChoice, this, 0);
	MicCenterFreq2->add("1500Hz", 0, OnChoice, this, 0);

	MicEQLevel2 = new Fl_Value_Slider(choiceX, MicCenterFreq2->y() + MicCenterFreq2->h() + 25, sliderWidth,sliderHeight,"Level");
	MicEQLevel2->range(20, -20);
	MicEQLevel2->step(1.0);
	MicEQLevel2->callback((Fl_Callback*)::OnScrollBar,this);
	MicEQLevel2->align(FL_ALIGN_TOP);
	
	MicBandWidth2 = new Fl_Value_Slider(MicEQLevel2->x() + MicEQLevel2->w() + 5, MicEQLevel2->y(), sliderWidth,sliderHeight,"Width");
	MicBandWidth2->range(10, 1);
	MicBandWidth2->step(1.0);
	MicBandWidth2->callback((Fl_Callback*)::OnScrollBar,this);
	MicBandWidth2->align(FL_ALIGN_TOP);

	choiceX = choiceX + choiceWidth + 20;

	MicCenterFreq3 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "High Freq");
	MicCenterFreq3->align(FL_ALIGN_TOP);
	MicCenterFreq3->add("OFF", 0, OnChoice, this, 0);
	MicCenterFreq3->add("1500Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("1600Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("1700Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("1800Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("1900Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2000Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2100Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2200Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2300Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2400Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2500Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2600Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2700Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2800Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("2900Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("3000Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("3100Hz", 0, OnChoice, this, 0);
	MicCenterFreq3->add("3200Hz", 0, OnChoice, this, 0);


	MicEQLevel3 = new Fl_Value_Slider(choiceX, MicCenterFreq3->y() + MicCenterFreq3->h() + 25, sliderWidth,sliderHeight,"Level");
	MicEQLevel3->range(20, -20);
	MicEQLevel3->step(1.0);
	MicEQLevel3->callback((Fl_Callback*)::OnScrollBar,this);
	MicEQLevel3->align(FL_ALIGN_TOP);
	
	MicBandWidth3 = new Fl_Value_Slider(MicEQLevel3->x() + MicEQLevel3->w() + 5, MicEQLevel3->y(), sliderWidth,sliderHeight,"Width");
	MicBandWidth3->range(10, 1);
	MicBandWidth3->step(1.0);
	MicBandWidth3->callback((Fl_Callback*)::OnScrollBar,this);
	MicBandWidth3->align(FL_ALIGN_TOP);
	MicEQGroup->end();

	choiceX = choiceX + choiceWidth + 20;
	CompEQGroup = new Fl_Group(MicEQGroup->x() + MicEQGroup->w(), MicEQGroup->y(), MicEQGroup->w(), MicEQGroup->h(), "PROC");
	CompEQGroup->box(FL_BORDER_BOX);
	MicPCenterFreq1 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "Low Freq");
	MicPCenterFreq1->add("OFF", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("100Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("200Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("300Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("400Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("500Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("600Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->add("700Hz", 0, OnChoice, this, 0);
	MicPCenterFreq1->align(FL_ALIGN_TOP);

	MicPEQLevel1 = new Fl_Value_Slider(choiceX, MicPCenterFreq1->y() + MicPCenterFreq1->h() + 25, sliderWidth,sliderHeight,"Level");
	MicPEQLevel1->range(20, -20);
	MicPEQLevel1->step(1.0);
	MicPEQLevel1->callback((Fl_Callback*)::OnScrollBar,this);
	MicPEQLevel1->align(FL_ALIGN_TOP);
	
	MicPBandWidth1 = new Fl_Value_Slider(MicPEQLevel1->x() + MicPEQLevel1->w() + 5, MicPEQLevel1->y(), sliderWidth,sliderHeight,"Width");
	MicPBandWidth1->range(10, 1);
	MicPBandWidth1->step(1.0);
	MicPBandWidth1->callback((Fl_Callback*)::OnScrollBar,this);
	MicPBandWidth1->align(FL_ALIGN_TOP);

	choiceX = choiceX + choiceWidth + 20;

	MicPCenterFreq2 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "Mid Freq");
	MicPCenterFreq2->add("OFF", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("700Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("800Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("900Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1000Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1100Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1200Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1300Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1400Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->add("1500Hz", 0, OnChoice, this, 0);
	MicPCenterFreq2->align(FL_ALIGN_TOP);

	MicPEQLevel2 = new Fl_Value_Slider(choiceX, MicPCenterFreq2->y() + MicPCenterFreq2->h() + 25, sliderWidth,sliderHeight,"Level");
	MicPEQLevel2->range(20, -20);
	MicPEQLevel2->step(1.0);
	MicPEQLevel2->callback((Fl_Callback*)::OnScrollBar,this);
	MicPEQLevel2->align(FL_ALIGN_TOP);
	
	MicPBandWidth2 = new Fl_Value_Slider(MicPEQLevel2->x() + MicPEQLevel2->w() + 5, MicPEQLevel2->y(), sliderWidth,sliderHeight,"Width");
	MicPBandWidth2->range(10, 1);
	MicPBandWidth2->step(1.0);
	MicPBandWidth2->callback((Fl_Callback*)::OnScrollBar,this);
	MicPBandWidth2->align(FL_ALIGN_TOP);

	choiceX = choiceX + choiceWidth + 20;

	MicPCenterFreq3 = new Fl_Choice(choiceX,sliderTop - choiceHeight - 5,choiceWidth,choiceHeight, "High Freq");
	MicPCenterFreq3->add("OFF", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("1500Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("1600Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("1700Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("1800Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("1900Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2000Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2100Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2200Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2300Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2400Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2500Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2600Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2700Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2800Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("2900Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("3000Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("3100Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->add("3200Hz", 0, OnChoice, this, 0);
	MicPCenterFreq3->align(FL_ALIGN_TOP);

	MicPEQLevel3 = new Fl_Value_Slider(choiceX, MicPCenterFreq3->y() + MicPCenterFreq3->h() + 25, sliderWidth,sliderHeight,"Level");
	MicPEQLevel3->range(20, -20);
	MicPEQLevel3->step(1.0);
	MicPEQLevel3->callback((Fl_Callback*)::OnScrollBar,this);
	MicPEQLevel3->align(FL_ALIGN_TOP);
	
	MicPBandWidth3 = new Fl_Value_Slider(MicPEQLevel3->x() + MicPEQLevel3->w() + 5, MicPEQLevel3->y(), sliderWidth,sliderHeight,"Width");
	MicPBandWidth3->range(10, 1);
	MicPBandWidth3->step(1.0);
	MicPBandWidth3->callback((Fl_Callback*)::OnScrollBar,this);
	MicPBandWidth3->align(FL_ALIGN_TOP);
	CompEQGroup->end();
	TXEQGroup->end();

}

void OnTabChanged(Fl_Tabs* obj, void* cls)
{
	FT891* pthis = (FT891*)cls;
	pthis->OnTabChanged(obj);
}

void FT891::OnTabChanged(Fl_Tabs* tabs)
{
	
	if(tabs->value() == CatSettingsTab & CatSettingsLoaded == false)
	{
		CatSettingsLoaded = true;
		m_port.writeString(Menu::ReadSSBPTTSelect());
		m_port.writeString(Menu::ReadAMPTTSelect());
		m_port.writeString(Menu::ReadPktPTTSelect());
		m_port.writeString(Menu::ReadDATAPTTSelect());
		m_port.writeString(Menu::ReadCatRate());		
		m_port.writeString(Menu::ReadCatTOT());
		m_port.writeString(Menu::ReadCatTOT());
		m_port.writeString(Menu::ReadPCKeying());
	}
	else if(tabs->value() == TXEQGroup & TXEQGroupLoaded == false)
	{
		TXEQGroupLoaded = true;
		m_port.writeString(Menu::ReadEQ1Freq());
		m_port.writeString(Menu::ReadEQ1Bwth());
		m_port.writeString(Menu::ReadEQ1Level());			
		m_port.writeString(Menu::ReadEQ2Freq());
		m_port.writeString(Menu::ReadEQ2Bwth());
		m_port.writeString(Menu::ReadEQ2Level());		
		m_port.writeString(Menu::ReadEQ3Freq());	
		m_port.writeString(Menu::ReadEQ3Bwth());
		m_port.writeString(Menu::ReadEQ3Level());		
		m_port.writeString(Menu::ReadPEQ1Freq());	
		m_port.writeString(Menu::ReadPEQ2Freq());
		m_port.writeString(Menu::ReadPEQ3Freq());		
		m_port.writeString(Menu::ReadPEQ1Bwth());
		m_port.writeString(Menu::ReadPEQ2Bwth());
		m_port.writeString(Menu::ReadPEQ3Bwth());	
		m_port.writeString(Menu::ReadPEQ1Level());
		m_port.writeString(Menu::ReadPEQ2Level());
		m_port.writeString(Menu::ReadPEQ3Level());
	}
	else if(tabs->value() == EQGroup & EQGroupLoaded == false)
	{
		EQGroupLoaded = true;
		m_port.writeString(Menu::ReadAMLowCutFreq());
		m_port.writeString(Menu::ReadAMLowCutSlope());
		m_port.writeString(Menu::ReadAMHighCutFreq());
		m_port.writeString(Menu::ReadAMHighCutSlope());
		m_port.writeString(Menu::ReadAMOutLevel());
		m_port.writeString(Menu::ReadCWLowCutFreq());
		m_port.writeString(Menu::ReadCWLowCutSlope());
		m_port.writeString(Menu::ReadCWHighCutFreq());
		m_port.writeString(Menu::ReadCWHighCutSlope());
		m_port.writeString(Menu::ReadCWOutLevel());
		m_port.writeString(Menu::ReadRTTYLowCutFreq());
		m_port.writeString(Menu::ReadRTTYLowCutSlope());
		m_port.writeString(Menu::ReadRTTYHighCutFreq());
		m_port.writeString(Menu::ReadRTTYHighCutSlope());
		m_port.writeString(Menu::ReadRTTYOutLevel());
		m_port.writeString(Menu::ReadDATALowCutFreq());
		m_port.writeString(Menu::ReadDATALowCutSlope());
		m_port.writeString(Menu::ReadDATAHighCutFreq());
		m_port.writeString(Menu::ReadDATAHighCutSlope());
		m_port.writeString(Menu::ReadDATAOutLevel());
		m_port.writeString(Menu::ReadSSBLowCutFreq());
		m_port.writeString(Menu::ReadSSBLowCutSlope());
		m_port.writeString(Menu::ReadSSBHighCutFreq());
		m_port.writeString(Menu::ReadSSBHighCutSlope());
		m_port.writeString(Menu::ReadSSBOutLevel());
	}
	else if(tabs->value() == CWSettingsTab & CWGroupLoaded == false)
	{
		CWGroupLoaded = true;
		m_port.writeString(Menu::ReadQSKDelayTime());
		m_port.writeString(Menu::ReadCWBreakInType());
		m_port.writeString(Menu::ReadCWWaveShape());
		m_port.writeString(Menu::ReadCWFreqDisplay());
		m_port.writeString(Menu::ReadKeyerType());
		m_port.writeString(Menu::ReadKeyerDotDash());
		m_port.writeString(Menu::ReadCwWeight());
		m_port.writeString(Menu::ReadCWMemory1());
		m_port.writeString(Menu::ReadCWMemory2());
		m_port.writeString(Menu::ReadCWMemory3());
		m_port.writeString(Menu::ReadCWMemory4());
		m_port.writeString(Menu::ReadCWMemory5());
		m_port.writeString(KeyerMemory::Read(1));
		m_port.writeString(KeyerMemory::Read(2));
		m_port.writeString(KeyerMemory::Read(3));
		m_port.writeString(KeyerMemory::Read(4));
		m_port.writeString(KeyerMemory::Read(5));	
	}
	else if(tabs->value() == OutputPowerG & PowerGroupLoaded == false  )
	{
		PowerGroupLoaded = true;
		m_port.writeString(Menu::ReadHfPwr());
		m_port.writeString(Menu::ReadHfAmPwr());
		m_port.writeString(Menu::ReadHfSsbPwr());
		m_port.writeString(Menu::Read50mPwr());
		m_port.writeString(Menu::Read50mAmPwr());
		m_port.writeString(Menu::Read50mSsbPwr());
	}
	else if(tabs->value() == Lighting & LightingGrouploaded == false)
	{
		LightingGrouploaded = true;
		m_port.writeString(Menu::ReadBackliteDimmer());	
		m_port.writeString(Menu::ReadLcdDimmer());	
		m_port.writeString(Menu::ReadTxBusyDimmer());
		m_port.writeString(Menu::ReadLcdContrast());	
		m_port.writeString(Menu::ReadApo());
		m_port.writeString(Menu::ReadLcdDimmer());
		m_port.writeString(Menu::ReadFanControl());
		m_port.writeString(Menu::ReadMemGroup());
		m_port.writeString(Menu::ReadFMSetting());
		m_port.writeString(Menu::ReadRecSetting());
		m_port.writeString(Menu::ReadATASSetting());
		m_port.writeString(Menu::ReadTXTOT());
		m_port.writeString(Menu::ReadMicScan());
		m_port.writeString(Menu::ReadMicScanResume());		
		m_port.writeString(Menu::ReadDataMode());
		m_port.writeString(Menu::ReadPSKTone());
		m_port.writeString(Menu::ReadAgcFastDelay());
		m_port.writeString(Menu::ReadAgcMidDelay());
		m_port.writeString(Menu::ReadAgcSlowDelay());
	}

}
void FT891::BuildCatSettings(int w, int h)
{
	int y = 60;
	int iStart = 15;
  	int sliderTop = (h - y - 320);
  	int slidery =  h - 320 - 15;
	int sliderHeight = 320;
	int sliderWidth = 45;	
  	int sliderGap = 20 + sliderWidth;
	int choiceWidth = (sliderWidth * 2) + 5;
	int choiceHeight = 30;
	int choiceX = iStart;

	CatSettingsTab = new Fl_Group(0, y, w, (h - y), "Cat Settings");

	
    y += choiceHeight;
	AMPTTSelect = new Fl_Choice(iStart,y,choiceWidth,choiceHeight,"AM PTT");
	AMPTTSelect->add("DAKY", 0, OnChoice, this, 0);
	AMPTTSelect->add("RTS", 0, OnChoice, this, 0);
	AMPTTSelect->add("DTR", 0, OnChoice, this, 0);
	AMPTTSelect->align(FL_ALIGN_TOP);
	
	DATAPTTSelect = new Fl_Choice(AMPTTSelect->x() + choiceWidth + 20,y,choiceWidth,choiceHeight,"DATA PTT");
	DATAPTTSelect->add("DAKY", 0, OnChoice, this, 0);
	DATAPTTSelect->add("RTS", 0, OnChoice, this, 0);
	DATAPTTSelect->add("DTR", 0, OnChoice, this, 0);
	DATAPTTSelect->align(FL_ALIGN_TOP);

	PktPTTSelect = new Fl_Choice(DATAPTTSelect->x() + choiceWidth + 20,y,choiceWidth,choiceHeight,"PKT PTT");
	PktPTTSelect->add("DAKY", 0, OnChoice, this, 0);
	PktPTTSelect->add("RTS", 0, OnChoice, this, 0);
	PktPTTSelect->add("DTR", 0, OnChoice, this, 0);
	PktPTTSelect->align(FL_ALIGN_TOP);

	PCKeying = new Fl_Choice(PktPTTSelect->x() + choiceWidth + 20, PktPTTSelect->y() , choiceWidth, choiceHeight, "PC Keying");
	PCKeying->add("OFF", 0, OnChoice, this, 0);
	PCKeying->add("DAKY", 0, OnChoice, this, 0);
	PCKeying->add("RTS", 0, OnChoice, this, 0);
	PCKeying->add("DTR", 0, OnChoice, this, 0);
	PCKeying->align(FL_ALIGN_TOP);

	SSBPTTSelect = new Fl_Choice(PCKeying->x() + choiceWidth + 20,y,choiceWidth,choiceHeight,"PKT PTT");
	SSBPTTSelect->add("DAKY", 0, OnChoice, this, 0);
	SSBPTTSelect->add("RTS", 0, OnChoice, this, 0);
	SSBPTTSelect->add("DTR", 0, OnChoice, this, 0);
	SSBPTTSelect->align(FL_ALIGN_TOP);

	CatRateSelect = new Fl_Choice(SSBPTTSelect->x() + choiceWidth + 20, y, choiceWidth, choiceHeight, "CAT Rate");
	CatRateSelect->add("4800 bps", 0, OnChoice, this, 0);
	CatRateSelect->add("9600 bps", 0, OnChoice, this, 0);
	CatRateSelect->add("19200 bps", 0, OnChoice, this, 0);
	CatRateSelect->add("38400 bps", 0, OnChoice, this, 0);
	CatRateSelect->align(FL_ALIGN_TOP);

	y += choiceHeight + 20;

	CatTOTSelect = new Fl_Choice(AMPTTSelect->x(), y, choiceWidth, choiceHeight,"CAT TOT");
	CatTOTSelect->add("10 ms", 0, OnChoice, this, 0);
	CatTOTSelect->add("100 ms", 0, OnChoice, this, 0);
	CatTOTSelect->add("1000 ms", 0, OnChoice, this, 0);
	CatTOTSelect->add("3000 ms", 0, OnChoice, this, 0);
	CatTOTSelect->align(FL_ALIGN_TOP);


}

void FT891::Init()
{
		MemoryChannelEdit = false;
		m_port.writeString(AutoInformation::Set(InformationState::ON));
		m_port.writeString(Menu::ReadSSBBFO());
		m_port.writeString(Menu::ReadCWBFO());
		m_port.writeString(Menu::ReadDATABFO());
		m_port.writeString(Menu::ReadRTTYBFO());
		m_port.writeString(Menu::ReadClarSelect());		
		m_port.writeString(Clarifier::Read());
		m_port.writeString(INFORMATION::Read());
		m_port.writeString(VFO_B_FREQ::Read());
		m_port.writeString(MeterSW::Read());
		m_port.writeString(RFGain::Read());
		m_port.writeString(SquelchLevel::Read());
		m_port.writeString(Narrow::Read());
		m_port.writeString(Width::Read());
		m_port.writeString(PreAmp::Read());
		m_port.writeString(NoiseReduction::Read());
		m_port.writeString(NoiseBlankerStatus::Read());
		m_port.writeString(RFAttenuator::Read());
		m_port.writeString(FAST_STEP::Read());		
		m_port.writeString(MonitorLevel::Read(MonitorFunction::MontiorOnOff));
		m_port.writeString(MonitorLevel::Read(MonitorFunction::MontiorLevel));
		m_port.writeString(SpeechProcessor::Read(SpeechProcessorType::Processor));
		m_port.writeString(SpeechProcessor::Read(SpeechProcessorType::ParametricEqualizer));	
		m_port.writeString(VolumeLevel::Read());
		m_port.writeString(VoxStatus::Read());
		m_port.writeString(VFODialLock::Read());
		m_port.writeString(Split::Read());
}

void FT891::BuildUI(int w, int h)
{
	this->label("FT-891 Control");
	Tabs = new Fl_Tabs(0, 15, w, (h - 15),"");
	Tabs->callback((Fl_Callback*)&::OnTabChanged, this);
  	BuildGeneralGroup(w,h);
  	BuildPowerGroup(w,h);
	BuildLightingGroup(w,h);
	BuildRxEQGroup(w,h);
	BuildTXEQGroup(w,h);
	BuildCWSettings(w,h);
	BuildCatSettings(w, h);
	Tabs->show();
	Tabs->end();
	end();
}

FT891::FT891(int w, int h) : Fl_Double_Window(w, h), m_port("COM10", 38400),
CatSettingsLoaded(false),
TXEQGroupLoaded(false),
EQGroupLoaded(false),
CWGroupLoaded(false),
LightingGrouploaded(false),
PowerGroupLoaded(false)
{
	BuildUI(w,h);
	m_port.setCallback(std::bind(&FT891::readCallback, this, _1, _2));
	ReadPowerSwitch();	
}

FT891::FT891(int w, int h, string prt, int speed) : Fl_Double_Window(w, h), 
m_port(prt, speed),
CatSettingsLoaded(false),
TXEQGroupLoaded(false),
EQGroupLoaded(false),
CWGroupLoaded(false),
LightingGrouploaded(false),
PowerGroupLoaded(false)
{

	BuildUI(w,h);
	if(m_port.isOpen())
	{
		std::fstream fs("FT891.ini", std::ios::out);
		fs << "[PORTSETTINGS]" << std::endl;
		fs << "Port = " << prt << std::endl;
		fs << "Baud = " << speed << std::endl;
		fs.flush();
		fs.close();
	}
	m_port.setCallback(std::bind(&FT891::readCallback, this, _1, _2));
	ReadPowerSwitch();	
}

void FT891::OnPowerButtonClick(Fl_Light_Button* o, void* v)
{
	if (o->value() == 0)
	{
		PowerDown();		
		m_port.writeString(AutoInformation::Set(InformationState::OFF));
	}
	else
	{		
		PowerUp();   
		ReadPowerSwitch();
	}
}


int arg_parser( int argc, char** argv, int &i ) {
  return 0;
}

int main(int argc, char** argv)
{
		std::string port ;
		int baud = 0;
	try
	{	
			std::fstream fs("FT891.ini"); 
			if(!fs.is_open())
			{
				ComPortDialog* dlg = new ComPortDialog();
				dlg->set_modal();
				dlg->show();
				while(dlg->shown()) Fl::wait();
				port = dlg->m_PortName;
				switch(dlg->Rate)
				{
					case Yaesu::FT891::Commands::CatRateValue::_19200bps:
					baud = 19200;
					break;
					case Yaesu::FT891::Commands::CatRateValue::_38400bps:
					baud = 38400;
					break;
					case Yaesu::FT891::Commands::CatRateValue::_4800bps:
					baud = 4800;
					break;
					case Yaesu::FT891::Commands::CatRateValue::_9600bps:
					baud = 9600;
					break;
				}
			}
			else
			{
				fs.close();
				using boost::property_tree::ptree;
    			ptree pt;
    			read_ini("FT891.ini", pt);
				for (auto& section : pt)
    			{
					if(section.first.find("PORTSETTINGS") != string::npos)
					{
						for(auto& key : section.second)
						{
							if(key.first.find("Port")  != string::npos)
							{
								port = key.second.get_value<std::string>();
							}
							if(key.first.find("Baud") != string::npos)
							{
								baud = key.second.get_value<int>();
							}
						}
					}
				}
			}
		if(!port.empty())
		{
			FT891* MyWindow = new FT891(700, 600, port, baud);
			int arg_i;
			Fl::args( argc, argv, arg_i, &arg_parser );
			MyWindow->show(argc, argv);
			return Fl::run();
		}
		else
		{
			 std::string msg = "No Port provided";
			 MessageBox(nullptr,msg.c_str(),"FT891", MB_OK | MB_ICONERROR );
		}
	}
	catch(const std::exception& e)
	{
		 std::string msg = e.what();
		 if(msg.find("could not find port") != string::npos)
		 {
			 MessageBox(nullptr,"The port provided doesn't exist on your machine. Please ensure that the radio has a proper connection to the computer","FT891", MB_OK | MB_ICONERROR);
		 }
		 else if(msg.find("Access is denied") != string::npos)
		 {
			 MessageBox(nullptr,"The com port provided is in use. Either there's another instance of this application running, or some other application has control over the com port.", "FT891", MB_OK | MB_ICONERROR);
		 }
		 else
		 {
			 msg = msg.replace(msg.find("open:"), strlen("open:"), port);			 
			 MessageBox(nullptr,msg.c_str(),"FT891", MB_OK | MB_ICONERROR );
		 }
	}
}