changeset 8:d59de9fd3496

Refactored messageController, ready for instroduction of other stages and tests.
author Robert Tubb <rt300@eecs.qmul.ac.uk>
date Fri, 17 Oct 2014 16:35:22 +0100
parents 4e00f92567d9
children d5e928887f51
files MessageOrganiser.h SearchMessageOrganiser.h SearchMessageOrganiser.mm SequenceController.h SequenceController.mm TrainingMessageOrganiser.h TrainingMessageOrganiser.mm testApp.h testApp.mm
diffstat 9 files changed, 746 insertions(+), 647 deletions(-) [+]
line wrap: on
line diff
--- a/MessageOrganiser.h	Fri Oct 17 15:13:35 2014 +0100
+++ b/MessageOrganiser.h	Fri Oct 17 16:35:22 2014 +0100
@@ -19,8 +19,6 @@
 #include <Buttron.h>
 #include <ButtronSlider.h>
 #include <ButtronXY.h>
-#include "AppCore.h"
-#include "ofxPd.h"
 #include "TestController.h"
 #include "timeController.h"
 #include "PDSynthWrapper.h"
@@ -60,327 +58,35 @@
 typedef boost::function<void(void)> AppModeChangeFunction;
 
 class MessageOrganiser {
-private:
-    AppCore* core;
-    //testApp* theOFApp;
+    
+public:
+    void init(PDSynthWrapper& cs, PDSynthWrapper& ts){
+        candidateSynth = cs;
+        targetSynth = ts;
+    }
+    // could template for ui element type??
+    void mapButtonToAction(UIElement* control, int mappingID){
+        UICallbackFunction callbackF;
+        callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2);
+        control->addHandler(callbackF, mappingID);
+        currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
+    }
+protected:
+
+    PDSynthWrapper candidateSynth;
     PDSynthWrapper targetSynth;
-    PDSynthWrapper candidateSynth;
+    
 
     map<int,UIElement*> currentMapping; // could get more sophisticated if not 1-1 ?
     
     SliderPanel* panel;
-    TimeController altPlaybackController;
     
-    TestController* testController;
-    Buttron* newTestButton;
-    //Buttron* submitButton;
-    
-    ButtonPanel* bottomPanel; // shows during test : play buttons and submit
-    Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand
-    CountdownText* countdownPanel;
-    TargetSymbol* targetSymbol;
-    Leap3DBoxGL* box3D;
-    TextPanel* scorePanel;
-    TextPanel* finishPanel;
-    AppModeChangeFunction testAppModeChange;
-    
-    //int scoreRunningTotal;
-    TimerID currentSoundPlayTimer;
-    
-    int alternationSpeed; // ms between cand and target
-    bool playingAlternating;
-    
-    bool okToGetLeapMidi;
 
-    void testsFinished(){
-        panel->hide();
-        bottomPanel->hide();
-        newTestButton->hide();
-        
-        vector<int> eData;
-        eData.push_back(testController->getScoreRunningTotal());
-        eventLogger.logEvent(ALL_TESTS_COMPLETED, eData);
-        
-        // TODO set final score screen txt to testController->getScoreRunningTotal()
-        finishPanel->show();
-        
-        string user = eventLogger.getUsername();
-        stringstream s;
-        s << "Experiment completed"
-            << endl << endl
-            << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl
-            << "to retake test please close " << endl << endl
-             <<   "the app and restart with username<num test>";
-        finishPanel->setText(s.str());
-        // get test app to do something...
-        
-        eventLogger.saveSessionToFile();
-    };
-    
-    void setupNewTest(){
-        // get mapping for new test and make sure we have right controls and stuff
-
-        
-        Test newTest = testController->goToNextTest();
-        
-        // V0.2 put details about what kind of test it is
-        vector<int> eData;
-        eData.push_back(newTest.isPractice());
-        eData.push_back(newTest.isWithHint());
-        eData.push_back(newTest.isMemoryTest());
-        eventLogger.logEvent(NEW_TEST, eData);
-        
-        
-        vector<int> mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest);
-        
-        vector<UIElement*> UIElemHandles = panel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType());
-        
-        mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams);
-        
-        countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning());
-        
-
-    };
-    void startNewTest(){
-        Test t = testController->getCurrentTest();
-        
-        countdownPanel->hide();
-        panel->show();
-        panel->setActive(true);
-        if(t.isWithHint()){
-            panel->showHint(true);
-        }
-        
-        bottomPanel->show();
-        targetPlayButton->show(); // incase it was memory test
-        if (t.isMemoryTest()){
-            targetPlayButton->setLabel("Memorise!");
-        }else{
-            targetPlayButton->setLabel("Target");
-        }
-        //startAlternatingPlayback();
-        //timeController.scheduleEvent(boost::bind(&MessageOrganiser::sendSynthValuesAgain, this), 200);
-        timeController.startStopwatch();
-        eventLogger.logEvent(TEST_TIMER_STARTED);
-        
-        
-        if(t.getListOfControlTypes()[0] == LEAP3D){
-            okToGetLeapMidi = true;
-        }
-    };
-    
-    vector<int> setSynthsUpForNewTest(Test newTest){
-        targetSynth.setAllParams(newTest.getTargetValues());
-        eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams
-        
-        candidateSynth.setAllParams(newTest.getStartingCandidateValues());
-        eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues());
-        
-        // eventLogger.logEvent(NEW_TARGET_PARAMS, vector<int> );
-        // eventLogger.logEvent(NEW_CANDIDATE_PARAMS, vector<int> );
-        
-        vector<int> mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices());
-        
-        eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices());
-        eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids);
-        
-        return mids;
-    };
     void sendSynthValuesAgain(){
         candidateSynth.sendAllParams();
         targetSynth.sendAllParams();
     };
