void  MTConnectStreamsParser::DumpData(DataDictionary data)
{
	for(DataDictionary::iterator it = data.begin(); it!=data.end(); it++)
	{
		AtlTrace("%s = %s\n", (*it).first.c_str(), (*it).second.c_str());
	}
}
// Replace into data with newer from data
static DataDictionary  Merge(DataDictionary &into, DataDictionary &from)
{
	DataDictionary newdata = into;
	for(DataDictionary::iterator it=from.begin(); it!=from.end(); it++)
	{
		into[(*it).first]=(*it).second;
	}
	return newdata;
}
std::string  MTConnectStreamsParser::CreateHtmlTable(DataDictionary data)
{
	std::string updatetable;
	std::string style;

	updatetable += "<TABLE>\n";
	updatetable +=   "<TR>";
	std::string skip( "estop,controllermode,PartCountActual,avail,PartCountBad,power,probed,ProbeNumber,probe,path_feedratefrt" );
	for(DataDictionary::iterator it = data.begin(); it!=data.end(); it++)
	{
		if(skip.find((*it).first) != std::string::npos)
			continue;
		updatetable +=   "<TH> " + (*it).first    + "</TH> ";
	}
	updatetable +=   "</TR>\n";
	updatetable +=   "<TR>\n";
	for(DataDictionary::iterator it = data.begin(); it!=data.end(); it++)
	{
		style.clear();
		if(skip.find((*it).first) != std::string::npos)
			continue;
		if((*it).first == "Outtol")
		{

		}
		if((*it).first == "execution")
		{	
			if((*it).second == "READY")  
				style =   "style=\"background-color:lightblue;\"";
			if((*it).second == "ACTIVE")  
				style =    "style=\"background-color:lightgreen;\"";
		}

		updatetable +=   "<TD " + style + "> "+ (*it).second + "</TD>" ;
	}
	updatetable +=   "</TR>\n";

	updatetable += "</TABLE>\n";
	return updatetable;
}
std::string CAlarmHandler::CheckFault(DataDictionary datum)
{
	_lastfault=_currentfault;
	_currentfault.clear();
	// what if multiple faults?
	for(int i=0; i< _faults.size(); i++)
	{
		if(datum.find(_faults[i]) == datum.end())
			continue;
		int npos  =  datum[_faults[i]].find('.');
		std::string level = datum[_faults[i]];
		std::string msg = datum[_faults[i]];

		if(npos!= std::string::npos) level =  Trim(datum[_faults[i]].substr(0,npos));
		if(npos!= std::string::npos) msg =  Trim(datum[_faults[i]].substr(npos+1));

		// FIXME: just grabs the first fault and leaves.
		if( (level != "Normal") && (stricmp(level.c_str(), "Unavailable")!=0))
		{	
			_currentfault=_faults[i]+ " " + datum[_faults[i]];

			if(_currentfault != _lastfault)
			{
				// cant continually reset
				_alarmdatum.clear();
				_alarmdatum["RaisedAt"] = datum["Timestamp"];
				_alarmdatum["Shift"] = datum["Shift"];
				_alarmdatum["RaisedBy"] = datum["Machine"];
				_alarmdatum["Severity"] = level;
				_alarmdatum["Description"] =_faults[i] + "-" + msg;
				_alarmdatum["ResolvedAt"] = datum["Timestamp"];
				_alarmdatum["Program"] = datum["program"];
				double dTBF = _tbftimer.elapsed();
				_tbftimer.restart();
				WriteRegistryTimeFailure(0);
				_alarmdatum["TBF"]=DataDictionary::HrMinSecFormat((double)dTBF); 
			}

			return _currentfault;
		}
	}
	if(!_lastfault.empty() && _currentfault.empty())
	{
		_alarmdatum["ResolvedAt"] = datum["Timestamp"];
		
		ptime start = GetDateTime(_alarmdatum["RaisedAt"]);
		ptime done = GetDateTime(_alarmdatum["ResolvedAt"]);
		time_duration duration = done - start;
		_alarmdatum["TTR"] = DataDictionary::HrMinSecFormat((double)duration.total_seconds()); 


		// FIXME: there can be multiple alarms simulataneously ...
		_allfaultdatum.push_back(_alarmdatum);
		_myfaultdatum.push_back(_alarmdatum);
		LogFault(_alarmdatum);

		if(_alarmdatum["Severity"] == "Fault")
		{

		}
	}
	return _currentfault;
}