<commit_before>// NCCode.cpp

#include "stdafx.h"
#include "NCCode.h"
#include "../../tinyxml/tinyxml.h"
#include "OutputCanvas.h"
#include "../../interface/MarkedObject.h"
#include "../../interface/PropertyColor.h"
#include "../../interface/PropertyList.h"
#include "CNCConfig.h"

void ColouredText::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "text" );
	root->LinkEndChild( element ); 

	// add actual text as a child object
    	TiXmlText* text = new TiXmlText(Ttc(m_str.c_str()));
    	element->LinkEndChild(text);

	if(m_color_type != TextColorDefaultType)element->SetAttribute("col", CNCCode::m_text_colors_str[m_color_type].c_str());
}

void ColouredText::ReadFromXMLElement(TiXmlElement* element)
{
	m_color_type = TextColorDefaultType;

	// get the attributes
	for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "col"){
			std::string coltype(a->Value());
			for(int i = 0; i<MaxTextColorTypes; i++)
			{
				if(coltype == CNCCode::m_text_colors_str[i])
				{
					m_color_type = (TextColorEnum)i;
					break;
				}
			}
		}
	}

	// get the text
	m_str = wxString(Ctt(element->GetText()));
}

void PathLine::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "line" );
	root->LinkEndChild( element ); 
	element->SetDoubleAttribute("x", m_x[0]);
	element->SetDoubleAttribute("y", m_x[1]);
	element->SetDoubleAttribute("z", m_x[2]);
}

void PathLine::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "x"){m_x[0] = a->DoubleValue();}
		else if(name == "y"){m_x[1] = a->DoubleValue();}
		else if(name == "z"){m_x[2] = a->DoubleValue();}
	}
}

void PathLine::glVertices(const PathObject* prev_po)
{
	if(prev_po)glVertex3dv(prev_po->m_x);
	glVertex3dv(m_x);
}

void PathArc::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element = new TiXmlElement( "arc" );
	root->LinkEndChild( element ); 

	element->SetDoubleAttribute("x", m_x[0]);
	element->SetDoubleAttribute("y", m_x[1]);
	element->SetDoubleAttribute("z", m_x[2]);
	element->SetDoubleAttribute("i", m_c[0]);
	element->SetDoubleAttribute("j", m_c[1]);
	element->SetDoubleAttribute("k", m_c[2]);
	element->SetDoubleAttribute("d", m_dir);
}

void PathArc::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "x"){m_x[0] = a->DoubleValue();}
		else if(name == "y"){m_x[1] = a->DoubleValue();}
		else if(name == "z"){m_x[2] = a->DoubleValue();}
		else if(name == "i"){m_c[0] = a->DoubleValue();}
		else if(name == "j"){m_c[1] = a->DoubleValue();}
		else if(name == "k"){m_c[2] = a->DoubleValue();}
		else if(name == "d"){m_dir = a->IntValue();}
	}
}

void PathArc::glVertices(const PathObject* prev_po)
{
	if(prev_po == NULL)return;

	double sx = -m_c[0];
	double sy = -m_c[1];
	// e = cs + se = -c + e - s
	double ex = -m_c[0] + m_x[0] - prev_po->m_x[0];
	double ey = -m_c[1] + m_x[1] - prev_po->m_x[1];
	double rs = sqrt(sx * sx + sy * sy);
	double re = sqrt(ex * ex + ey * ey);

	double start_angle = atan2(sy, sx);
	double end_angle = atan2(ey, ex);

	if(m_dir == 1){
		if(end_angle < start_angle)end_angle += 6.283185307179;
	}
	else{
		if(start_angle < end_angle)start_angle += 6.283185307179;
	}

	double angle_step = (end_angle - start_angle) / 10;
	glVertex3dv(prev_po->m_x);
	for(int i = 0; i< 10; i++)
	{
		double angle = start_angle + angle_step * (i + 1);
		double r = rs + ((re - rs) * (i + 1)) /10;
		double x = prev_po->m_x[0] + m_c[0] + r * cos(angle);
		double y = prev_po->m_x[1] + m_c[1] + r * sin(angle);
		double z = prev_po->m_x[2] + ((m_x[2] - prev_po->m_x[2]) * (i+1))/10;
		glVertex3d(x, y, z);
	}
}

