void TuioClientApp::draw2( tuio::Cursor cursor, int sourcenum )
{	
	switch( sourcenum % 6 ) {
		case 0: gl::color(ColorA(1.0f, 0.0f, 0.0f, 0.6f)); break;
		case 1: gl::color(ColorA(0.0f, 1.0f, 0.0f, 0.6f)); break;
		case 2: gl::color(ColorA(0.0f, 0.0f, 1.0f, 0.6f)); break;
		case 3: gl::color(ColorA(1.0f, 1.0f, 0.0f, 0.6f)); break;
		case 4: gl::color(ColorA(0.0f, 1.0f, 1.0f, 0.6f)); break;
		case 5: gl::color(ColorA(1.0f, 0.0f, 1.0f, 0.6f)); break;
	}
	gl::drawSolidCircle( cursor.getPos() * vec2(getWindowSize()), 30 );
}
void SecondStudy::TheApp::cursorUpdated(tuio::Cursor cursor) {
	//console() << "Upd" << endl;
	go = true;
	_tracesMutex.lock();
	_traces[cursor.getSessionId()]->cursorMove(cursor);
	_tracesMutex.unlock();
    
    for(auto &g : _groups) {
        for(auto pgr : _progressiveGRs) {
            pgr->processGroup(g);
        }
    }
	
	stringstream ss;
	ss	<< "TheApp::cursorUpdated "
		<< "(x:" << cursor.getPos().x
		<< " y:" << cursor.getPos().y
		<< " session_id:" << cursor.getSessionId()
		<< " widget_id:" << _traces[cursor.getSessionId()]->widgetId
		<< ")";
	Logger::instance().log(ss.str());
}
void SecondStudy::TheApp::cursorAdded(tuio::Cursor cursor) {
	//console() << "Add" << endl;
	bool continued = false;
	int joined = -1;
	_tracesMutex.lock();
	for(auto t : _traces) {
		auto trace = t.second;
		if(!trace->isVisible && !trace->isDead() && tuioToWindow(trace->currentPosition()).distance(tuioToWindow(cursor.getPos())) <= 50.0f) {
			_traces[cursor.getSessionId()] = _traces[trace->getSessionId()];
			joined = trace->getSessionId(); // the old session id (therefore the old trace that has been resurrected)
			_traces[cursor.getSessionId()]->resurrect();
			_traces[cursor.getSessionId()]->cursorMove(cursor);
			continued = true;
			break;
		}
	}

	if(continued) {
		if(joined > 0) {
			_traces.erase(joined);
		}
	} else {
		// This is a brand new trace, we have to do stuff!
		_traces[cursor.getSessionId()] = make_shared<TouchTrace>();
		_traces[cursor.getSessionId()]->addCursorDown(cursor);

		// Check if it's on a widget
		_widgetsMutex.lock();
		// This is done in reverse order because I say so.
		for(auto it = _widgets.rbegin(); it != _widgets.rend(); ++it) {
			auto w = *it;
			if(w->hit(tuioToWindow(cursor.getPos()))) {
				_traces[cursor.getSessionId()]->widgetId = w->id();
				break;
			}
		}
		_widgetsMutex.unlock();

		_groupsMutex.lock();
		int g = findGroupForTrace(_traces[cursor.getSessionId()]);
		if(g == -1) {
			list<shared_ptr<TouchTrace>> l;
			l.push_back(_traces[cursor.getSessionId()]);
			_groups.push_back(l);
		} else {
			_groups[g].push_back(_traces[cursor.getSessionId()]);
		}
		_groupsMutex.unlock();
	}
	_tracesMutex.unlock();
	
    for(auto &g : _groups) {
        for(auto pgr : _progressiveGRs) {
            pgr->processGroup(g);
        }
    }
	
	stringstream ss;
	ss	<< "TheApp::cursorAdded "
		<< "(x:" << cursor.getPos().x
		<< " y:" << cursor.getPos().y
		<< " session_id:" << cursor.getSessionId()
		<< " widget_id:" << _traces[cursor.getSessionId()]->widgetId
		<< " new_trace:" << (continued ? "n" : "y")
		<< " joined_trace:" << joined
		<< ")";
	Logger::instance().log(ss.str());
}
void TuioClientApp::cursorRemoved( tuio::Cursor cursor ) {
	console() << "Cursor removed " << cursor.getSessionId() << std::endl;
}
void TuioClientApp::draw2b( tuio::Cursor cursor )
{
	gl::color( Color::white() );
	gl::drawSolidCircle( cursor.getPos() * vec2(getWindowSize()), 5.0f );
}