-    
-    // could have been cleverer. takes forever due to searching ???
-    void mapUIToNewTestParams(vector<UIElement*> elems, vector<int> mids){
-        
-        vector<UIElement*>::iterator elit;
-        vector<int> typeListLog;
-        int i = 0;
-        for(elit=elems.begin(); elit<elems.end();elit++){
-            if ( (*elit)->getType() == XYPAD){
-                if(i+1 >= mids.size()){
-                    cout << "ERROR ERROR: too many controls for mapping IDs" << endl;
-                }
-                
-                ButtronXY* theXY = (ButtronXY*)(*elit);
-                mapXYToParams(theXY, mids[i], mids[i+1]);
-                theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
-                theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))
-                                    ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1])));
-                i+=2;
-                typeListLog.push_back(int(XYPAD));
-            }else if ( (*elit)->getType() == SLIDER){
-                if(i >= mids.size()){
-                    
-                    cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl;
-                }
-                
-                ButtronSlider* theSlider = (ButtronSlider*)(*elit);
-                mapControlToParam((*elit), mids[i]);
-                theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i]));
-                cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl;
-                theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])));
-                i++;
-                typeListLog.push_back(int(SLIDER));
-            }else if ( (*elit)->getType() == LEAP3D ){
-                set3Dbox((Leap3DBoxGL*)(*elit));
-                // UH
-                string nameX = candidateSynth.getNameForMappingID(mids[i]);
-                box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX));
-                box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i]));
-                i++;
-                
-                string nameY = candidateSynth.getNameForMappingID(mids[i]);
-                box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY));
-                box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i]));
-                i++;
-                
-                string nameZ = candidateSynth.getNameForMappingID(mids[i]);
-                box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ));
-                box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i]));
-                i++;
-                
-
-                box3D->setLabels(nameX,nameY,nameZ);
-                typeListLog.push_back(int(LEAP3D));
-                
-            }else{
-                cout << "ERROR ERROR: ui type not handled my mapping function !" << endl;
-            }
-        }
-        
-        eventLogger.logEvent(CONTROL_LIST,typeListLog);
-    };
-    
-    // TODO - no, triggering playback needs to be logged
-    void startAlternatingPlayback(){
-        
-        cout << "start alt playback" << endl;
-        // use our special timer to fire off play to pd
-        // sets off timed alternating playback
-        
-        playAlternating();
-        playingAlternating = true;
-
-    };
-    void stopAlternatingPlayback(){
-        cout << "stop alt playback" << endl;
-        // kill the alternation
-        timeController.cancelEvent(currentSoundPlayTimer);
-        playingAlternating = false;
-    };
-    
-    void playAlternating(){
-        
-        static bool alt;
-        int nextTime;
-        if (alt){
-            targetSynth.trigger();
-            // flash the target thingy
-            targetSymbol->flash();
-            nextTime = alternationSpeed*1.503; // gap after target
-        }else{
-            sendSynthValuesAgain(); // and again and again
-            candidateSynth.trigger();
-            panel->flash();
-            nextTime = alternationSpeed;
-        }
-        alt = !alt;
-        candidateSynth.setNoteLength(alternationSpeed);
-        targetSynth.setNoteLength(alternationSpeed); // could be user alterable
-        currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&MessageOrganiser::playAlternating,this), nextTime);
-        
-        
-        
-    };
-    
-    void delayedShowNewTest(){
-        newTestButton->show();
-        // JUST IN CASE IT CRASHES near end...
-        //eventLogger.saveSessionToFile();
-    };
-    void submitSingleControl(){
-        // if last one
-        // submitPressed()
-        
-        // else
-        
-        // grey out that slider,
-        // activate next slider and show it's button (same button but moved!???)
-        
-    };
-    
-    
-    void submitPressed(){
-        
-        // depending on mode go to next control
-        //        if(testController->getCurrentPanelType() == SEQUENTIAL){
-        //            submitSingleControl();
-        //            return;
-        //        }
-        // otherwise do this other  - or call
-        
-        okToGetLeapMidi = false;
-        
-        TimerMillisec timeTaken = timeController.stopStopwatch();
-        vector<int> answer = candidateSynth.getAllParamValues();
-        
-        eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?));
-        
-        TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results
-        
-        vector<int> logResult;
-        logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??!
-        logResult.push_back(result.timeTaken); // milliseconds
-        logResult.push_back(result.score);
-        logResult.push_back(result.targetBandHit);
-        logResult.push_back(result.timeWindowHit);
-        
-        eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult);
-        
-        
-        // gui stuff - different controller?
-        panel->setActive(false);
-        panel->showHint(true); // add some encouraging feedback to hint
-        bottomPanel->hide();
-        
-        showScoreForTest(result);
-        
-        stopAlternatingPlayback();
-        
-        // was it the final sumbit?
-        if(testController->isLastTest()){
-            // thats it - show a final score screen etc
-            timeController.scheduleEvent(boost::bind(&MessageOrganiser::testsFinished, this), 500);
-            return;
-        }else{
-            timeController.scheduleEvent(boost::bind(&MessageOrganiser::delayedShowNewTest, this), 300);
-        }
-        
-
-    };
-    
-    void showScoreForTest(TestResult result){
-        scorePanel->setText(result.displayText);
-        scorePanel->show();
-        
-        ofColor c;
-        if(result.targetBandHit == 1){
-            // yellow red blue
-            c = ofColor(255,255,0,255);
-        }else if(result.targetBandHit == 2){
-            c = ofColor(255,0,0,255);
-        }else if(result.targetBandHit == 3){
-            c = ofColor(45,45,255,255);
-        }else if(result.targetBandHit == 4){
-            c = ofColor(0,255,0,255);
-        }else{
-            c = ofColor(150,235,200,255);
-        }
-        scorePanel->setColor(c);
-        panel->setHintColor(c);
-    };
+ 
     
     void setAllSlidersToValues(vector<int> values){
         for(int i = 0; i < values.size(); i++){
@@ -435,28 +141,7 @@
         control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY));
         
     };
-    
-    void mapLeapToParams(ButtronXY* control, int mappingIDX, int mappingIDY, int mappingIDZ){
-//        UICallbackFunction callbackX;
-//        UICallbackFunction callbackY;
-//        UICallbackFunction callbackZ;
-//        
-//        callbackX = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
-//        callbackY = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
-//        callbackZ = boost::bind(&MessageOrganiser::paramChangeCallback, this, _1,_2);
-//        
-//        control->addHandler(callbackX, mappingIDX);
-//        control->addHandler(callbackY, mappingIDY);
-//        
-//        // put in our map so we can send param values to gui
-//        //currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
-//        
-//        
-//        cout << " Mapped control to XID: " << mappingIDX << "Name: " << candidateSynth.getNameForMappingID(mappingIDX) << endl;
-//        cout << " Mapped control to YID: " << mappingIDY << "Name: " << candidateSynth.getNameForMappingID(mappingIDY) << endl;
-//        control->setLabel(candidateSynth.getNameForMappingID(mappingIDX), candidateSynth.getNameForMappingID(mappingIDY));
-        
-    };
+
     
     void mapControlToParam(UIElement* control, string paramName){
         // get mapping ID from synth
@@ -464,276 +149,13 @@
         mapControlToParam(control, mappingID);
         control->setLabel(paramName);
     };