ColouredPath::ColouredPath(const ColouredPath& c)
{
	operator=(c);
}

const ColouredPath &ColouredPath::operator=(const ColouredPath& c)
{
	Clear();
	m_color_type = c.m_color_type;
	for(std::list< PathObject* >::const_iterator It = c.m_points.begin(); It != c.m_points.end(); It++)
	{
		PathObject* object = *It;
		m_points.push_back(object->MakeACopy());
	}
	return *this;
}

void ColouredPath::Clear()
{
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* object = *It;
		delete object;
	}
	m_points.clear();
}

void ColouredPath::glCommands()
{
	CNCCode::m_lines_colors[m_color_type].glColor();
	glBegin(GL_LINE_STRIP);
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po = *It;
		po->glVertices(CNCCode::prev_po);
		CNCCode::prev_po = po;
	}
	glEnd();
}

void ColouredPath::GetBox(CBox &box)
{
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po= *It;
		box.Insert(po->m_x);
	}
}

void ColouredPath::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "path" );
	root->LinkEndChild( element ); 

	element->SetAttribute("col", CNCCode::m_lines_colors_str[m_color_type].c_str());
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po = *It;
		po->WriteXML(element);
	}
}

void ColouredPath::ReadFromXMLElement(TiXmlElement* element)
{
	// get the attributes
	for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "col"){
			std::string coltype(a->Value());
			for(int i = 0; i<MaxLinesColorType; i++)
			{
				if(coltype == CNCCode::m_lines_colors_str[i])
				{
					m_color_type = (LinesColorEnum)i;
					break;
				}
			}
		}
	}

	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "line")
		{
			PathLine *new_object = new PathLine;
			new_object->ReadFromXMLElement(pElem);
			m_points.push_back(new_object);
		}
		else if(name == "arc")
		{
			PathArc *new_object = new PathArc;
			new_object->ReadFromXMLElement(pElem);
			m_points.push_back(new_object);
		}
	}
}

HeeksObj *CNCCodeBlock::MakeACopy(void)const{return new CNCCodeBlock(*this);}

void CNCCodeBlock::glCommands(bool select, bool marked, bool no_color)
{
	if(marked)glLineWidth(3);

	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath& line_strip = *It;
		line_strip.glCommands();
	}

	if(marked)glLineWidth(1);
}

void CNCCodeBlock::GetBox(CBox &box)
{
	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath& line_strip = *It;
		line_strip.GetBox(box);
	}
}

void CNCCodeBlock::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "ncblock" );
	root->LinkEndChild( element ); 

	for(std::list<ColouredText>::iterator It = m_text.begin(); It != m_text.end(); It++)
	{
		ColouredText &text = *It;
		text.WriteXML(element);
	}

	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath &line_strip = *It;
		line_strip.WriteXML(element);
	}

	WriteBaseXML(element);
}

// static 
HeeksObj* CNCCodeBlock::ReadFromXMLElement(TiXmlElement* element)
{
	CNCCodeBlock* new_object = new CNCCodeBlock;
	new_object->m_from_pos = CNCCode::pos;

	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "text")
		{
			ColouredText t;
			t.ReadFromXMLElement(pElem);
			new_object->m_text.push_back(t);
			CNCCode::pos += t.m_str.Len();
		}
		else if(name == "path")
		{
			ColouredPath l;
			l.ReadFromXMLElement(pElem);
			new_object->m_line_strips.push_back(l);
		}
	}

#ifdef WIN32
	CNCCode::pos += 2; // 2 for each line ( presumably \r\n )
#else
	CNCCode::pos += 1;
#endif

	new_object->m_to_pos = CNCCode::pos;

	new_object->ReadBaseXML(element);

	return new_object;
}

void CNCCodeBlock::AppendTextCtrl(wxTextCtrl *textCtrl)
{
	for(std::list<ColouredText>::iterator It = m_text.begin(); It != m_text.end(); It++)
	{
		ColouredText &text = *It;
		HeeksColor &col = CNCCode::m_text_colors[text.m_color_type];
		wxColour c(col.red, col.green, col.blue);
		textCtrl->SetDefaultStyle(wxTextAttr(c));
		textCtrl->AppendText(text.m_str);
	}
	textCtrl->AppendText(_T("\n"));
}

