void ofxTimeMeasurements::loadSettings(){

	//todo this might get called before OF is setup, os ofToDataPath gives us weird results sometimes?
	string f = ofToDataPath(TIME_MEASUREMENTS_SETTINGS_FILENAME, true);
	ifstream myfile(f.c_str());
	string name, visible, enabled_, plotting;
	bool fileHasPlotData = false;
	if (myfile.is_open()){

		int c = 0;
		while( !myfile.eof() ){

			if (c == 0){ //see if file has PlotData, 2 '|' per line if it does, only 1 if it doesnt
				string wholeLine;
				getline( myfile, wholeLine, '\n' );//see what version we are on
				int numBars = 0;
				for(int i = 0; i < wholeLine.size(); i++){
					if (wholeLine[i] == '|') numBars++;
				}
				if(numBars == 2) fileHasPlotData = true;
				myfile.clear();
				myfile.seekg(0, ios::beg);
				c++;
			}

			getline( myfile, name, '=' );//name
			getline( myfile, visible, '|' ); //visible
			if(fileHasPlotData){
				getline( myfile, enabled_, '|' ); //enabled
				getline( myfile, plotting, '\n' ); //plotting
			}else{
				getline( myfile, enabled_, '\n' ); //enabled
			}

			if (name == TIME_MEASUREMENTS_SETUP_KEY ||
				name == TIME_MEASUREMENTS_UPDATE_KEY ||
				name == TIME_MEASUREMENTS_DRAW_KEY ){
				visible = enabled_ = "1";
			}
			if(name.length()){
				settings[name].visible = bool(visible == "1" ? true : false);
				settings[name].enabled = bool(enabled_ == "1" ? true : false);
				#if defined(USE_OFX_HISTORYPLOT)
				settings[name].plotting = bool(plotting == "1" ? true : false);
				if(settings[name].plotting){
					ofxHistoryPlot * plot = makeNewPlot(name);
					plots[name] = plot;
				}
				#endif
			}
			//ofLogVerbose("ofxTimeMeasurements") << "loaded settings for " << name << " enabled: " << settings[name].enabled << " visible: " << settings[name].visible ;
		}
		myfile.close();
	}else{
		ofLogWarning("ofxTimeMeasurements") << "Unable to load Settings file " << TIME_MEASUREMENTS_SETTINGS_FILENAME;
	}
}
bool ofxTimeMeasurements::_keyPressed(ofKeyEventArgs &e){

	if (e.key == enableKey){
		TIME_SAMPLE_SET_ENABLED(!TIME_SAMPLE_GET_ENABLED());
	}

	if (TIME_SAMPLE_GET_ENABLED()){
		if (e.key == activateKey){
			menuActive = !menuActive;
		}

		if(e.key == 'A') averaging ^= true;  //Average Toggle
		if(e.key == 'B') internalBenchmark ^= true;  //internalBenchmark Toggle
		if (e.key == 'F') freeze ^= true;  //free measurements

		if(e.key == 'V'){ //make all timings visible!
			unordered_map<string, TimeMeasurement*>::iterator it = times.begin();
			while(it != times.end()){
				it->second->settings.visible = true;
				++it;
			}
		}

		if(e.key == 'L'){
			drawLocation = ofxTMDrawLocation(drawLocation+1);
			if(drawLocation == TIME_MEASUREMENTS_NUM_DRAW_LOCATIONS) drawLocation = ofxTMDrawLocation(0);
		}

		bool ret = false;
		if(menuActive){

			if (drawLines.size()){
				int selIndex = -1;
				for(int i = 0; i < drawLines.size(); i++){
					if (drawLines[i].key == selection) selIndex = i;
				}
				if(selIndex != -1){
					switch (e.key) {

						case OF_KEY_DOWN:{
							selIndex ++;
							if(selIndex >= drawLines.size()) selIndex = 0;
							while(drawLines[selIndex].tm == NULL){
								selIndex ++;
								if(selIndex >= drawLines.size()) selIndex = 0;
							}
							selection = drawLines[selIndex].key;
						}break;

						case OF_KEY_UP:{
							selIndex --;
							if(selIndex < 0 ) selIndex = drawLines.size() - 1;
							while(drawLines[selIndex].tm == NULL){
								selIndex --;
								if(selIndex < 0 ) selIndex = drawLines.size() - 1;
							}
							selection = drawLines[selIndex].key;
						}break;

						#if defined(USE_OFX_HISTORYPLOT)
						case 'P':{
							if (!plots[selection]){
								plots[selection] = makeNewPlot(selection);
								times[selection]->settings.plotting = true;
							}else{
								times[selection]->settings.plotting ^= true;
							}
						}break;
						#endif

						case OF_KEY_RETURN:{
								//cant disable update() & draw()
								if (selection != TIME_MEASUREMENTS_SETUP_KEY &&
									selection != TIME_MEASUREMENTS_UPDATE_KEY &&
									selection != TIME_MEASUREMENTS_DRAW_KEY &&
									drawLines[selIndex].tm
									){
										times[selection]->settings.enabled ^= true;
								}
							}break;

						case OF_KEY_RIGHT:
							collapseExpand(selection, false); //expand
						break;

						case OF_KEY_LEFT:
							collapseExpand(selection, true ); //collapse
							break;
					}
				}
			}
			ret = e.key != OF_KEY_ESC; //return true or false; if returning true, it stops the event chain
			//so, next listerners will not get notified
			if(ret == true && times[TIME_MEASUREMENTS_KEYPRESSED_KEY]->measuring){
				stopMeasuring(TIME_MEASUREMENTS_KEYPRESSED_KEY, false); //if enabling the menu, we interrupt the following events,
																		//so we manually stop the timing as otherwise its never stopped
																		//bc the "after" kepressed event is never reached.
			}
		}
		return ret;
	}
	return false; //if TM is disabled, dont interrtup event chain
}
void ofxTimeMeasurements::_keyPressed(ofKeyEventArgs &e){

	if (e.key == enableKey){
		TIME_SAMPLE_SET_ENABLED(!TIME_SAMPLE_GET_ENABLED());
	}

	if (TIME_SAMPLE_GET_ENABLED()){
		if (e.key == activateKey){
			menuActive = !menuActive;
		}

		if(menuActive){

			if (drawLines.size()){
				int selIndex = -1;
				for(int i = 0; i < drawLines.size(); i++){
					if (drawLines[i].key == selection) selIndex = i;
				}
				if(selIndex == -1){
					return;
				}

				switch (e.key) {

					case OF_KEY_DOWN:{
						selIndex ++;
						if(selIndex >= drawLines.size()) selIndex = 0;
						while(drawLines[selIndex].tm == NULL){
							selIndex ++;
							if(selIndex >= drawLines.size()) selIndex = 0;
						}
						selection = drawLines[selIndex].key;
					}break;

					case OF_KEY_UP:{
						selIndex --;
						if(selIndex < 0 ) selIndex = drawLines.size() - 1;
						while(drawLines[selIndex].tm == NULL){
							selIndex --;
							if(selIndex < 0 ) selIndex = drawLines.size() - 1;
						}
						selection = drawLines[selIndex].key;
					}break;

					#if defined(USE_OFX_HISTORYPLOT)
					case 'P':{
						if (!plots[selection]){
							plots[selection] = makeNewPlot(selection);
							times[selection]->settings.plotting = true;
						}else{
							times[selection]->settings.plotting ^= true;
						}
					}break;
					#endif

					case OF_KEY_RETURN:{
							//cant disable update() & draw()
							if (selection != TIME_MEASUREMENTS_SETUP_KEY &&
								selection != TIME_MEASUREMENTS_UPDATE_KEY &&
								selection != TIME_MEASUREMENTS_DRAW_KEY &&
								drawLines[selIndex].tm
								){
									times[selection]->settings.enabled ^= true;
							}
						}break;

					case OF_KEY_RIGHT:
						collapseExpand(selection, false); //expand
					break;

					case OF_KEY_LEFT:
						collapseExpand(selection, true ); //collapse
						break;
				}
			}
		}
	}
}