-public:
-    void init(AppCore* aCore, TestController* tc){
-        // set PD core...
 
-        core = aCore;
-        targetSynth.init(aCore,"targetSynth");
-        candidateSynth.init(aCore,"candidateSynth");
-        
-        testController = tc;
-        currentSoundPlayTimer = -1;
-        okToGetLeapMidi = false;
-        
-        alternationSpeed = 200;
-        
-        candidateSynth.setNoteLength(alternationSpeed);
-        targetSynth.setNoteLength(alternationSpeed); 
-        
-        playingAlternating = false;
+    virtual void paramChangeCallback(int mappingID, int value){
+        // virtual?
     };
-    void setNewTestButton(Buttron * ntb){
-        newTestButton = ntb;
-    };
-    void set3Dbox(Leap3DBoxGL* box){
-        box3D = box;
-    };
-    void setBottomPanel(ButtonPanel * ntb){
-        bottomPanel = ntb;
-    };
-    void setControlPanel(SliderPanel* p){
-        panel = p;
+    virtual void buttonPressCallback(int mappingID, int value){
         
     };
-    void setCountdownPanel(CountdownText* cd){
-        countdownPanel = cd;
-    };
-    void setTargetSymbol(TargetSymbol* ts){
-        targetSymbol = ts;
-    };
-    void setScorePanel(TextPanel* tp){
-        scorePanel = tp;
-    };
-    void setFinishPanel(TextPanel* fp){
-        finishPanel = fp;
-    }
-    void setTargetButton(Buttron* tb){
-        targetPlayButton = tb;
-    }
-    int getScore(){
-        return testController->getScoreRunningTotal();
-    };
-    
-    pair<int,int> getTime(){
-        TimerMillisec tms = timeController.getStopwatchElapsedTime();
-        int s = int(tms/1000);
-        int hs = int((tms%1000)/10);
-        pair<int,int> p(s,hs);
-        return p;
-    };
-    void countdownToNewTest(){
-        
-        panel->hide();
-        panel->setActive(false);
-        scorePanel->hide();
-        bottomPanel->hide();
-        newTestButton->hide();
-        
-        // set up stuff
-        setupNewTest();
-        eventLogger.logEvent(COUNTDOWN_INITIATED);
-        
-        countdownPanel->showAndStart(3);
-
-        timeController.scheduleEvent(boost::bind(&MessageOrganiser::startNewTest, this), 3000);
-
-    };
-    void sendToGUI(vector<int> paramsToMap){
-        // look up these ids in mapping table
-    };
-    void saveGoodTest(Test t){
-        
-    };
-    void playTargetButtonPressed(){
-
-        static int numPlays = 3;
-        
-        Test* t = testController->getCurrentTestPtr();
-        if (!t->checkTargetPlaysRemaining()){
-                cout << t->getTargetPlaysLeft() << endl;
-            
-                sendSynthValuesAgain();
-                targetSynth.trigger();
-                eventLogger.logEvent(TARGET_PLAYED);
-                targetPlayButton->hide();
-                return;
-
-        }
-        cout << t->getTargetPlaysLeft() << endl;
-        
-        sendSynthValuesAgain();
-        targetSynth.trigger();
-        eventLogger.logEvent(TARGET_PLAYED);
-        
-        return;
-    }
-    void playCandidateButtonPressed(){
-        //
-    }
-    void buttonPressCallback(int mappingID, int value){
-        if(mappingID == VOLUME_CHANGE_ID){
-            targetSynth.sendVolume(value);
-            candidateSynth.sendVolume(value);
-            
-        }
-        if(mappingID == SPEED_CHANGE_ID){
-            alternationSpeed = 2*(140 - value);
-            vector<int> eData;
-            eData.push_back(alternationSpeed);
-            eventLogger.logEvent(SPEED_CHANGED, eData);
-        }
-        if(mappingID == NEW_TEST_ID){
-            countdownToNewTest();
-            return;
-        }
-        if (mappingID == START_ALTERNATE_ID){
-            if(!playingAlternating){
-                startAlternatingPlayback();
-                
-            }else{
-                stopAlternatingPlayback();
-            }
-            return;
-        }
-        if(mappingID == GOOD_TEST_ID){
-            Test t = testController->getCurrentTest();
-            saveGoodTest(t);
-        }
-        if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr
-            targetSynth.randomiseParams();
-            return;
-        }
-        if (mappingID == TRIGGER_TARGET_ID){
-            playTargetButtonPressed();
-            
-        }
-        if (mappingID == TRIGGER_CANDIDATE_ID){
-            // log event
-            sendSynthValuesAgain();
-            candidateSynth.trigger();
-            eventLogger.logEvent(CANDIDATE_PLAYED);
-            // flash panel?
-            panel->flash();
-            return;
-        }
-        if (mappingID == SUBMIT_CANDIDATE){
-            // log event
-            submitPressed();
-            
-            return;
-        }
-        if (mappingID == CRAP_TEST_ID){
-            // this is rubbish! send a log of target values, and mapping ids
-            vector<int> data;
-            vector<int> tvals = targetSynth.getAllParamValues();
-            vector<int> pidx = testController->getCurrentChangeableParams();
-            data.insert(data.end(), tvals.begin(), tvals.end());
-            data.insert(data.end(), pidx.begin(), pidx.end());
-
-            eventLogger.logEvent(CRAP_TEST, data);
-        }
-        if(mappingID == SHOW_HIDE_PANEL){
-            static bool showing;
-            
-            if(showing){
-                cout << " showing"<<endl;
-                
-                panel->show();
-                
-            }else{
-                cout << " hiding"<<endl;
-                panel->hide();
-            }
-            showing = !showing;
-        }
-        if(mappingID == SHOW_HIDE_HINT){
-            static bool showingHint;
-            if(showingHint){
-                panel->showHint(false);
-                showingHint = false;
-            }else{
-                panel->showHint(true);
-                showingHint = true;
-            }
-        }
-        if(mappingID == SAVE_PRESET_HIT){
-            expPresetManager.savePreset("blah", candidateSynth.getAllParamValues());
-            
-        }
-        if(mappingID == RECALL_PRESET_HIT){
-            
-            loadPreset("blah");
-            //candidateSynth.startMetronome();
-            
-        }
-    }
-    void loadPreset(string pname){
-        
-        vector<int> values = expPresetManager.recallPreset(pname);
-        if (values.size()){
-        candidateSynth.setAllParams(values);
-        setAllSlidersToValues(values);
-        }else{
-            cout << "ERROR, no preset found" << endl;
-        }
-    }
-    // called from UI
-    void paramChangeCallback(int mappingID, int value){
-        candidateSynth.paramChangeCallback(mappingID, value);
-        vector<int> evtData;
-        evtData.push_back(mappingID); // or just index?
-        evtData.push_back(value);
-        
-        eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
-    };
-
-    // could template for ui element type??
-    void mapButtonToAction(UIElement* control, int mappingID){
-        UICallbackFunction callbackF;
-        callbackF = boost::bind(&MessageOrganiser::buttonPressCallback, this, _1,_2);
-        control->addHandler(callbackF, mappingID);
-        currentMapping.insert(std::pair<int,UIElement*>(mappingID,control));
-    }
-
-    
-    void midiFromLeap(int ctl_num, int ctl_val){
-        
-  
-        if (!okToGetLeapMidi){
-            return;
-        }
-
-
-        Test *theTest = testController->getCurrentTestPtr();
-        if (theTest == NULL) return;
-        
-    
-
-        
-        
-        vector<int> ci = theTest->getChangeableIndices();
-        vector<int> mids = candidateSynth.getMappingIDForIndices(ci);
-        if (ctl_num >= mids.size() || ctl_num < 0) return;
-        
-        candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val);
-        
-        setUIToParam(ctl_num, ctl_val);
-        
-        vector<int> evtData;
-        evtData.push_back(mids[ctl_num]); // or just index?
-        evtData.push_back(ctl_val);
-        
-        eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
-        // also call UI object
-        // get mapping ID for
-        // setUIToParam(ctl_num, ctl_val);
-    }
-//    void setSlidersFromLeap(int i, int val){
-//        ButtronSlider* theSlider = (ButtronSlider*)panel->getSlider(i);
-//        theSlider->setValueAndScale(val);
-//    }
-    
 
     
     void setSlidersToTarget(){
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SearchMessageOrganiser.h	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,612 @@
+//
+//  SearchMessageOrganiser.h
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#ifndef __riftathon__SearchMessageOrganiser__
+#define __riftathon__SearchMessageOrganiser__
+
+#include <iostream>
+#include "MessageOrganiser.h"
+
+class SearchMessageOrganiser : public MessageOrganiser {
+
+public:
+    
+
+
+protected:
+    
+    
+    TimeController altPlaybackController;
+    
+    TestController* testController;
+    Buttron* newTestButton;
+    //Buttron* submitButton;
+    
+    ButtonPanel* bottomPanel; // shows during test : play buttons and submit
+    Buttron* targetPlayButton; // so we can hide target in memory test. this pointer stuff is getting out of hand
+    CountdownText* countdownPanel;
+    TargetSymbol* targetSymbol;
+    Leap3DBoxGL* box3D;
+    TextPanel* scorePanel;
+    TextPanel* finishPanel;
+    AppModeChangeFunction testAppModeChange;
+    
+    //int scoreRunningTotal;
+    TimerID currentSoundPlayTimer;
+    
+    int alternationSpeed; // ms between cand and target
+    bool playingAlternating;
+    
+    bool okToGetLeapMidi;
+    
+    
+// protected methods
+    void testsFinished(){
+        panel->hide();
+        bottomPanel->hide();
+        newTestButton->hide();
+        
+        vector<int> eData;
+        eData.push_back(testController->getScoreRunningTotal());
+        eventLogger.logEvent(ALL_TESTS_COMPLETED, eData);
+        
+        // TODO set final score screen txt to testController->getScoreRunningTotal()
+        finishPanel->show();
+        
+        string user = eventLogger.getUsername();
+        stringstream s;
+        s << "Experiment completed"
+        << endl << endl
+        << "You scored: " << testController->getScoreRunningTotal() << " well done " << user << endl << endl
+        << "to retake test please close " << endl << endl
+        <<   "the app and restart with username<num test>";
+        finishPanel->setText(s.str());
+        // get test app to do something...
+        
+        eventLogger.saveSessionToFile();
+    };
+    
+    void setupNewTest(){
+        // get mapping for new test and make sure we have right controls and stuff
+        
+        
+        Test newTest = testController->goToNextTest();
+        
+        // V0.2 put details about what kind of test it is
+        vector<int> eData;
+        eData.push_back(newTest.isPractice());
+        eData.push_back(newTest.isWithHint());
+        eData.push_back(newTest.isMemoryTest());
+        eventLogger.logEvent(NEW_TEST, eData);
+        
+        
+        vector<int> mappingIDsForChangeableParams = setSynthsUpForNewTest(newTest);
+        
+        vector<UIElement*> UIElemHandles = panel->generateControls(testController->getCurrentListOfControls(), testController->getCurrentPanelType());
+        
+        mapUIToNewTestParams(UIElemHandles, mappingIDsForChangeableParams);
+        
+        countdownPanel->setTestTypeString(newTest.getTestTypeAdvanceWarning());
+        
+        
+    };
+    void startNewTest(){
+        Test t = testController->getCurrentTest();
+        
+        countdownPanel->hide();
+        panel->show();
+        panel->setActive(true);
+        if(t.isWithHint()){
+            panel->showHint(true);
+        }
+        
+        bottomPanel->show();
+        targetPlayButton->show(); // incase it was memory test
+        if (t.isMemoryTest()){
+            targetPlayButton->setLabel("Memorise!");
+        }else{
+            targetPlayButton->setLabel("Target");
+        }
+        //startAlternatingPlayback();
+        //timeController.scheduleEvent(boost::bind(&MessageOrganiser::sendSynthValuesAgain, this), 200);
+        timeController.startStopwatch();
+        eventLogger.logEvent(TEST_TIMER_STARTED);
+        
+        
+        if(t.getListOfControlTypes()[0] == LEAP3D){
+            okToGetLeapMidi = true;
+        }
+    };
+    
+    vector<int> setSynthsUpForNewTest(Test newTest){
+        targetSynth.setAllParams(newTest.getTargetValues());
+        eventLogger.logEvent(TARGET_PARAM_SET, newTest.getTargetValues()); // unless something goes wrong in setAllParams
+        
+        candidateSynth.setAllParams(newTest.getStartingCandidateValues());
+        eventLogger.logEvent(CANDIDATE_PARAM_SET,newTest.getStartingCandidateValues());
+        
+        // eventLogger.logEvent(NEW_TARGET_PARAMS, vector<int> );
+        // eventLogger.logEvent(NEW_CANDIDATE_PARAMS, vector<int> );
+        
+        vector<int> mids = candidateSynth.getMappingIDForIndices(newTest.getChangeableIndices());
+        
+        eventLogger.logEvent(CANDIDATE_CHANGEABLE_IDX, newTest.getChangeableIndices());
+        eventLogger.logEvent(CANDIDATE_MAPPING_IDS, mids);
+        
+        return mids;
+    };
+    
+    
+    // could have been cleverer. takes forever due to searching ???
+    void mapUIToNewTestParams(vector<UIElement*> elems, vector<int> mids){
+        
+        vector<UIElement*>::iterator elit;
+        vector<int> typeListLog;
+        int i = 0;
+        for(elit=elems.begin(); elit<elems.end();elit++){
+            if ( (*elit)->getType() == XYPAD){
+                if(i+1 >= mids.size()){
+                    cout << "ERROR ERROR: too many controls for mapping IDs" << endl;
+                }
+                
+                ButtronXY* theXY = (ButtronXY*)(*elit);
+                mapXYToParams(theXY, mids[i], mids[i+1]);
+                theXY->setValueAndScale(candidateSynth.getParamValueForID(mids[i]), candidateSynth.getParamValueForID(mids[i+1]));
+                theXY->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i]))
+                                    ,targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i+1])));
+                i+=2;
+                typeListLog.push_back(int(XYPAD));
+            }else if ( (*elit)->getType() == SLIDER){
+                if(i >= mids.size()){
+                    
+                    cout << "ERROR ERROR: too many controls for mapping IDs: " << mids.size() << endl;
+                }
+                
+                ButtronSlider* theSlider = (ButtronSlider*)(*elit);
+                mapControlToParam((*elit), mids[i]);
+                theSlider->setValueAndScale(candidateSynth.getParamValueForID(mids[i]));
+                cout << "Hint Value " << targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])) << endl;
+                theSlider->setHintValue(targetSynth.getParamValueFromName(candidateSynth.getNameForMappingID(mids[i])));
+                i++;
+                typeListLog.push_back(int(SLIDER));
+            }else if ( (*elit)->getType() == LEAP3D ){
+                set3Dbox((Leap3DBoxGL*)(*elit));
+                // UH
+                string nameX = candidateSynth.getNameForMappingID(mids[i]);
+                box3D->setHintValue(0,targetSynth.getParamValueFromName(nameX));
+                box3D->setValueAndScale(0, candidateSynth.getParamValueForID(mids[i]));
+                i++;
+                
+                string nameY = candidateSynth.getNameForMappingID(mids[i]);
+                box3D->setHintValue(1,targetSynth.getParamValueFromName(nameY));
+                box3D->setValueAndScale(1, candidateSynth.getParamValueForID(mids[i]));
+                i++;
+                
+                string nameZ = candidateSynth.getNameForMappingID(mids[i]);
+                box3D->setHintValue(2,targetSynth.getParamValueFromName(nameZ));
+                box3D->setValueAndScale(2, candidateSynth.getParamValueForID(mids[i]));
+                i++;
+                
+                
+                box3D->setLabels(nameX,nameY,nameZ);
+                typeListLog.push_back(int(LEAP3D));
+                
+            }else{
+                cout << "ERROR ERROR: ui type not handled my mapping function !" << endl;
+            }
+        }
+        
+        eventLogger.logEvent(CONTROL_LIST,typeListLog);
+    };
+    
+    // TODO - no, triggering playback needs to be logged
+    void startAlternatingPlayback(){
+        
+        cout << "start alt playback" << endl;
+        // use our special timer to fire off play to pd
+        // sets off timed alternating playback
+        
+        playAlternating();
+        playingAlternating = true;
+        
+    };
+    void stopAlternatingPlayback(){
+        cout << "stop alt playback" << endl;
+        // kill the alternation
+        timeController.cancelEvent(currentSoundPlayTimer);
+        playingAlternating = false;
+    };
+    
+    void playAlternating(){
+        
+        static bool alt;
+        int nextTime;
+        if (alt){
+            targetSynth.trigger();
+            // flash the target thingy
+            targetSymbol->flash();
+            nextTime = alternationSpeed*1.503; // gap after target
+        }else{
+            sendSynthValuesAgain(); // and again and again
+            candidateSynth.trigger();
+            panel->flash();
+            nextTime = alternationSpeed;
+        }
+        alt = !alt;
+        candidateSynth.setNoteLength(alternationSpeed);
+        targetSynth.setNoteLength(alternationSpeed); // could be user alterable
+        currentSoundPlayTimer = timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::playAlternating,this), nextTime);
+        
+        
+        
+    };
+    
+    void delayedShowNewTest(){
+        newTestButton->show();
+        // JUST IN CASE IT CRASHES near end...
+        //eventLogger.saveSessionToFile();
+    };
+    void submitSingleControl(){
+        // if last one
+        // submitPressed()
+        
+        // else
+        
+        // grey out that slider,
+        // activate next slider and show it's button (same button but moved!???)
+        
+    };
+    
+    
+    void submitPressed(){
+        
+        // depending on mode go to next control
+        //        if(testController->getCurrentPanelType() == SEQUENTIAL){
+        //            submitSingleControl();
+        //            return;
+        //        }
+        // otherwise do this other  - or call
+        
+        okToGetLeapMidi = false;
+        
+        TimerMillisec timeTaken = timeController.stopStopwatch();
+        vector<int> answer = candidateSynth.getAllParamValues();
+        
+        eventLogger.logEvent(SUBMIT_PRESSED, answer); //, answer, scoreRunningTotal, time taken (why not?));
+        
+        TestResult result = testController->submitAnswer(answer, timeTaken); // TODO returns all the results
+        
+        vector<int> logResult;
+        logResult.push_back(result.realDistanceToTarget*1000); // measured in milliCC !??!
+        logResult.push_back(result.timeTaken); // milliseconds
+        logResult.push_back(result.score);
+        logResult.push_back(result.targetBandHit);
+        logResult.push_back(result.timeWindowHit);
+        
+        eventLogger.logEvent(DISTANCE_TIME_SCORE, logResult);
+        
+        
+        // gui stuff - different controller?
+        panel->setActive(false);
+        panel->showHint(true); // add some encouraging feedback to hint
+        bottomPanel->hide();
+        
+        showScoreForTest(result);
+        
+        stopAlternatingPlayback();
+        
+        // was it the final sumbit?
+        if(testController->isLastTest()){
+            // thats it - show a final score screen etc
+            timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::testsFinished, this), 500);
+            return;
+        }else{
+            timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::delayedShowNewTest, this), 300);
+        }
+        
+        
+    };
+    
+    void showScoreForTest(TestResult result){
+        scorePanel->setText(result.displayText);
+        scorePanel->show();
+        
+        ofColor c;
+        if(result.targetBandHit == 1){
+            // yellow red blue
+            c = ofColor(255,255,0,255);
+        }else if(result.targetBandHit == 2){
+            c = ofColor(255,0,0,255);
+        }else if(result.targetBandHit == 3){
+            c = ofColor(45,45,255,255);
+        }else if(result.targetBandHit == 4){
+            c = ofColor(0,255,0,255);
+        }else{
+            c = ofColor(150,235,200,255);
+        }
+        scorePanel->setColor(c);
+        panel->setHintColor(c);
+    };
+    
+public:
+    void init( PDSynthWrapper& cs, PDSynthWrapper& ts){
+        
+        testController = new TestController;
+        
+        MessageOrganiser::init(cs,ts);
+
+        currentSoundPlayTimer = -1;
+        okToGetLeapMidi = false;
+        
+        alternationSpeed = 200;
+        
+        candidateSynth.setNoteLength(alternationSpeed);
+        targetSynth.setNoteLength(alternationSpeed);
+        
+        playingAlternating = false;
+        
+        
+        verdBig.loadFont("verdana.ttf", 18, true, true);
+        verdBig.setLineHeight(18.0f);
+        verdBig.setLetterSpacing(1.037);
+    };
+    
+    //------------------------------------------------------------------------
+    void drawScore(){
+        ofColor txtCol = ofColor(150,235,200,255);
+        
+        int score = getScore();
+        stringstream msg;
+        
+        msg << "Test: " << testController->getCurrentTestLetter();
+        ofSetColor(txtCol);
+        verdBig.drawString(msg.str(), 40, 140);
+        msg.str(std::string());
+        
+        msg << "Score: " << score;
+        verdBig.drawString(msg.str(), 240, 140);
+        msg.str(std::string());
+        
+        pair<int,int> time;
+        time = getTime();
+        msg << "Time taken: " << time.first << ":" << time.second << endl;
+        verdBig.drawString(msg.str(), 600, 140);
+        
+    }
+    
+    void setNewTestButton(Buttron * ntb){
+        newTestButton = ntb;
+    };
+    void set3Dbox(Leap3DBoxGL* box){
+        box3D = box;
+    };
+    void setBottomPanel(ButtonPanel * ntb){
+        bottomPanel = ntb;
+    };
+    void setControlPanel(SliderPanel* p){
+        panel = p;
+        
+    };
+    void setCountdownPanel(CountdownText* cd){
+        countdownPanel = cd;
+    };
+    void setTargetSymbol(TargetSymbol* ts){
+        targetSymbol = ts;
+    };
+    void setScorePanel(TextPanel* tp){
+        scorePanel = tp;
+    };
+    void setFinishPanel(TextPanel* fp){
+        finishPanel = fp;
+    }
+    void setTargetButton(Buttron* tb){
+        targetPlayButton = tb;
+    }
+    int getScore(){
+        return testController->getScoreRunningTotal();
+    };
+    
+    pair<int,int> getTime(){
+        TimerMillisec tms = timeController.getStopwatchElapsedTime();
+        int s = int(tms/1000);
+        int hs = int((tms%1000)/10);
+        pair<int,int> p(s,hs);
+        return p;
+    };
+    void countdownToNewTest(){
+        
+        panel->hide();
+        panel->setActive(false);
+        scorePanel->hide();
+        bottomPanel->hide();
+        newTestButton->hide();
+        
+        // set up stuff
+        setupNewTest();
+        eventLogger.logEvent(COUNTDOWN_INITIATED);
+        
+        countdownPanel->showAndStart(3);
+        
+        timeController.scheduleEvent(boost::bind(&SearchMessageOrganiser::startNewTest, this), 3000);
+        
+    };
+
+    void playTargetButtonPressed(){
+        
+        static int numPlays = 3;
+        
+        Test* t = testController->getCurrentTestPtr();
+        if (!t->checkTargetPlaysRemaining()){
+            cout << t->getTargetPlaysLeft() << endl;
+            
+            sendSynthValuesAgain();
+            targetSynth.trigger();
+            eventLogger.logEvent(TARGET_PLAYED);
+            targetPlayButton->hide();
+            return;
+            
+        }
+        cout << t->getTargetPlaysLeft() << endl;
+        
+        sendSynthValuesAgain();
+        targetSynth.trigger();
+        eventLogger.logEvent(TARGET_PLAYED);
+        
+        return;
+    }
+    void playCandidateButtonPressed(){
+        //
+    }
+    void buttonPressCallback(int mappingID, int value){
+        if(mappingID == VOLUME_CHANGE_ID){
+            targetSynth.sendVolume(value);
+            candidateSynth.sendVolume(value);
+            
+        }
+        if(mappingID == SPEED_CHANGE_ID){
+            alternationSpeed = 2*(140 - value);
+            vector<int> eData;
+            eData.push_back(alternationSpeed);
+            eventLogger.logEvent(SPEED_CHANGED, eData);
+        }
+        if(mappingID == NEW_TEST_ID){
+            countdownToNewTest();
+            return;
+        }
+        if (mappingID == START_ALTERNATE_ID){
+            if(!playingAlternating){
+                startAlternatingPlayback();
+                
+            }else{
+                stopAlternatingPlayback();
+            }
+            return;
+        }
+
+        if (mappingID == RANDOMISE_TARGET_ID){ // bleyeueurrrr
+            targetSynth.randomiseParams();
+            return;
+        }
+        if (mappingID == TRIGGER_TARGET_ID){
+            playTargetButtonPressed();
+            
+        }
+        if (mappingID == TRIGGER_CANDIDATE_ID){
+            // log event
+            sendSynthValuesAgain();
+            candidateSynth.trigger();
+            eventLogger.logEvent(CANDIDATE_PLAYED);
+            // flash panel?
+            panel->flash();
+            return;
+        }
+        if (mappingID == SUBMIT_CANDIDATE){
+            // log event
+            submitPressed();
+            
+            return;
+        }
+        if (mappingID == CRAP_TEST_ID){
+            // this is rubbish! send a log of target values, and mapping ids
+            vector<int> data;
+            vector<int> tvals = targetSynth.getAllParamValues();
+            vector<int> pidx = testController->getCurrentChangeableParams();
+            data.insert(data.end(), tvals.begin(), tvals.end());
+            data.insert(data.end(), pidx.begin(), pidx.end());
+            
+            eventLogger.logEvent(CRAP_TEST, data);
+        }
+        if(mappingID == SHOW_HIDE_PANEL){
+            static bool showing;
+            
+            if(showing){
+                cout << " showing"<<endl;
+                
+                panel->show();
+                
+            }else{
+                cout << " hiding"<<endl;
+                panel->hide();
+            }
+            showing = !showing;
+        }
+        if(mappingID == SHOW_HIDE_HINT){
+            static bool showingHint;
+            if(showingHint){
+                panel->showHint(false);
+                showingHint = false;
+            }else{
+                panel->showHint(true);
+                showingHint = true;
+            }
+        }
+        if(mappingID == SAVE_PRESET_HIT){
+            expPresetManager.savePreset("blah", candidateSynth.getAllParamValues());
+            
+        }
+        if(mappingID == RECALL_PRESET_HIT){
+            
+            loadPreset("blah");
+            //candidateSynth.startMetronome();
+            
+        }
+    }
+    //TODO move this
+    void loadPreset(string pname){
+        
+        vector<int> values = expPresetManager.recallPreset(pname);
+        if (values.size()){
+            candidateSynth.setAllParams(values);
+            setAllSlidersToValues(values);
+        }else{
+            cout << "ERROR, no preset found" << endl;
+        }
+    }
+    // called from UI
+    // OVERLOADED
+    void paramChangeCallback(int mappingID, int value){
+        candidateSynth.paramChangeCallback(mappingID, value);
+        vector<int> evtData;
+        evtData.push_back(mappingID); // or just index?
+        evtData.push_back(value);
+        
+        eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
+    };
+    
+    
+    void midiFromLeap(int ctl_num, int ctl_val){
+        
+        if (!okToGetLeapMidi){
+            return;
+        }
+        
+        Test *theTest = testController->getCurrentTestPtr();
+        if (theTest == NULL) return;
+        
+        vector<int> ci = theTest->getChangeableIndices();
+        vector<int> mids = candidateSynth.getMappingIDForIndices(ci);
+        if (ctl_num >= mids.size() || ctl_num < 0) return;
+        
+        candidateSynth.paramChangeCallback(mids[ctl_num], ctl_val);
+        
+        setUIToParam(ctl_num, ctl_val);
+        
+        vector<int> evtData;
+        evtData.push_back(mids[ctl_num]); // or just index?
+        evtData.push_back(ctl_val);
+        
+        eventLogger.logEvent(CANDIDATE_PARAM_ADJUSTED, evtData);
+
+    }
+
+    
+    ofTrueTypeFont verdBig;
+
+};
+
+#endif /* defined(__riftathon__SearchMessageOrganiser__) */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SearchMessageOrganiser.mm	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,9 @@
+//
+//  SearchMessageOrganiser.mm
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#include "SearchMessageOrganiser.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SequenceController.h	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,35 @@
+//
+//  SequenceController.h
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#ifndef __riftathon__SequenceController__
+#define __riftathon__SequenceController__
+
+#include <iostream>
+#include "presetManager.h"
+
+class Sequence{
+    int tempo;
+    vector<Preset *> presetSequence;
+    
+    
+};
+
+class SequenceControler{
+    
+    SequenceControler(const vector<Preset>& presets);
+
+    void makeSequences();
+    
+    Sequence getNextSequence();
+    
+private:
+    const vector<Preset>& thePresets;
+    vector<Sequence> theSequences;
+};
+
+#endif /* defined(__riftathon__SequenceController__) */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SequenceController.mm	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,9 @@
+//
+//  SequenceController.mm
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#include "SequenceController.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TrainingMessageOrganiser.h	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,17 @@
+//
+//  TrainingMessageOrganiser.h
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#ifndef __riftathon__TrainingMessageOrganiser__
+#define __riftathon__TrainingMessageOrganiser__
+
+#include <iostream>
+
+class TrainingMessageOrganiser{
+    
+};
+#endif /* defined(__riftathon__TrainingMessageOrganiser__) */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TrainingMessageOrganiser.mm	Fri Oct 17 16:35:22 2014 +0100
@@ -0,0 +1,9 @@
+//
+//  TrainingMessageOrganiser.mm
+//  riftathon
+//
+//  Created by Robert Tubb on 17/10/2014.
+//
+//
+
+#include "TrainingMessageOrganiser.h"
--- a/testApp.h	Fri Oct 17 15:13:35 2014 +0100
+++ b/testApp.h	Fri Oct 17 16:35:22 2014 +0100
@@ -28,6 +28,8 @@
 #include "buttronXY.h"
 #include "UIGrid.h"
 #include "MessageOrganiser.h"