long CNCCode::pos = 0;
// static
PathObject* CNCCode::prev_po = NULL;

HeeksColor CNCCode::m_text_colors[MaxTextColorTypes];

std::string CNCCode::m_text_colors_str[MaxTextColorTypes] = {
	std::string("default"), // won't get written
	std::string("blocknum"),
	std::string("misc"),
	std::string("program"),
	std::string("tool"),
	std::string("comment"),
	std::string("variable"),
	std::string("prep"),
	std::string("axis"),
	std::string("rapid"),
	std::string("feed")
};

// static
void CNCCode::ReadColorsFromConfig()
{
	CNCConfig config;
	long col;
	config.Read(_T("TextColorDefaultType"),		&col, RGB(0, 0, 0)); CNCCode::m_text_colors[TextColorDefaultType] = HeeksColor(col);
	config.Read(_T("TextColorBlockType"),		&col, RGB(0, 222, 0)); CNCCode::m_text_colors[TextColorBlockType] = HeeksColor(col);
	config.Read(_T("TextColorMiscType"),		&col, RGB(0, 200, 0)); CNCCode::m_text_colors[TextColorMiscType] = HeeksColor(col);
	config.Read(_T("TextColorProgramType"),		&col, RGB(255, 128, 0)); CNCCode::m_text_colors[TextColorProgramType] = HeeksColor(col);
	config.Read(_T("TextColorToolType"),		&col, RGB(200, 200, 0)); CNCCode::m_text_colors[TextColorToolType] = HeeksColor(col);
	config.Read(_T("TextColorCommentType"),		&col, RGB(0, 200, 200)); CNCCode::m_text_colors[TextColorCommentType] = HeeksColor(col);
	config.Read(_T("TextColorVariableType"),	&col, RGB(164, 88, 188)); CNCCode::m_text_colors[TextColorVariableType] = HeeksColor(col);
	config.Read(_T("TextColorPrepType"),		&col, RGB(255, 0, 175)); CNCCode::m_text_colors[TextColorPrepType] = HeeksColor(col);
	config.Read(_T("TextColorAxisType"),		&col, RGB(189, 86, 86)); CNCCode::m_text_colors[TextColorAxisType] = HeeksColor(col);
	config.Read(_T("TextColorRapidType"),		&col, RGB(222, 0, 0)); CNCCode::m_text_colors[TextColorRapidType] = HeeksColor(col);
	config.Read(_T("TextColorFeedType"),		&col, RGB(0, 179, 0)); CNCCode::m_text_colors[TextColorFeedType] = HeeksColor(col);

	config.Read(_T("LinesColorRapidType"),		&col, RGB(255, 0, 0)); CNCCode::m_lines_colors[LinesColorRapidType] = HeeksColor(col);
	config.Read(_T("LinesColorFeedType"),		&col, RGB(0, 255, 0)); CNCCode::m_lines_colors[LinesColorFeedType] = HeeksColor(col);
}

// static
void CNCCode::WriteColorsToConfig()
{
	CNCConfig config;

	config.Write(_T("TextColorDefaultType"),	CNCCode::m_text_colors[TextColorDefaultType	].COLORREF_color());
	config.Write(_T("TextColorBlockType"),		CNCCode::m_text_colors[TextColorBlockType	].COLORREF_color());
	config.Write(_T("TextColorMiscType"),		CNCCode::m_text_colors[TextColorMiscType	].COLORREF_color());
	config.Write(_T("TextColorProgramType"),	CNCCode::m_text_colors[TextColorProgramType	].COLORREF_color());<commit_msg>RGB not found on Linux build<commit_after>// NCCode.cpp

#include "stdafx.h"
#include "NCCode.h"
#include "../../tinyxml/tinyxml.h"
#include "OutputCanvas.h"
#include "../../interface/MarkedObject.h"
#include "../../interface/PropertyColor.h"
#include "../../interface/PropertyList.h"
#include "CNCConfig.h"

void ColouredText::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "text" );
	root->LinkEndChild( element ); 

	// add actual text as a child object
    	TiXmlText* text = new TiXmlText(Ttc(m_str.c_str()));
    	element->LinkEndChild(text);

	if(m_color_type != TextColorDefaultType)element->SetAttribute("col", CNCCode::m_text_colors_str[m_color_type].c_str());
}

