//
//  TestController.mm
//  tweakathlon
//
//  Created by Robert Tubb on 16/01/2014.
//
//

#include "TestController.h"
const int TestController::numDifferentTests = 80;
const int TestController::totalNumTests = 80;


template <typename T>
vector<T> makeVector(T a1, T a2,T a3,T a4,T a5,T a6, T a7, T a8){
    
    vector<T> vec;
    vec.push_back(a1);
    vec.push_back(a2);
    vec.push_back(a3);
    vec.push_back(a4);
    vec.push_back(a5);
    vec.push_back(a6);
    vec.push_back(a7);
    vec.push_back(a8);
    return vec;
}

void randomise(int& n){
    n = ofRandom(0,127);
    
}

vector<vector <bool> > makeCombinations(){
    // make all unordered pairs
    int N = TOTAL_NUM_PARAMS;
    
    vector<vector <bool> > table;
    for(int n=0; n < N-1; n++){
        
        vector<bool> c(6, false);
        for(int m=n+1; m<N; m++){
            
            // reset all to false
            for(int i=0; i<N; i++){
                c[i] = false;
            }
            
            c[n] = true;
            c[m] = true;
            
            table.push_back(c);
            
        }
        
    }
    return table;
}
//----------------------------------------------------------------------------------------

void TestController::generate2DRandomTests(){
    
    controlPanelType panelType;
    int numDimensions = 2;
    
    vector<vector <bool> > ap = makeCombinations();
    // 4 tests for each
    int testsPerSpace = 2;
    int numTests = 2 * testsPerSpace * ap.size();
    int testNum = testList.size();
    panelType = REVISITABLE;
    for(int i=0;i<numTests/2; i++){
        char letter = char(testNum+65);
        
        testList.push_back(Test(letter,20, panelType, numDimensions, ap[floor(i/testsPerSpace)]));
        testNum++;
    }
    panelType = SIMULTANEOUS;
    for(int i=numTests/2+1;i<numTests; i++){
        char letter = char(i+65);
        
        testList.push_back(Test(letter,20, panelType, numDimensions, ap[floor((i-numTests/2)/testsPerSpace)]));
        
    }
};
//------------------------------------------
// much better contruction!
void TestController::generateSomeTests(int howManyTests,
                                       int numDimensions,
                                       controlPanelType panelType,
                                       int whichSpace,
                                       bool scored,
                                       bool aHint,
                                       bool aMemoryTest){
    int testNum = testList.size();
    
    vector<bool> adjustables = makeVector(false, false, false, false, false, false, false, false);
    vector<int> target = makeVector(40,64, 10, 74, 21, 80,45 ,45 ); // the default target
    
    // big if - good spaces for each num of dimensions
    if(numDimensions == 1){
        // def 64,64, 30, 55, 42, 43;
        
        adjustables[whichSpace-1] = true;
        
    }else if(numDimensions == 2){
        
        if (whichSpace == 1){
            target = makeVector(64,64, 30, 55, 40, 43, 0, 0);
            adjustables[0] = true; // pitch
            adjustables[3] = true; // decay
        }else if(whichSpace == 2){

            
            target = makeVector(64,64, 0, 90, 20, 127, 0, 0);
            adjustables[3] = true; // decay
            adjustables[5] = true; // cutoff
        }else if(whichSpace == 3){
            target = makeVector(56,64, 20, 64, 10, 90, 0, 0);
           
            adjustables[1] = true; // pulse
            adjustables[2] = true; // attack
        }else if(whichSpace == 4){
            target = makeVector(64,64, 0, 55, 40, 43, 0, 0);
            adjustables[1] = true; // pulse
            adjustables[4] = true; // ftype
        }
    }else if(numDimensions == 3){
        if(whichSpace == 1){
            target = makeVector(64,64, 10, 64, 41, 43, 0, 0);
            adjustables[0] = true; // pitch
            adjustables[3] = true; // decay
            adjustables[5] = true; // cutoff
        }else if(whichSpace == 2){
            target = makeVector(12,64, 10, 67, 41, 64, 0, 0);
            adjustables[1] = true; // pulse
            adjustables[2] = true; // attack
            adjustables[4] = true; // ftype
        }
    }else {
        for (int i = 0; i < numDimensions; i++){
            adjustables[i] = true; // pitch
        }
    }
    
    
    
    for(int i=0; i < howManyTests; i++){
        char letter = char(testNum+65);
        testList.push_back(Test(letter,20, panelType, numDimensions, adjustables, target, scored, aHint, aMemoryTest));
    }
}


//-------------------------------------------
void TestController::generate4DTests(){
    // 4d seq  - learnable??
}