+#include "SearchMessageOrganiser.h"
+#include "TrainingMessageOrganiser.h"
 #include "TestController.h"
 #include "timeController.h"
 #include <buttonPanel.h>
@@ -76,7 +78,13 @@
     UsernameAlertViewController *usernameAlertViewController;
     IntroViewController * introViewController;
     
-    MessageOrganiser messageOrganiser;
+    SearchMessageOrganiser searchMessageOrganiser;
+    TrainingMessageOrganiser trainingMessageOrganiser;
+    
+    
+    PDSynthWrapper targetSynth;
+    PDSynthWrapper candidateSynth;
+    
     TestController* testController;
     //TimeController timeController;
     interfaceType whichInterfaceShowing, previousInterface;
--- a/testApp.mm	Fri Oct 17 15:13:35 2014 +0100
+++ b/testApp.mm	Fri Oct 17 16:35:22 2014 +0100
@@ -17,22 +17,23 @@
     
     
     initialiseVariables();
-    
-    
-    testController = new TestController;
+
     
     expPresetManager.onAppLoad();
     
     //presetManager.startLoadAll();
     
+    targetSynth.init(&core,"targetSynth");
+    candidateSynth.init(&core,"candidateSynth");
     
-    messageOrganiser.init(&core, testController);
+    searchMessageOrganiser.init(targetSynth, candidateSynth);
     timeController.init();
     initialiseGUIs();
     initialiseMIDI();
     setupUIElements();
 
 