void ColouredText::ReadFromXMLElement(TiXmlElement* element)
{
	m_color_type = TextColorDefaultType;

	// get the attributes
	for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "col"){
			std::string coltype(a->Value());
			for(int i = 0; i<MaxTextColorTypes; i++)
			{
				if(coltype == CNCCode::m_text_colors_str[i])
				{
					m_color_type = (TextColorEnum)i;
					break;
				}
			}
		}
	}

	// get the text
	m_str = wxString(Ctt(element->GetText()));
}

void PathLine::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "line" );
	root->LinkEndChild( element ); 
	element->SetDoubleAttribute("x", m_x[0]);
	element->SetDoubleAttribute("y", m_x[1]);
	element->SetDoubleAttribute("z", m_x[2]);
}

void PathLine::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "x"){m_x[0] = a->DoubleValue();}
		else if(name == "y"){m_x[1] = a->DoubleValue();}
		else if(name == "z"){m_x[2] = a->DoubleValue();}
	}
}

void PathLine::glVertices(const PathObject* prev_po)
{
	if(prev_po)glVertex3dv(prev_po->m_x);
	glVertex3dv(m_x);
}

void PathArc::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element = new TiXmlElement( "arc" );
	root->LinkEndChild( element ); 

	element->SetDoubleAttribute("x", m_x[0]);
	element->SetDoubleAttribute("y", m_x[1]);
	element->SetDoubleAttribute("z", m_x[2]);
	element->SetDoubleAttribute("i", m_c[0]);
	element->SetDoubleAttribute("j", m_c[1]);
	element->SetDoubleAttribute("k", m_c[2]);
	element->SetDoubleAttribute("d", m_dir);
}

void PathArc::ReadFromXMLElement(TiXmlElement* pElem)
{
	// get the attributes
	for(TiXmlAttribute* a = pElem->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "x"){m_x[0] = a->DoubleValue();}
		else if(name == "y"){m_x[1] = a->DoubleValue();}
		else if(name == "z"){m_x[2] = a->DoubleValue();}
		else if(name == "i"){m_c[0] = a->DoubleValue();}
		else if(name == "j"){m_c[1] = a->DoubleValue();}
		else if(name == "k"){m_c[2] = a->DoubleValue();}
		else if(name == "d"){m_dir = a->IntValue();}
	}
}

void PathArc::glVertices(const PathObject* prev_po)
{
	if(prev_po == NULL)return;

	double sx = -m_c[0];
	double sy = -m_c[1];
	// e = cs + se = -c + e - s
	double ex = -m_c[0] + m_x[0] - prev_po->m_x[0];
	double ey = -m_c[1] + m_x[1] - prev_po->m_x[1];
	double rs = sqrt(sx * sx + sy * sy);
	double re = sqrt(ex * ex + ey * ey);

	double start_angle = atan2(sy, sx);
	double end_angle = atan2(ey, ex);

	if(m_dir == 1){
		if(end_angle < start_angle)end_angle += 6.283185307179;
	}
	else{
		if(start_angle < end_angle)start_angle += 6.283185307179;
	}

	double angle_step = (end_angle - start_angle) / 10;
	glVertex3dv(prev_po->m_x);
	for(int i = 0; i< 10; i++)
	{
		double angle = start_angle + angle_step * (i + 1);
		double r = rs + ((re - rs) * (i + 1)) /10;
		double x = prev_po->m_x[0] + m_c[0] + r * cos(angle);
		double y = prev_po->m_x[1] + m_c[1] + r * sin(angle);
		double z = prev_po->m_x[2] + ((m_x[2] - prev_po->m_x[2]) * (i+1))/10;
		glVertex3d(x, y, z);
	}
}

ColouredPath::ColouredPath(const ColouredPath& c)
{
	operator=(c);
}

const ColouredPath &ColouredPath::operator=(const ColouredPath& c)
{
	Clear();
	m_color_type = c.m_color_type;
	for(std::list< PathObject* >::const_iterator It = c.m_points.begin(); It != c.m_points.end(); It++)
	{
		PathObject* object = *It;
		m_points.push_back(object->MakeACopy());
	}
	return *this;
}