+
     
     light.setSpotlight(45. , 1.);
     light.enable();
@@ -134,36 +135,36 @@
     
     Buttron* playTargetButton = new Buttron(p.buttonWidth*0.2,680, p);
     playTargetButton->setLabel("Target");
-    messageOrganiser.mapButtonToAction(playTargetButton, TRIGGER_TARGET_ID);
+    searchMessageOrganiser.mapButtonToAction(playTargetButton, TRIGGER_TARGET_ID);
     bottomButtonPanel->addButton(playTargetButton);
-    messageOrganiser.setTargetButton(playTargetButton);
+    searchMessageOrganiser.setTargetButton(playTargetButton);
     
     Buttron * playCandidateButton = new Buttron(p.buttonWidth*1.4,680, p);
     playCandidateButton->setLabel("Current");
-    messageOrganiser.mapButtonToAction(playCandidateButton, TRIGGER_CANDIDATE_ID);
+    searchMessageOrganiser.mapButtonToAction(playCandidateButton, TRIGGER_CANDIDATE_ID);
     bottomButtonPanel->addButton(playCandidateButton);
     
     
     // submit button - only one for now
     Buttron * submitButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
     submitButton->setLabel("Submit");
-    messageOrganiser.mapButtonToAction(submitButton, SUBMIT_CANDIDATE);
+    searchMessageOrganiser.mapButtonToAction(submitButton, SUBMIT_CANDIDATE);
     bottomButtonPanel->addButton(submitButton);
     
     //  button - just for spacing pruposes
     Buttron * saveButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
     saveButton->setLabel("SAVE");
-    messageOrganiser.mapButtonToAction(saveButton, SAVE_PRESET_HIT);
+    searchMessageOrganiser.mapButtonToAction(saveButton, SAVE_PRESET_HIT);
     bottomButtonPanel->addButton(saveButton);
     saveButton->hide();
     
     Buttron * recallButton = new Buttron(ofGetWidth()*0.5 - p.buttonWidth*0.5,680, p);
     recallButton->setLabel("RECALL");
-    messageOrganiser.mapButtonToAction(recallButton, RECALL_PRESET_HIT);
+    searchMessageOrganiser.mapButtonToAction(recallButton, RECALL_PRESET_HIT);
     bottomButtonPanel->addButton(recallButton);
     recallButton->hide();
     
-    messageOrganiser.setBottomPanel(bottomButtonPanel);
+    searchMessageOrganiser.setBottomPanel(bottomButtonPanel);
     UIElements.push_back(bottomButtonPanel);
     bottomButtonPanel->showBorder(false);
 
@@ -171,19 +172,19 @@
     
     CountdownText * countDownBox = new CountdownText("5" , 500, 380, 455, 455, p);
     UIElements.push_back(countDownBox);
-    messageOrganiser.setCountdownPanel(countDownBox);
+    searchMessageOrganiser.setCountdownPanel(countDownBox);
     countDownBox->hide();
     
     TextPanel * scoreFeedback = new TextPanel("Feedback panel", ofGetWidth()*0.5 - p.buttonWidth*0.5, 666, 400,100,p);
     scoreFeedback->setFontSize(SMALLFONT);
     UIElements.push_back(scoreFeedback);