void ColouredPath::Clear()
{
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* object = *It;
		delete object;
	}
	m_points.clear();
}

void ColouredPath::glCommands()
{
	CNCCode::m_lines_colors[m_color_type].glColor();
	glBegin(GL_LINE_STRIP);
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po = *It;
		po->glVertices(CNCCode::prev_po);
		CNCCode::prev_po = po;
	}
	glEnd();
}

void ColouredPath::GetBox(CBox &box)
{
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po= *It;
		box.Insert(po->m_x);
	}
}

void ColouredPath::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "path" );
	root->LinkEndChild( element ); 

	element->SetAttribute("col", CNCCode::m_lines_colors_str[m_color_type].c_str());
	for(std::list< PathObject* >::iterator It = m_points.begin(); It != m_points.end(); It++)
	{
		PathObject* po = *It;
		po->WriteXML(element);
	}
}

void ColouredPath::ReadFromXMLElement(TiXmlElement* element)
{
	// get the attributes
	for(TiXmlAttribute* a = element->FirstAttribute(); a; a = a->Next())
	{
		std::string name(a->Name());
		if(name == "col"){
			std::string coltype(a->Value());
			for(int i = 0; i<MaxLinesColorType; i++)
			{
				if(coltype == CNCCode::m_lines_colors_str[i])
				{
					m_color_type = (LinesColorEnum)i;
					break;
				}
			}
		}
	}

	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "line")
		{
			PathLine *new_object = new PathLine;
			new_object->ReadFromXMLElement(pElem);
			m_points.push_back(new_object);
		}
		else if(name == "arc")
		{
			PathArc *new_object = new PathArc;
			new_object->ReadFromXMLElement(pElem);
			m_points.push_back(new_object);
		}
	}
}

HeeksObj *CNCCodeBlock::MakeACopy(void)const{return new CNCCodeBlock(*this);}

void CNCCodeBlock::glCommands(bool select, bool marked, bool no_color)
{
	if(marked)glLineWidth(3);

	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath& line_strip = *It;
		line_strip.glCommands();
	}

	if(marked)glLineWidth(1);
}

void CNCCodeBlock::GetBox(CBox &box)
{
	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath& line_strip = *It;
		line_strip.GetBox(box);
	}
}

void CNCCodeBlock::WriteXML(TiXmlElement *root)
{
	TiXmlElement * element;
	element = new TiXmlElement( "ncblock" );
	root->LinkEndChild( element ); 

	for(std::list<ColouredText>::iterator It = m_text.begin(); It != m_text.end(); It++)
	{
		ColouredText &text = *It;
		text.WriteXML(element);
	}

	for(std::list<ColouredPath>::iterator It = m_line_strips.begin(); It != m_line_strips.end(); It++)
	{
		ColouredPath &line_strip = *It;
		line_strip.WriteXML(element);
	}

	WriteBaseXML(element);
}

// static 
HeeksObj* CNCCodeBlock::ReadFromXMLElement(TiXmlElement* element)
{
	CNCCodeBlock* new_object = new CNCCodeBlock;
	new_object->m_from_pos = CNCCode::pos;

	// loop through all the objects
	for(TiXmlElement* pElem = TiXmlHandle(element).FirstChildElement().Element(); pElem; pElem = pElem->NextSiblingElement())
	{
		std::string name(pElem->Value());
		if(name == "text")
		{
			ColouredText t;
			t.ReadFromXMLElement(pElem);
			new_object->m_text.push_back(t);
			CNCCode::pos += t.m_str.Len();
		}
		else if(name == "path")
		{
			ColouredPath l;
			l.ReadFromXMLElement(pElem);
			new_object->m_line_strips.push_back(l);
		}
	}

#ifdef WIN32
	CNCCode::pos += 2; // 2 for each line ( presumably \r\n )
#else
	CNCCode::pos += 1;
#endif

	new_object->m_to_pos = CNCCode::pos;

	new_object->ReadBaseXML(element);

	return new_object;
}