-    messageOrganiser.setScorePanel(scoreFeedback);
+    searchMessageOrganiser.setScorePanel(scoreFeedback);
     scoreFeedback->hide();
     
     TextPanel * finishPanel = new TextPanel("Finish txt panel", 250, 250, 1000,400,p);
     finishPanel->setFontSize(LARGEFONT);
     finishPanel->setText("Experiment completed");
-    messageOrganiser.setFinishPanel(finishPanel);
+    searchMessageOrganiser.setFinishPanel(finishPanel);
     
     UIElements.push_back(finishPanel);
     finishPanel->hide();
@@ -192,12 +193,12 @@
     Buttron * newTestButton = new Buttron(ofGetWidth()-300,690, p);
     newTestButton->setLabel("Next Test");
     UIElements.push_back(newTestButton);
-    messageOrganiser.mapButtonToAction(newTestButton, NEW_TEST_ID);
+    searchMessageOrganiser.mapButtonToAction(newTestButton, NEW_TEST_ID);
     newTestButton->hide();
-    messageOrganiser.setNewTestButton(newTestButton);
+    searchMessageOrganiser.setNewTestButton(newTestButton);
     
     TargetSymbol* targetSymbol = new TargetSymbol(ofGetWidth()*0.5,160,30,p);
-    messageOrganiser.setTargetSymbol(targetSymbol);
+    searchMessageOrganiser.setTargetSymbol(targetSymbol);
     UIElements.push_back(targetSymbol);
     
 }
@@ -215,7 +216,7 @@
                                                  sl2);
     
     UIElements.push_back(controlPanel);
-    messageOrganiser.setControlPanel(controlPanel);
+    searchMessageOrganiser.setControlPanel(controlPanel);
     controlPanel->showBorder(true);
 }
 //--------------------------------------------------------------
@@ -319,9 +320,7 @@
 		delete outputs[i];
 	}
     deleteVectorOfPointers(&UIElements); // TODO this crashes??
-    
-    
-    delete testController;
+
     
     cout << "exit done \n";
 }
@@ -383,7 +382,7 @@
     eventLogger.logEvent(START_THE_TESTS);
     whichInterfaceShowing = COUNT_DOWN;
     // do countdown etc
-    messageOrganiser.countdownToNewTest();
+    searchMessageOrganiser.countdownToNewTest();
     // TODO how is testApp going to kknow whichInterfaceShowing ???
     
 }
@@ -487,7 +486,7 @@
     //ofLine(0,150,1024,150);
     
     //drawWaveform();
-    drawScore();
+    searchMessageOrganiser.drawScore();
     
     
 
@@ -500,28 +499,7 @@
         (*UIitr)->draw();
     }
 }
-//------------------------------------------------------------------------
-void testApp::drawScore(){
-    ofColor txtCol = ofColor(150,235,200,255);
-    
-    int score = messageOrganiser.getScore();
-    stringstream msg;
-    
-    msg << "Test: " << testController->getCurrentTestLetter();
-    ofSetColor(txtCol);
-    verdBig.drawString(msg.str(), 40, 140);
-    msg.str(std::string());
-    
-    msg << "Score: " << score;
-    verdBig.drawString(msg.str(), 240, 140);
-    msg.str(std::string());
-    
-    pair<int,int> time;
-    time = messageOrganiser.getTime();
-    msg << "Time taken: " << time.first << ":" << time.second << endl;
-    verdBig.drawString(msg.str(), 600, 140);
-    
-}
+
 //------------------------------------------------------------------------
 
 //--------------------------------------------------------------
@@ -664,7 +642,7 @@
         int ctl_val = msg.value;
         // TODO route control change message here
         //cout << " ctrl : " << ctl_num << " : " << ctl_val << endl;
-        messageOrganiser.midiFromLeap(ctl_num, ctl_val);
+        searchMessageOrganiser.midiFromLeap(ctl_num, ctl_val);
     }
  
 }