void CNCCodeBlock::AppendTextCtrl(wxTextCtrl *textCtrl)
{
	for(std::list<ColouredText>::iterator It = m_text.begin(); It != m_text.end(); It++)
	{
		ColouredText &text = *It;
		HeeksColor &col = CNCCode::m_text_colors[text.m_color_type];
		wxColour c(col.red, col.green, col.blue);
		textCtrl->SetDefaultStyle(wxTextAttr(c));
		textCtrl->AppendText(text.m_str);
	}
	textCtrl->AppendText(_T("\n"));
}

long CNCCode::pos = 0;
// static
PathObject* CNCCode::prev_po = NULL;

HeeksColor CNCCode::m_text_colors[MaxTextColorTypes];

std::string CNCCode::m_text_colors_str[MaxTextColorTypes] = {
	std::string("default"), // won't get written
	std::string("blocknum"),
	std::string("misc"),
	std::string("program"),
	std::string("tool"),
	std::string("comment"),
	std::string("variable"),
	std::string("prep"),
	std::string("axis"),
	std::string("rapid"),
	std::string("feed")
};

// static
void CNCCode::ReadColorsFromConfig()
{
	CNCConfig config;
	long col;
	config.Read(_T("TextColorDefaultType"),		&col, HeeksColor(0, 0, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorDefaultType] = HeeksColor(col);
	config.Read(_T("TextColorBlockType"),		&col, HeeksColor(0, 222, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorBlockType] = HeeksColor(col);
	config.Read(_T("TextColorMiscType"),		&col, HeeksColor(0, 200, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorMiscType] = HeeksColor(col);
	config.Read(_T("TextColorProgramType"),		&col, HeeksColor(255, 128, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorProgramType] = HeeksColor(col);
	config.Read(_T("TextColorToolType"),		&col, HeeksColor(200, 200, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorToolType] = HeeksColor(col);
	config.Read(_T("TextColorCommentType"),		&col, HeeksColor(0, 200, 200).COLORREF_color()); CNCCode::m_text_colors[TextColorCommentType] = HeeksColor(col);
	config.Read(_T("TextColorVariableType"),	&col, HeeksColor(164, 88, 188).COLORREF_color()); CNCCode::m_text_colors[TextColorVariableType] = HeeksColor(col);
	config.Read(_T("TextColorPrepType"),		&col, HeeksColor(255, 0, 175).COLORREF_color()); CNCCode::m_text_colors[TextColorPrepType] = HeeksColor(col);
	config.Read(_T("TextColorAxisType"),		&col, HeeksColor(189, 86, 86).COLORREF_color()); CNCCode::m_text_colors[TextColorAxisType] = HeeksColor(col);
	config.Read(_T("TextColorRapidType"),		&col, HeeksColor(222, 0, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorRapidType] = HeeksColor(col);
	config.Read(_T("TextColorFeedType"),		&col, HeeksColor(0, 179, 0).COLORREF_color()); CNCCode::m_text_colors[TextColorFeedType] = HeeksColor(col);

	config.Read(_T("LinesColorRapidType"),		&col, HeeksColor(255, 0, 0).COLORREF_color()); CNCCode::m_lines_colors[LinesColorRapidType] = HeeksColor(col);
	config.Read(_T("LinesColorFeedType"),		&col, HeeksColor(0, 255, 0).COLORREF_color()); CNCCode::m_lines_colors[LinesColorFeedType] = HeeksColor(col);
}

// static
void CNCCode::WriteColorsToConfig()
{
	CNCConfig config;

	config.Write(_T("TextColorDefaultType"),	CNCCode::m_text_colors[TextColorDefaultType	].COLORREF_color());
	config.Write(_T("TextColorBlockType"),		CNCCode::m_text_colors[TextColorBlockType	].COLORREF_color());
	config.Write(_T("TextColorMiscType"),		CNCCode::m_text_colors[TextColorMiscType	].COLORREF_color());
	config.Write(_T("TextColorProgramType"),	CNCCode::m_text_colors[TextColorProgramType	].COLORREF_color());
{'fraction_non_alphanumeric': 0.18408047233763394, 'fraction_numerical': 0.014345068882571615, 'mean_word_length': 5.5574992830513334, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 161, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2588089', 'n_tokens_mistral': 9518, 'n_tokens_neox': 8892, 'n_words': 1488}