//
//  Quase-Cinema VJ software
//  http://www.quasecinema.org
//
//  Alexandre Rangel - VJ Xorume
//
//  C++
//  openFrameworks http://www.openframeworks.cc
//
//  GLP 2.0 licence http://www.gnu.org/licenses/gpl.html
//


#include "testApp.h"


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::setup(){

	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  general setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// platformDependant variables:

	//ofSetLogLevel(OF_LOG_VERBOSE);
	
	#ifdef TARGET_WIN32
		eraseChars = 12;
		QCmovieSaver = 1;
	#elif defined(TARGET_OSX)
		eraseChars = 22;
		QCmovieSaver = 1;
	#elif defined(TARGET_LINUX)
		eraseChars = 5;
		QCmovieSaver = 0;
	#endif


	
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  general variables setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    ofSetVerticalSync(true); //for smooth animation, set vertical sync if we can
	ofSetFrameRate(60);
	layerInfluenced = 1;
	ofBackground(0,0,0);
	ofSetBackgroundAuto(true);

	screenSizeIndex = 5; interfaceSizeIndex = 3; QCchangeResolution();
	
	checkX = 0; checkY = 0; checkWidth = 0; checkHeight = 0;

	tempValue = 0.0;
	tempValueInt = 0;

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  directories setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    browsingDirs = -1; // not browsing video directories
    browsingClips = 1; // browsing video clips
    browsingAudioDirs = -1; // not browsing audio directories
	browsingAudioClips = -1; // not browsing audio clips
	browsingDirsPage = 1; // initial directory page (for dirs with more than 45 clips)
	browsingAudioDirsPage = 1; // initial audio directory page (for dirs with more than 45 clips)
	nAudioFilesLimited = 1;


    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  images setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    DirImages.allowExt("png"); DirImages.allowExt("jpg"); DirImages.allowExt("bmp"); DirImages.allowExt("gif");
    nImages = DirImages.listDir("_images");
 	images = new ofImage[nImages];
    for(int i = 0; i < nImages; i++) images[i].loadImage(DirImages.getPath(i));
    currentImage = 0;



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  video playback setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    nFolders = DirFolders.listDir("_videos");
    int tempValue = (ofGetSeconds()*16); ofSeedRandom(tempValue); ofSeedRandom();
    int currentFolderNum = int(ofRandom(0,nFolders));
    nVideos = DirVideos.listDir(DirFolders.getPath(currentFolderNum));
	selectedLayer = 1;
	previewMonitor = 1; // little preview on
	previewFull = 0; // full screen preview off



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  audio playback setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    nAudioFolders = DirAudioFolders.listDir("_audio");
    int currentAudioFolderNum = 0;
    DirAudioFiles.allowExt("mp3"); DirAudioFiles.allowExt("wav"); DirAudioFiles.allowExt("ogg");
    nAudioFiles = DirAudioFiles.listDir(DirAudioFolders.getPath(currentAudioFolderNum));
    browsingAudioDirsPage = 1; // initial audio directory page (useful for dirs with more than 45 clips)
    selectedAudioChannel = 1;
    //setMultiPlay(1);



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // video array setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    for (int x = 0; x < 16; x++) {
	    videos[x] = new ofVideoPlayer[nVideos]; // 16 video player instances
	    currentVideo[x] = 0;
	    videos[x][currentVideo[x]].loadMovie(DirVideos.getPath(int(ofRandom(0,nVideos))));
	    videos[x][currentVideo[x]].setLoopState(OF_LOOP_NORMAL); // Linux
        //videos[x][currentVideo[x]].idleMovie();
	}
	texScreen.allocate(screenSizeX,screenSizeY,GL_RGB); // full screen preview



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
	//  thumbnails setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	videoThumbs = new ofVideoPlayer[nVideos];
	videoThumbsPage = 1;
	audioThumbsPage = 1;
	currentVideoThumb = 0;
	currentAudioThumb = 0;
	QCchangeFolder();
	QCvideoThumbs();



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  setup of variables
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	for (int x = 0; x < 4; x++) { // loop layers 1 to 4 (indexes 0 to 3)
        layerVisibility[x] = -1; // layer off
        layerSequenceEnabled[x] = -1;
        layerSequenceItem[x] = 0;
        layerSpeed[x] = 1.0; // layer speed = 1
        layerVolume[x] = 1.0;
	}
	for (int x = 0; x < 8; x++) { //loop layers 5 to 8 (indexes 4 to 7)
        layerVisibility[x] = -1;
        layerBlend[x] = 0; // normal blend
        layerOpacity[x] = 1.0; // layer opacity = 1
        layerRed[x] = 1.0;
        layerGreen[x] = 1.0;
        layerBlue[x] = 1.0;
        layerInvert[x] = -1;
		layerFlip[x] = false;
	}
	layerVisibility[0] = 1; //layer 1 on



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  interface setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    redrawInterface = 1; // do interface initialization on draw routine
    interfaceBackground.loadImage("interface/interface.png");
    interfaceLayers.loadImage("interface/interfaceLayers.png");
    interfaceNeutralLayers.loadImage("interface/interfaceNeutralLayers.png");
    layerOutlineA.loadImage("interface/layerOutlineA.png");
    layerOutlineB.loadImage("interface/layerOutlineB.png");
    thumbsVertPos = 200; thumbsHorPos = 10;
    splashScreen.loadImage("interface/splashScreen.png");
	iconLightPaintOn.loadImage("interface/iconLightPaintOn.png");
	iconLightPaintOff.loadImage("interface/iconLightPaintOff.png");
	iconLightPaintFeedOn.loadImage("interface/iconLightPaintFeedOn.png");
	iconLightPaintFeedOff.loadImage("interface/iconLightPaintFeedOff.png");
	iconLightPaintMirrorOn.loadImage("interface/iconMirrorOn.png");
	iconLightPaintMirrorOff.loadImage("interface/iconMirrorOff.png");
    iconPageActive.loadImage("interface/iconPageActive.png");
    iconPageNotActive.loadImage("interface/iconPageNotActive.png");
	languageCode[0] = 'P';
	bFullscreen = 0;
	showBinDurations = 1;



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // livecam setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	bWebcamInit = 0;
    livecamDevice = 0;



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  effects setup: invert
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // video invert
    videoInvert1B = new unsigned char[screenSizeX*screenSizeY*3];

    //videoInvert1A.allocate(800,600, GL_RGB);

    // image invert
    imageInvert1B = new unsigned char[screenSizeX*screenSizeY*3];

	// flip
    videoFlipB = new unsigned char[screenSizeX*screenSizeY*3];





    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  image saver setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	snapCounter = 0;
	bSnapshot = false;



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  3D setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    object3D.loadModel("_3D/3DObject.3ds");
    bMousePressed = false;
	size3D = 1.0;
	rot3D = 0.0;
	rot3DAxis = ofRandom(0,2);



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  ofxGui setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	speed   	= 0.0f;
	tempValue   = 0.0f;
	gui	= ofxGui::Instance(this);
	gui->buildFromXml(OFXGUI_XML);



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  text setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	fontAutomat6.loadFont("interface/fonts/automat.ttf",6 , false, true);  // no antialias
	fontAutomat8.loadFont("interface/fonts/automat.ttf",8 , false, true);  // no antialias
    fontVerdana8.loadFont("interface/fonts/verdana.ttf",8 , false, true);  // no antialias
    fontVerdana10.loadFont("interface/fonts/verdana.ttf",10 , true, true);
	fontVerdana11.loadFont("interface/fonts/verdana.ttf",11 , true, true);
    fontArial18.loadFont("interface/fonts/arial.ttf",18 , true, true);
    fontArial64.loadFont("interface/fonts/arial.ttf",64 , true, true);
    fontArialBlack18.loadFont("interface/fonts/ariblk.ttf",18 , true, true);
    fontArialBlack48.loadFont("interface/fonts/ariblk.ttf",48 , true, true);
    fontArialBlack64.loadFont("interface/fonts/ariblk.ttf",64 , true, true);
    fontArialBlack72.loadFont("interface/fonts/ariblk.ttf",72 , true, true);
    fontAsimov18.loadFont("interface/fonts/asimov.ttf",18 , true, true);
    fontAsimov64.loadFont("interface/fonts/asimov.ttf",64 , true, true);
	fontGoodtime18.loadFont("interface/fonts/goodtime.ttf",18 , true, true);
    fontGoodtime64.loadFont("interface/fonts/goodtime.ttf",64 , true, true);
    fontGreek18.loadFont("interface/fonts/greek.ttf",18 , true, true);
    fontGreek64.loadFont("interface/fonts/greek.ttf",64 , true, true);
    fontSteppes18.loadFont("interface/fonts/steppes.ttf",18 , true, true);
    fontSteppes64.loadFont("interface/fonts/steppes.ttf",64 , true, true);
    fontTimes18.loadFont("interface/fonts/timesbd.ttf",18 , true, true);
    fontTimes64.loadFont("interface/fonts/timesbd.ttf",64 , true, true);
    textHorPos = 10; textVertPos = 300;
    currentFont = 1;
	for (int x = 0; x <22; x++) textInput[x] = '.';
    textInputActive = -1;
    textInputCharPos = 0;



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  timer setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    currentTime = glutGet(GLUT_ELAPSED_TIME);
    QCresetTimers();



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  stepping video load setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    videoLoading = 0;
    videoLoadingNewPage = 0;
    videoLoadStep = 0;
    audioLoading = 0;
    audioLoadStep = 0;



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  video saver setup
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #ifdef TARGET_LINUX
        // nothing
    #else // Mac and Windows
		saver.listCodecs();
		//saver.setCodecType(7); //ZACH FIX see recording quicktime with sound in sync on of forum
		saver.setCodecQualityLevel(OF_QT_SAVER_CODEC_QUALITY_HIGH);
		//QCrecordingPrepare();
    #endif



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  light paint setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	for (int x = 0; x<8; x++) lightPaint[x] = 0;
	lightPaintTime = 0.0; // light paint does not resets with time
	lightPaintRetrigger = 3000; // time to turn back on light paint when 'light paint time' is set on slider
	lightPaintFeedback = false;
	lightPaintStretchX = 0;
	lightPaintStretchY = 0;
	lightPaintStretchXadd = 0;
	lightPaintStretchYadd = 0;



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  arduino setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ard.connect("/dev/cu.usbserial-A6008lUz", 57600);
	//ard.connect("/dev/cu.usbserial-A6008iN9", 57600);
	bSetupArduino = false;
	for (int x = 0; x<6; x++) arduinoPatching[x] = false;
	arduinoControlling[0] = "layerOpacity1";
	arduinoControlling[1] = "layerOpacity2";
	arduinoControlling[2] = "layerOpacity3";
	arduinoControlling[3] = "layerOpacity4";
	arduinoControlling[4] = "layerOpacity5";
	arduinoControlling[5] = "layerOpacity7";

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  openCV setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	colorImg.allocate(screenSizeX,screenSizeY);
	//grayImage.allocate(screenSizeX,screenSizeY);
	//grayBg.allocate(screenSizeX,screenSizeY);
	//grayDiff.allocate(screenSizeX,screenSizeY);
	//bLearnBakground = true;
	//threshold = 80;
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  OSC setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// listen on the given port
	cout << "listening for osc messages on port " << PORT << "\n";
	receiver.setup( PORT );

	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  FFT1 setup
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
//	srand((unsigned int)time((time_t *)NULL));
//	
//	// 0 output channels, 
//	// 2 input channels
//	// 44100 samples per second
//	// BUFFER_SIZE samples per buffer
//	// 4 num buffers (latency)
//	
//	ofSoundStreamSetup(0,2,this, 44100,BUFFER_SIZE, 4);	
//	left = new float[BUFFER_SIZE];
//	right = new float[BUFFER_SIZE];
//	
//	for (int i = 0; i < NUM_WINDOWS; i++)
//	{
//		for (int j = 0; j < BUFFER_SIZE/2; j++)
//		{
//			freq[i][j] = 0;	
//		}
//	}
	
	
	////////////////////////////
	//
	//  FFT2 setup
	//
	////////////////////////////
	
//	nBandsToGet = 128;
//	numberOfFreqsToGet = 256;
//	
//	ofSoundStreamSetup(0,2,this, 44100, 256, 4);	
//	left = new float[256];
//	right = new float[256];
	
	
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::update(){

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  interface update
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	//////////////////////
	//
	//  idle movies
	//
	//////////////////////

	MoviesTask(0,0);
	
	//for (int x = 0; x <4; x++) {
	//	if (layerVisibility[x] == 1) videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].idleMovie();
	//}



	/////////////////////////////////////////
	//
	//  layer sequence update
	//  checking if QC has to change layer movie
	//
	/////////////////////////////////////////

	for (int x = 0; x < 4; x++) {
		if (layerSequenceEnabled[x] == 1) {
			if (videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].getPosition() > 0.975) { // movie ended

				QCstopMovieOnLayer(x);

				layerSequenceItem[x]++;
				if (layerSequenceItem[x] == 4) layerSequenceItem[x] = 0;

				QCresumeCurrentMovieOnLayer(x);

				videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPosition(0.01);
				//videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].idleMovie();
			}
		}
	}



	////////////////////
	//
	// livecam update
	//
	////////////////////

	if (layerVisibility[4] == 1) { // livecam layer 5 (index 4)
		vidGrabber.grabFrame();
		if ( (layerInvert[4] == 1) and (vidGrabber.isFrameNew()) ) { // video color inverted
			int totalPixels = camWidth*camHeight*3;
			unsigned char * pixels = vidGrabber.getPixels();
			for (int i = 0; i < totalPixels; i++) videoInverted[i] = 255 - pixels[i];
			videoTexture.loadData(videoInverted, camWidth,camHeight, GL_RGB);
		}
	}



	////////////////////////
	//
	// save image update
	//
	////////////////////////

	if (bSnapshot == true){
		img.grabScreen(interfaceSizeX,0,screenSizeX,screenSizeY);
		char fileName[255];
		sprintf(fileName, "snapshot_%0.3i.bmp", snapCounter);
		img.saveImage(fileName);
		snapCounter++;
		bSnapshot = false;
	}



	/////////////////////
	//
	// timer update
	//
	/////////////////////

	currentTime = glutGet(GLUT_ELAPSED_TIME);

	for (int x = 0; x <4; x++) { // for layers 1 to 4 only

		///////////////////////
		//
		// layer sequence step
		//
		///////////////////////

		// if (layerSequenceEnabled[x] == 1) { // step update
		if ( (timeStep[x] > 1) and ((currentTime-previousTimeStep[x]) > timeStep[x]) ) {
			QCstopMovieOnLayer(x);
			QCchangeSequenceItem(x);
			if (layerVisibility[x] == 1) QCresumeCurrentMovieOnLayer(x);
			previousTimeStep[x] = currentTime;
		} // end if
		//} // end if


		///////////////////////////
		//
		// layer playhead random
		//
		///////////////////////////

		if ( (timePlayheadRandom[x] > 1) and ((currentTime-previousTimePlayheadRandom[x]) > timePlayheadRandom[x]) and (layerVisibility[x] == 1) ) { // playhead random update
			tempValue = ofRandom(0.01,0.99);
			videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPosition(tempValue);
			previousTimePlayheadRandom[x] = currentTime;
			QCupdatePlayhead(x, tempValue);
		} // end if

	} // end for layers 1 to 4


	for (int x = 0; x <8; x++) { // for layers 1 to 8

		/////////////////
		//
		// layer blink
		//
		/////////////////

		if ( (timeBlink[x] > 0) and ((currentTime-previousTimeBlink[x]) >= timeBlink[x]) ) {
			layerVisibility[x]= - layerVisibility[x];
			if (x < 4) { // video layers 1 to 4
				if (layerVisibility[x] == -1)  {
					QCstopMovieOnLayer(x);
				} else {
					QCresumeCurrentMovieOnLayer(x);
				}
			}
			if (x == 4) { // livecam
				if ( (bWebcamInit == 0) and (layerVisibility[4] == 1) ) QCinitWebcam();
				lightPaintStretchXadd = 0; lightPaintStretchYadd = 0; // if layer was just turned on, resets feedback
			}
			previousTimeBlink[x] = currentTime;
		} // end if


		//////////////////////
		//
		// layer color random
		//
		//////////////////////

		if ( (timeColorRandom[x] > 1) and ( (currentTime-previousTimeColorRandom[x]) >= timeColorRandom[x]) ) {
			switch (int (ofRandom(0.0,7.99))) { // 3 bit color combinations
				case 0: layerRed[x] = 1.0; layerGreen[x] = 0.0; layerBlue[x] = 0.0; break;
				case 1: layerRed[x] = 0.0; layerGreen[x] = 1.0; layerBlue[x] = 0.0; break;
				case 2: layerRed[x] = 0.0; layerGreen[x] = 0.0; layerBlue[x] = 1.0; break;
				case 3: layerRed[x] = 1.0; layerGreen[x] = 1.0; layerBlue[x] = 0.0; break;
				case 4: layerRed[x] = 1.0; layerGreen[x] = 0.0; layerBlue[x] = 1.0; break;
				case 5: layerRed[x] = 0.0; layerGreen[x] = 1.0; layerBlue[x] = 1.0; break;
				case 6: layerRed[x] = 1.0; layerGreen[x] = 0.0; layerBlue[x] = 1.0; break;
				case 7: layerRed[x] = 1.0; layerGreen[x] = 1.0; layerBlue[x] = 1.0; break;
			} // end switch
			previousTimeColorRandom[x] = currentTime;
		} // end if color random

		/////////////////////
		//
		// layer invert
		//
		/////////////////////

		if ( (timeInvert[x] > 1) and ((currentTime-previousTimeInvert[x]) > timeInvert[x]) ) {
			layerInvert[x]= - layerInvert[x];
			previousTimeInvert[x] = currentTime;
		} // end if

	} // end for layers 1 to 8

	//////////////////////
	//
	// timers 3D
	//
	//////////////////////

	// 3D size
	if ( (timeSize3D > 1) and ( (currentTime-previousTimeSize3D) >= timeSize3D) ) {
		size3D = ofRandom(0.0,1.5);
		previousTimeSize3D = currentTime;
	} // end if

	// 3D rotation
	if ( (timeRot3D > 1) and ( (currentTime-previousTimeRot3D) >= timeRot3D) ) {
		rot3D = ofRandom(-360,360);
		rot3DAxis = ofRandom(0,2);
		previousTimeRot3D = currentTime;
	} // end if

	//////////////////////
	//
	// light paint timer
	//
	//////////////////////

	// just turns light paint off
	if ( (layerVisibility[4] == 1) and (lightPaint[4] == 1) and (lightPaintTime > 0.0) and ( (currentTime-previousLightPaintTime) >= lightPaintTime) ) {
		lightPaint[4] = 0;
		previousLightPaintTime = currentTime;
		lightPaintRetrigger = currentTime;
		offLightPaintTime = currentTime; // when light paint was turned off

		lightPaintStretchXadd = 0;
		lightPaintStretchYadd = 0;

	} // end if

	// just turn light paint back on
	if ( (layerVisibility[4] == 1) and (lightPaint[4] == 0) and (lightPaintTime > 0.0) and ( (currentTime-offLightPaintTime) >= 1000) ) {
		lightPaint[4] = 1;
		//previousLightPaintTime = currentTime;
	} // end if



	//////////////////////
	//
	// light paint update
	//
	//////////////////////

	if (lightPaint[4] == 1) {
		// stores previous frame
		texScreen.loadScreenData(interfaceSizeX,0,screenSizeX,screenSizeY);
	}



	/////////////////////
	//
	// Arduino update
	//
	/////////////////////

	if ( ard.isArduinoReady()){

		// 1st: setup the arduino if haven't already:
		if (bSetupArduino == false){
			setupArduino();
			bSetupArduino = true;	// only do this once
		}
		// 2nd do the update of the arduino
		updateArduino();
	}
	
	
	
	///////////////////////////////
	//
	//  OSC update
	//
	//////////////////////////////
	
	// check for waiting messages
	while( receiver.hasWaitingMessages() )
	{
		// get the next message
		ofxOscMessage m;
		receiver.getNextMessage( &m );
		
		// OSC - touchOSC
		
		
		// fade
		if ( m.getAddress() == "/xtra/fade" ) {
		//if ( m.getAddress() == "/midi/cc22/1" ) {
			tempValue = m.getArgAsFloat(0);
			masterFader = tempValue;
			tempValue = tempValue * 100.0;
			gui->update(kParameter_masterFader, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		
		// OSC layer 1
		if ( m.getAddress() == "/layer1" ) { selectedLayer = 1; }
		if ( m.getAddress() == "/layer1/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 0;
			layerVisibility[layerIndex] = tempValue;
			if (layerVisibility[layerIndex] == -1) {
				QCstopOneMovie();
			}else{
				QCresumeCurrentMovie();
			}
		}
		if ( m.getAddress() == "/layer1/reverse" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 1) { // thumb down
				int layerIndex = 0;
				float x = videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].getSpeed();
				x = - (x) ;
				layerSpeed[layerIndex] = x;
				videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			}
		}
		if ( m.getAddress() == "/layer1/opacity" ) {
			int layerIndex = 0;
			tempValue = m.getArgAsFloat(0);
			layerOpacity[layerIndex] = tempValue;
			gui->update(kParameter_LayerOpacity1, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer1/speed" ) {
			int layerIndex = 0;
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 5.0; 
			layerSpeed[layerIndex] = tempValue;
			// sets new video speed
			videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			gui->update(kParameter_LayerSpeed1, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer1/step" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 0;
			tempValue = tempValue * 480; // normalize for slider
			timeStep[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeStep1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer1/blink" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 0;
			tempValue = tempValue * 480; // normalize for slider
			timeBlink[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeBlink1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer1/tempo" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 0;
			tempValue = tempValue * 480; // normalize for slider
			timePlayheadRandom[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timePlayheadRandom1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer1/invert" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 0;
			tempValue = tempValue * 480; // normalize for slider
			timeInvert[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeInvert1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		
		// OSC layer 2
		if ( m.getAddress() == "/layer2" ) { selectedLayer = 2; }
		if ( m.getAddress() == "/layer2/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 1;
			layerVisibility[layerIndex] = tempValue;
			if (layerVisibility[layerIndex] == -1) {
				QCstopOneMovie();
			}else{
				QCresumeCurrentMovie();
			}
		}
		if ( m.getAddress() == "/layer2/comp0" ) {
			int tempValue = 0;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp1" ) {
			int tempValue = 1;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp2" ) {
			int tempValue = 2;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp3" ) {
			int tempValue = 3;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp4" ) {
			int tempValue = 4;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp5" ) {
			int tempValue = 5;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/comp6" ) {
			int tempValue = 6;
			int layerIndex = 1;
			layerBlend[layerIndex] = tempValue;
			gui->update(kParameter_Composite2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/reverse" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 1) { // thumb down
				int layerIndex = 1;
				float x = videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].getSpeed();
				x = - (x) ;
				layerSpeed[layerIndex] = x;
				videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			}
		}
		if ( m.getAddress() == "/layer2/opacity" ) {
			int layerIndex = 1;
			tempValue = m.getArgAsFloat(0);
			layerOpacity[layerIndex] = tempValue;
			gui->update(kParameter_LayerOpacity2, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer2/speed" ) {
			int layerIndex = 1;
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 5.0; 
			layerSpeed[layerIndex] = tempValue;
			// sets new video speed
			videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			gui->update(kParameter_LayerSpeed2, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer2/step" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 1;
			tempValue = tempValue * 480; // normalize for slider
			timeStep[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeStep2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/blink" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 1;
			tempValue = tempValue * 480; // normalize for slider
			timeBlink[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeBlink2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/tempo" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 1;
			tempValue = tempValue * 480; // normalize for slider
			timePlayheadRandom[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timePlayheadRandom2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer2/invert" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 1;
			tempValue = tempValue * 480; // normalize for slider
			timeInvert[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeInvert2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		
		// OSC layer 3
		if ( m.getAddress() == "/layer3" ) { selectedLayer = 3; }
		if ( m.getAddress() == "/layer3/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 2;
			layerVisibility[layerIndex] = tempValue;
			if (layerVisibility[layerIndex] == -1) {
				QCstopOneMovie();
			}else{
				QCresumeCurrentMovie();
			}
		}
		if ( m.getAddress() == "/layer3/reverse" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 1) { // thumb down
				int layerIndex = 2;
				float x = videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].getSpeed();
				x = - (x) ;
				layerSpeed[layerIndex] = x;
				videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			}
		}
		if ( m.getAddress() == "/layer3/opacity" ) {
			int layerIndex = 2;
			tempValue = m.getArgAsFloat(0);
			layerOpacity[layerIndex] = tempValue;
			gui->update(kParameter_LayerOpacity3, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer3/speed" ) {
			int layerIndex = 2;
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 5.0; 
			layerSpeed[layerIndex] = tempValue;
			// sets new video speed
			videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			gui->update(kParameter_LayerSpeed3, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer3/step" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 2;
			tempValue = tempValue * 480; // normalize for slider
			timeStep[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeStep3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer3/blink" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 2;
			tempValue = tempValue * 480; // normalize for slider
			timeBlink[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeBlink3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer3/tempo" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 2;
			tempValue = tempValue * 480; // normalize for slider
			timePlayheadRandom[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timePlayheadRandom3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer3/invert" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 2;
			tempValue = tempValue * 480; // normalize for slider
			timeInvert[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeInvert3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		
		// OSC layer 4
		if ( m.getAddress() == "/layer4" ) { selectedLayer = 4; }
		if ( m.getAddress() == "/layer4/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 3;
			layerVisibility[layerIndex] = tempValue;
			if (layerVisibility[layerIndex] == -1) {
				QCstopOneMovie();
			}else{
				QCresumeCurrentMovie();
			}
		}
		if ( m.getAddress() == "/layer4/reverse" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 1) { // thumb down
				int layerIndex = 3;
				float x = videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].getSpeed();
				x = - (x) ;
				layerSpeed[layerIndex] = x;
				videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			}
		}
		if ( m.getAddress() == "/layer4/opacity" ) {
			int layerIndex = 3;
			tempValue = m.getArgAsFloat(0);
			layerOpacity[layerIndex] = tempValue;
			gui->update(kParameter_LayerOpacity4, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer4/speed" ) {
			int layerIndex = 3;
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 5.0; 
			layerSpeed[layerIndex] = tempValue;
			// sets new video speed
			videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setSpeed(layerSpeed[layerIndex]);
			gui->update(kParameter_LayerSpeed4, kofxGui_Set_Float, &tempValue, sizeof(tempValue));
		}
		if ( m.getAddress() == "/layer4/step" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 3;
			tempValue = tempValue * 480; // normalize for slider
			timeStep[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeStep4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer4/blink" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 3;
			tempValue = tempValue * 480; // normalize for slider
			timeBlink[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeBlink4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		if ( m.getAddress() == "/layer4/tempo" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 3;
			tempValue = tempValue * 480; // normalize for slider
			timePlayheadRandom[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timePlayheadRandom4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		if ( m.getAddress() == "/layer4/invert" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 3;
			tempValue = tempValue * 480; // normalize for slider
			timeInvert[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeInvert4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		
		// OSC layer 5
		if ( m.getAddress() == "/layer5" ) selectedLayer = 4;
		if ( m.getAddress() == "/layer5/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			layerVisibility[4] = int(tempValue);
			// livecam visibility
			livecam = !(livecam);
			if (layerVisibility[4] == 1) { lightPaintStretchXadd = 0; lightPaintStretchYadd = 0; } ; // resets feedback value xxxxx
			if ( (bWebcamInit == 0) and (layerVisibility[4] == 1) ) QCinitWebcam(); // initializes livecam
		}
		if ( m.getAddress() == "/layer5/lightPaint" ) {
			tempValue = m.getArgAsInt32(0);
			lightPaint[4] = int(tempValue);
		}
		if ( m.getAddress() == "/layer5/feedback" ) {
			tempValue = m.getArgAsInt32(0);
			lightPaintFeedback = tempValue;
		}
		if ( m.getAddress() == "/layer5/mirror" ) {
			tempValue = m.getArgAsInt32(0);
			layerFlip[4] = tempValue;
		}
		if ( m.getAddress() == "/layer5/red" ) { layerRed[4] = 1.0; layerGreen[4] = 0.0; layerBlue[4] = 0.0; }
		if ( m.getAddress() == "/layer5/green" ) { layerRed[4] = 0.0; layerGreen[4] = 1.0; layerBlue[4] = 0.0; }
		if ( m.getAddress() == "/layer5/blue" ) { layerRed[4] = 0.0; layerGreen[4] = 0.0; layerBlue[4] = 1.0; }
		if ( m.getAddress() == "/layer5/pink" ) { layerRed[4] = 1.0; layerGreen[4] = 0.0; layerBlue[4] = 1.0; }
		if ( m.getAddress() == "/layer5/yellow" ) { layerRed[4] = 1.0; layerGreen[4] = 1.0; layerBlue[4] = 0.0; }
		if ( m.getAddress() == "/layer5/white" ) { layerRed[4] = 1.0; layerGreen[4] = 1.0; layerBlue[4] = 1.0; }
		
		if ( m.getAddress() == "/layer5/comp1" ) {
			int tempValue = 0;
			layerBlend[4] = tempValue;
			gui->update(kParameter_Composite5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer5/comp2" ) {
			int tempValue = 1;
			layerBlend[4] = tempValue;
			gui->update(kParameter_Composite5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer5/comp3" ) {
			int tempValue = 2;
			layerBlend[4] = tempValue;
			gui->update(kParameter_Composite5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer5/clear" ) {
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 60.0;// normalize for slider
			lightPaintTime = tempValue * 1000;
			gui->update(kParameter_lightPaintTime, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		if ( m.getAddress() == "/layer5/color" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 4;
			tempValue = tempValue * 60.0;// normalize for slider
			timeColorRandom[layerIndex] = tempValue * 1000;
			gui->update(kParameter_timeColorRandom5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		if ( m.getAddress() == "/layer5/blink" ) {
			tempValue = m.getArgAsFloat(0);
			int layerIndex = 4;
			tempValue = tempValue * 480; // normalize for slider
			timeBlink[layerIndex] = int (60000/tempValue);
			gui->update(kParameter_timeBlink2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			
		}
		if ( m.getAddress() == "/layer5/feedbackXY" ) {
			tempValue = m.getArgAsFloat(0);
			tempValue = tempValue * 5.0;
			lightPaintStretchX = tempValue;
			gui->update(kParameter_lightPaintFeedbackX, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
			tempValue = m.getArgAsFloat(1);
			tempValue = tempValue * 5.0;
			lightPaintStretchY = tempValue;
			gui->update(kParameter_lightPaintFeedbackY, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
		}
		
		
		// OSC layer 6
		if ( m.getAddress() == "/layer6" ) { selectedLayer = 4; }
		if ( m.getAddress() == "/layer6/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 5;
			layerVisibility[layerIndex] = tempValue;

		}
		
		
		// OSC layer 7
		if ( m.getAddress() == "/layer7" ) { selectedLayer = 4; }
		if ( m.getAddress() == "/layer7/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 6;
			layerVisibility[layerIndex] = tempValue;
			
		}
		
		// OSC layer 8
		if ( m.getAddress() == "/layer8" ) { selectedLayer = 4; }
		if ( m.getAddress() == "/layer9/visibility" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) tempValue = -1;
			int layerIndex = 7;
			layerVisibility[layerIndex] = tempValue;
			
		}
		
		// OSC movs page
		if ( m.getAddress() == "/mov/movs/1/1" ) QCclickChangeMovie(0); 
		if ( m.getAddress() == "/mov/movs/2/1" ) QCclickChangeMovie(1); 
		if ( m.getAddress() == "/mov/movs/3/1" ) QCclickChangeMovie(2); 
		if ( m.getAddress() == "/mov/movs/4/1" ) QCclickChangeMovie(3); 
		if ( m.getAddress() == "/mov/movs/5/1" ) QCclickChangeMovie(4); 
		if ( m.getAddress() == "/mov/movs/1/2" ) QCclickChangeMovie(5); 
		if ( m.getAddress() == "/mov/movs/2/2" ) QCclickChangeMovie(6); 
		if ( m.getAddress() == "/mov/movs/3/2" ) QCclickChangeMovie(7); 
		if ( m.getAddress() == "/mov/movs/4/2" ) QCclickChangeMovie(8); 
		if ( m.getAddress() == "/mov/movs/5/2" ) QCclickChangeMovie(9); 
		if ( m.getAddress() == "/mov/movs/1/3" ) QCclickChangeMovie(10); 
		if ( m.getAddress() == "/mov/movs/2/3" ) QCclickChangeMovie(11); 
		if ( m.getAddress() == "/mov/movs/3/3" ) QCclickChangeMovie(12); 
		if ( m.getAddress() == "/mov/movs/4/3" ) QCclickChangeMovie(13); 
		if ( m.getAddress() == "/mov/movs/5/3" ) QCclickChangeMovie(14); 
		if ( m.getAddress() == "/mov/movs/1/4" ) QCclickChangeMovie(15); 
		if ( m.getAddress() == "/mov/movs/2/4" ) QCclickChangeMovie(16); 
		if ( m.getAddress() == "/mov/movs/3/4" ) QCclickChangeMovie(17); 
		if ( m.getAddress() == "/mov/movs/4/4" ) QCclickChangeMovie(18); 
		if ( m.getAddress() == "/mov/movs/5/4" ) QCclickChangeMovie(19); 
		if ( m.getAddress() == "/mov/movs/1/5" ) QCclickChangeMovie(20); 
		if ( m.getAddress() == "/mov/movs/2/5" ) QCclickChangeMovie(21); 
		if ( m.getAddress() == "/mov/movs/3/5" ) QCclickChangeMovie(22); 
		if ( m.getAddress() == "/mov/movs/4/5" ) QCclickChangeMovie(23); 
		if ( m.getAddress() == "/mov/movs/5/5" ) QCclickChangeMovie(24); 
		if ( m.getAddress() == "/mov/movs/1/6" ) QCclickChangeMovie(25); 
		if ( m.getAddress() == "/mov/movs/2/6" ) QCclickChangeMovie(26); 
		if ( m.getAddress() == "/mov/movs/3/6" ) QCclickChangeMovie(27); 
		if ( m.getAddress() == "/mov/movs/4/6" ) QCclickChangeMovie(28); 
		if ( m.getAddress() == "/mov/movs/5/6" ) QCclickChangeMovie(29); 
		if ( m.getAddress() == "/mov/movs/1/7" ) QCclickChangeMovie(30); 
		if ( m.getAddress() == "/mov/movs/2/7" ) QCclickChangeMovie(31); 
		if ( m.getAddress() == "/mov/movs/3/7" ) QCclickChangeMovie(32); 
		if ( m.getAddress() == "/mov/movs/4/7" ) QCclickChangeMovie(33); 
		if ( m.getAddress() == "/mov/movs/5/7" ) QCclickChangeMovie(34); 
		if ( m.getAddress() == "/mov/movs/1/8" ) QCclickChangeMovie(35); 
		if ( m.getAddress() == "/mov/movs/2/8" ) QCclickChangeMovie(36); 
		if ( m.getAddress() == "/mov/movs/3/8" ) QCclickChangeMovie(37); 
		if ( m.getAddress() == "/mov/movs/4/8" ) QCclickChangeMovie(38); 
		if ( m.getAddress() == "/mov/movs/5/8" ) QCclickChangeMovie(39); 
		if ( m.getAddress() == "/mov/movs/1/9" ) QCclickChangeMovie(40); 
		if ( m.getAddress() == "/mov/movs/2/9" ) QCclickChangeMovie(41); 
		if ( m.getAddress() == "/mov/movs/3/9" ) QCclickChangeMovie(42); 
		if ( m.getAddress() == "/mov/movs/4/9" ) QCclickChangeMovie(43); 
		if ( m.getAddress() == "/mov/movs/5/9" ) QCclickChangeMovie(44); 
		if ( m.getAddress() == "/mov/random" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 1) { // thumb down
				QCclickChangeMovie(int(ofRandom(0.0,44.0)));
			}
		}
			if ( m.getAddress() == "/mov/randomDir" ) {
			tempValue = m.getArgAsInt32(0);
			if (tempValue == 0) { // thumb up
			currentFolderNum = int(ofRandom(0,nFolders));
			QCchangeFolderStepPrepare();
			videoLoading = 1;
			}
		}
			//break;
		
	} // end while OSC - touchOSC

			
	///////////////////////////////
	//
	//  FFT2 update
	//
	//////////////////////////////
			
	//			ofSoundUpdate();
	//			
	//			fftSmoothed = ofSoundGetSpectrum(128);
	//			
	//			float * val = ofSoundGetSpectrum(nBandsToGet); // request 128 values
	//			for (int i=0; i < nBandsToGet; i++) {
	//				fftSmoothed[i] *= 0.096f;
	//				if (fftSmoothed[i] < val[i]) fftSmoothed[i] = val[i];
	//			}

            

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  video step loading update
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if (videoLoading == 1) QCchangeFolderStep();
    if (videoLoadingNewPage == 1) QCchangePageStep();



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  video saver update
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #ifdef TARGET_LINUX
        // nothing
    #else // Mac and Windows
        if (bRecording == true){
            //texScreen.loadScreenData(interfaceSizeX,0,screenSizeX,screenSizeY);
            imageToSave.grabScreen(interfaceSizeX,0,screenSizeX , screenSizeY);
            //saver.addFrame(imageToSave.getPixels(), 1.0f / 30.0f);
            saver.addFrame(imageToSave.getPixels(), 1.0f / ofGetFrameRate() );
        }
    #endif
	
	
} // end update



//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------



void testApp::draw(){

	// scale
	 //glPushMatrix();
	 //glScalef(interfaceSizeX/1024.0, interfaceSizeY/768.0, 1);	
	
	
	
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // interfaces initial draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    switch (redrawInterface) { // draws interface
        case 0:
            // do not redraw
            break;
        case 1: // initial draw main interface
			switch (languageCode[0]) {
				case 'P': gui->buildFromXml("interface/gui_QC_Port.xml"); break;
				case 'E': gui->buildFromXml("interface/gui_QC_Eng.xml"); break;
			} // end switch languageCode
            QCresetTimers();
			interfaceBackground.draw(0,0);
            tempValue = masterFader * 100.0;
			gui->update(kParameter_masterFader, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // share masterFader value
            redrawInterface = 0;
            break;
		}



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  interface draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//                              ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  main module interface draw  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//                              ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  interface draw simple - main module
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	glDisable(GL_BLEND); ofSetColor(255,255,255);
	interfaceBackground.draw(0,0);
	// draw icons
	if (lightPaint[4] == true) iconLightPaintOn.draw(896,9); else iconLightPaintOff.draw(896,9);
	if (lightPaintFeedback == true) iconLightPaintFeedOn.draw(920,9); else iconLightPaintFeedOff.draw(920,9);
	if (layerFlip[4] == true) iconLightPaintMirrorOn.draw(944,9); else iconLightPaintMirrorOff.draw(944,9);
	glEnable(GL_BLEND);
	switch (selectedLayer) {
		case 1: case 2: case 3: case 4:
			layerOutlineA.draw(366,(3+((selectedLayer-1)*192))); // draws outline layers 1 to 4
			break;
		case 5: case 6: case 7: case 8:
			layerOutlineB.draw(808,(3+((selectedLayer-5)*192))); // draws outline layers 4 to 8
			break;
	} // end switch selectedLayer
	glDisable(GL_BLEND); // turn off alpha blending

	QClayerThumbs(); // video thumbs on layer tabs



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  videos visibility interface draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	for (int x = 0; x < 4; x++) { // visibility checkmark layers 1 to 4
		if (layerVisibility[x] == -1) { // layer off
			ofSetColor(255,0,0); // red
		}
		else { // layer on
			ofSetColor(0,255,0); //green
		}
		int verticalPosition = 16 + (192 * x); // interface cell vertical size = 192
		ofFill(); ofCircle(380,verticalPosition,8); // horizontal position hard coded
	} // end for
	for (int x = 4; x < 8; x++) { // visibility checkmark layers 5 to 8
		if (layerVisibility[x] == -1) { // layer off
			ofSetColor(255,0,0); // red
		}
		else { // layer on
			ofSetColor(0,255,0); //green
		}
		int verticalPosition = 16 + (192 * (x-4)); // interface cell vertical size = 192
		ofFill(); ofCircle(825,verticalPosition,8); // horizontal position hard coded
	} // end for



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  text panel draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	ofSetColor(54,54,54);
	if ( (textInputActive == 1) and (ofRandom(0.0,4.0)>3.0) ) ofSetColor(0,255,0);
	ofRect(815,728,200,25); // clears text input area
	ofSetColor(255,255,255);
	//cout << textInput;
	switch (currentFont) {
		case 1: fontArialBlack18.drawString(textInput, 817, 748); break;
		case 2: fontAsimov18.drawString(textInput, 817, 748); break;
		case 3: fontGreek18.drawString(textInput, 817, 748); break;
		case 4: fontGoodtime18.drawString(textInput, 817, 748); break;
		case 5: fontSteppes18.drawString(textInput, 817, 748); break;
		case 6: fontTimes18.drawString(textInput, 817, 748); break;
	} // end switch font

	
	
	///////////////////////
	//
	//  FFT1 panel draw
	//
	///////////////////////
	
//			static int index = 0;
//			avg_power = 0.0f;	
//			
//			if(index < 80)
//				index += 1;
//			else
//				index = 0;
//			/* do the FFT	*/
//			myfft.powerSpectrum(0,(int)BUFFER_SIZE/2, left,BUFFER_SIZE,&magnitude[0],&phase[0],&power[0],&avg_power);
//			/* start from 1 because mag[0] = DC component and discard the upper half of the buffer */
//			for(int j=1; j < BUFFER_SIZE/2; j++) freq[index][j] = magnitude[j];		
//			glDisable(GL_BLEND); ofSetColor(180, 180, 180); // green
//			/* draw the FFT */
//			for (int i = 1; i < (int)(BUFFER_SIZE/2); i++){
//				//ofLine(200+(i*8),400,200+(i*8),400-magnitude[i]*10.0f);
//				ofLine(30+i,180,30+i,180-magnitude[i]*1.5f);
//				//ofLine(11+(i*4),180,11+(i*4),180-magnitude[i]*2.0f);
//				//ofLine(12+(i*4),180,12+(i*4),180-magnitude[i]*2.0f);
//				//ofLine(13+(i*4),180,13+(i*4),180-magnitude[i]*2.0f);
//				//ofRect(10+(i*4), 180, 4, 180-magnitude[i]*4.0f);
//				// if (i == 1) layerOpacity[0] = float(magnitude[1]/20.0); FFT test
//				}
//			// end FFT draw
//			
//			//layerOpacity[0] = freq[index][1];
	
	
	///////////////////////
	//
	//  FFT2 panel draw
	//
	///////////////////////
	
	
//			float width = (float)(5*128) / nBandsToGet;
//			for (int i =0; i < nBandsToGet; i++) {
//				//ofRect(100+i*width,ofGetHeight()-100,width,-(fftSmoothed[i]*200));
//				ofRect(100+i*width,180,width,-(fftSmoothed[i]*200));
//			}
	
		

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                        //////////////////////////////////////////////////////////////////
    //  interface draw                        //////////////////////////////////////////////////////////////////
    //                                        //////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////


	QCtimeDisplay();

	if (browsingClips == 1) {
		// if (videoLoading == 0)
		QCvideoThumbs(); // video thumbs at bin
		//
		// videos paging icons draw
		//
		ofSetColor(255,255,255);
		iconPageNotActive.draw (9,715); // icon clips page 1
		if (nVideos > 45) { iconPageNotActive.draw (39,715); } // icon clips page 2
		if (nVideos > 90) { iconPageNotActive.draw (69,715); } // icon clips page 3
		if (nVideos > 135) { iconPageNotActive.draw (99,715); } // icon clips page 4
		if (nVideos > 180) { iconPageNotActive.draw (129,715); } // icon clips page 5
		if (nVideos > 225) { iconPageNotActive.draw (159,715); } // icon clips page 6
		if (nVideos > 270) { iconPageNotActive.draw (189,715); } // icon clips page 7
		if (nVideos > 315) { iconPageNotActive.draw (219,715); } // icon clips page 8
		if (nVideos > 360) { iconPageNotActive.draw (249,715); } // icon clips page 9
		if (nVideos > 405) { iconPageNotActive.draw (279,715); } // icon clips page 10

		iconPageActive.draw(9+((videoThumbsPage-1)*30),715); // icon active page

		
		//
		// current directory name draw
		//
		
		string tempString = DirFolders.getPath(currentFolderNum);
		
		//string tempString = ofToDataPath(DirFolders.getPath(currentFolderNum),1);
		//ofToDataPath(tempString,1);
		
		tempString.erase(0,eraseChars);
		ofSetColor(180,180,180); // light grey text
		fontVerdana8.drawString(tempString, 60, 706);

	} // end if browsingClips == 1



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  clip preview draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if ( (browsingClips == 1) and (videoLoading == 0) ) { // video layers 1 to 4
		for (int line = 0; line < 9; line++) { // video thumbs - for by lines
			if (mouseY > (thumbsVertPos+(54*line)) and mouseY < (thumbsVertPos+(54*(line+1))) ) { // if by lines
				for(int column = 0; column < 5; column++){ // video thumbs by columns
					if ( mouseX > (thumbsHorPos+(70*column)) and mouseX < (thumbsHorPos+(70*(column+1))) ) { // if by columns
						tempValue = ((line*5) + column) + ((videoThumbsPage-1)*45);
						if (tempValue < nVideos){ // valid video thumb
							videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].play();
							videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].setVolume(0.0);
							videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].setSpeed(1.0);
							//videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].idleMovie();
							// Linux
							#ifdef TARGET_LINUX
								if (videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].getPosition() > 0.975) { videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].setPosition(0.001); } // reset position
							#endif
							// draw thumb
							glDisable(GL_BLEND); ofSetColor(255,255,255);
							videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].draw(14,61,160,120);
							// draw duration
							int tempValue2 = videoThumbs[int(tempValue - ((videoThumbsPage-1)*45))].getDuration();
							int minutes = tempValue2 / 60; int seconds = tempValue2 % 60;
							if (seconds < 10){
								tempString = ofToString (minutes) + ":0" + ofToString (seconds,0);
							} else {
								tempString = ofToString (minutes) + ":" + ofToString (seconds,0);
							}
							if (minutes < 10){
								ofSetColor(0,0,0); fontVerdana8.drawString(tempString, 146, 179); // time shadow
								ofSetColor(0,255,0); fontVerdana8.drawString(tempString, 145, 178); // time
							} else {
								ofSetColor(0,0,0); fontVerdana8.drawString(tempString, 138, 179); // time shadow
								ofSetColor(0,255,0); fontVerdana8.drawString(tempString, 137, 178); // time
							}
						} // end if tempValue < nVideos
					} // end if by columns
				} // end for by columns
			} // end if lines
		} // end for by lines
	} // end if video layers 1 to 4



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  directory list draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (browsingDirs == 1) QClistDirsDraw();



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  audio dirs list draw xxxxx
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (browsingAudioDirs == 1) QClistDirsAudioDraw();



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  audio clips list draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (browsingAudioClips == 1) QClistClipsAudioDraw();



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  framerate interface draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	tempValueInt = ofGetFrameRate();

	// zzzzz
	
	//if (currentTime > previousTimeFpsAverage + 600) {
		
		
		
		// draw average
		
		
		//
		//frameCountFpsAverage = 
		
		
		
		
	//}
	
	//string fpsStr = string(ofGetLastFrameTime(),0);
	
	// sets fps color based on performance
	if (tempValueInt < 12) ofSetColor(255,0,0); // red
	if ( (tempValueInt > 11) and (tempValueInt < 30) ) ofSetColor(200,128,0); // orange
	if ( (tempValueInt >= 30) and (tempValueInt < 45) ) ofSetColor(0,255,0); // green
	if (tempValueInt >45) ofSetColor(0,230,230); // light blue

	
	//ofSetColor(0,255,0);
	string fpsStr = ofToString(tempValueInt, 0);
	fontVerdana8.drawString(fpsStr, 8, 764);

	
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  screen size interface draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	ofSetColor(200,200,200);
	//sprintf (fpsStr," %d",fpsStr);
	//char fpsStr [32];
	fpsStr = "FACE:"+ofToString(interfaceSizeX)+"x"+ofToString(interfaceSizeY)+" OUT:" + ofToString(screenSizeX)+"x"+ofToString(screenSizeY);
	fontAutomat6.drawString(fpsStr, 100, 764);

	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  loading text draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if ( (videoLoading == 1) or (videoLoadStep == 1) ) { // loading draw
		fpsStr = "";
		fpsStr = fpsStr + "       loading clip " + ofToString(videoLoadStep) + " of " + ofToString(nVideosLimited) + "."; //+ str(videoLoadStep);
		ofSetColor(180,180,180); // light grey text
		fontAutomat6.drawString(fpsStr, 85, 750);
	}



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////
    ////  output draw
    ////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//                           ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//  output draw              ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//                           ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	// video layer 1 draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (layerVisibility[0] == 1) {
		videos[0+(layerSequenceItem[0]*4)][currentVideo[0+(layerSequenceItem[0]*4)]].play();
		if (layerOpacity[0] == 1.0) glDisable(GL_BLEND); // full opacity
		else glEnable(GL_BLEND); glBlendFunc(GL_SRC0_ALPHA,GL_ZERO); // has transparency %
		//glColor4f(layerRed[0],layerGreen[0],layerBlue[0],layerOpacity[0]); // layer color and alpha
		glColor4f(layerRed[0],layerGreen[0],layerBlue[0],layerOpacity[0]); // layer color and alpha
		if (layerInvert[0] == -1){ // if not invert, draw normal video
			videos[0+(layerSequenceItem[0]*4)][currentVideo[0+(layerSequenceItem[0]*4)]].draw(interfaceSizeX,0,screenSizeX,screenSizeY); // draw the video
		}
		else { // if invert
			int w = videos[layerSequenceItem[0]*4][currentVideo[(layerSequenceItem[0]*4)]].width;
			int h = videos[layerSequenceItem[0]*4][currentVideo[(layerSequenceItem[0]*4)]].height;
			int totalPixels = w*h*3;
			videoInvert1B = new unsigned char[w*h*3];
			unsigned char * pixels = videos[layerSequenceItem[0]*4][currentVideo[(layerSequenceItem[0]*4)]].getPixels();
			for (int i = 0; i < totalPixels; i++) {videoInvert1B[i] = 255 - pixels[i];}
			videoInvert1A.allocate(w,h, GL_RGB);
			videoInvert1A.loadData(videoInvert1B, w, h, GL_RGB);
			videoInvert1A.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
		} // end if invert
		if (previewMonitor==1) { // preview monitor
			if (layerInvert[0] == -1) { // if not invert, draw normal video preview
				videos[0+(layerSequenceItem[0]*4)][currentVideo[0+(layerSequenceItem[0]*4)]].draw(191,61,160,120); // draw video preview
			}
			else { // invert preview
				videoInvert1A.draw(191,61,160,120);
			} // end if preview
			int verticalPosition = 10 + (192 * 0); glDisable(GL_BLEND); ofSetColor(255,255,255); // white
		}

		// ofxGui update playhead slider layer 1
		tempValue = videos[0+(layerSequenceItem[0]*4)][currentVideo[0+(layerSequenceItem[0]*4)]].getPosition();
		gui->update(kParameter_LayerPlayhead1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw playhead interface
	}



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	// blend and draw of layers 2 to 4
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	for (int x = 1; x < 4; x++) {
		if (layerVisibility[x]==1) {
			switch (layerBlend[x]) {
				case 0: glEnable(GL_BLEND); glBlendFunc(GL_SRC0_ALPHA, GL_ONE); break;
				case 1: glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
				case 2: glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
				case 3: glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR); break;
				case 4: glEnable(GL_BLEND); glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
				case 5: glEnable(GL_BLEND); glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR); break;
				case 6: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
			} //end switch
			videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].play();
			glColor4f(layerRed[x],layerGreen[x],layerBlue[x],layerOpacity[x]); // layer color and alpha
			// video draw
			if (layerInvert[x] == -1) { // if not invert, draw normal video
				videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].draw(interfaceSizeX,0,screenSizeX,screenSizeY); // draw the video
			}
			else { // if invert
				int w = videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].width;
				int h = videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].height;
				int totalPixels = w*h*3;
				videoInvert1B = new unsigned char[w*h*3];
				unsigned char * pixels = videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].getPixels();
				for (int i = 0; i < totalPixels; i++) { videoInvert1B[i] = 255 - pixels[i]; }
				videoInvert1A.allocate(w,h, GL_RGB);
				videoInvert1A.loadData(videoInvert1B, w, h, GL_RGB);
				videoInvert1A.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
			}
			// preview monitor
			if (previewMonitor == 1) {
				if (layerInvert[x] == -1) { // if not invert, draw normal video preview
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].draw(191,61,160,120); // draw video preview
				}
				else {
					videoInvert1A.draw(191,61,160,120);
				} // end if invert
				glDisable(GL_BLEND); int verticalPosition = 10 + (192 * x); ofSetColor(255,255,255); // white
				//videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].draw(395+(layerSequenceItem[x]*70),verticalPosition,64,48); // draws video layer thumb
			} // end if preview
			glDisable(GL_BLEND);
			tempValue = videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].getPosition();
			switch (x) { // ofxGui update playhead slider layers 2 to 4
				case 1: // layer 2
					gui->update(kParameter_LayerPlayhead2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
				case 2: // layer 3
					gui->update(kParameter_LayerPlayhead3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
				case 3: // layer 4
					gui->update(kParameter_LayerPlayhead4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
			} // end switch playhead sliders 2 to 4
		} //end if layer visibility
	} //end for



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  livecam draw
	//
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	if (layerVisibility[4] == 1) { // layer 5, index 4
		glEnable(GL_BLEND);
		
		if (lightPaint[4] == 1) {
			//
			// livecam light paint draw
			//
			
			//
			// lightpaint redraws previous frame
			//
			
			// fade code goes here
			// glEnable(GL_BLEND);
			// glBlendFunc(GL_SRC0_ALPHA, GL_ONE);
			// glColor4f(1.0,1.0,1.0,0.998);
			
			// not fade
			glDisable(GL_BLEND);
			glColor3f(1.0,1.0,1.0);
			
			texScreen.draw(interfaceSizeX,0,(screenSizeX+lightPaintStretchXadd),(screenSizeY+lightPaintStretchYadd));
			
			if (lightPaintFeedback == 1) {
				lightPaintStretchXadd = lightPaintStretchXadd + (lightPaintStretchX * lightPaintStretchSpeed );
				lightPaintStretchYadd = lightPaintStretchYadd + (lightPaintStretchY * lightPaintStretchSpeed );
			}
			
			if (previewMonitor == 1) texScreen.draw(191,61,160,120);
			
			//
			// light paint draws current frame
			//
			
			if (layerFlip[4] == 1) {
				glEnable(GL_BLEND);
				switch (layerBlend[4]) {
					case 0: glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
					case 1: glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
					case 2: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
				} //end switch blend
				glColor3f(layerRed[4],layerGreen[4],layerBlue[4]); // layer color and alpha
				
				// flip
				ofPushMatrix();
				ofScale(-1, 1, 1);
				vidGrabber.draw(-1024-screenSizeX,0,screenSizeX,screenSizeY);
				ofPopMatrix();
				
				//colorImg.setFromPixels(vidGrabber.getPixels(), vidGrabber.width, vidGrabber.height); // setup openCV
				//colorImg.mirror(0,1); // openCV flip image
				//colorImg.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
				//if (previewMonitor == 1) colorImg.draw(191,61,160,120); // preview
				
			} else { // not layerFlip[4]
				glEnable(GL_BLEND);
				switch (layerBlend[4]) {
					case 0: glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
					case 1: glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
					case 2: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
				} //end switch blend
				glColor3f(layerRed[4],layerGreen[4],layerBlue[4]); // layer color and alpha
				
				if (layerInvert[4] == 1) { // invert color
					// flip
					ofPushMatrix();
					ofScale(-1, 1, 1);
					videoTexture.draw(-1024-screenSizeX,0,screenSizeX,screenSizeY);
					ofPopMatrix();
					//if (previewMonitor == 1) videoTexture.draw(191,61,160,120);
				} else { // not invert
					vidGrabber.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
				} // end if invert or not
			} // end if light paint flipped or not
			
		} else {
			//
			// livecam normal draw (not live paint)
			//
			
			
			if (layerFlip[4] == 1) {
				// flip
				glEnable(GL_BLEND);
				switch (layerBlend[4]) {
					case 0: glBlendFunc(GL_SRC0_ALPHA, GL_ONE); break;
					case 1: glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
					case 2: glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
					case 3: glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR); break;
					case 4: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
					case 5: glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); break;
					case 6: glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
				} //end switch blend
				glColor4f(layerRed[4],layerGreen[4],layerBlue[4],layerOpacity[4]); // layer color and alpha
				
				// flip
				ofPushMatrix();
				ofScale(-1, 1, 1);
				vidGrabber.draw(-1024-screenSizeX,0,screenSizeX,screenSizeY);
				ofPopMatrix();
				
				//if (previewMonitor == 1) colorImg.draw(191,61,160,120); // preview
				
			} // end if layerFlip[4]
			
			
			if (layerFlip[4] == 0) { // not flip draw
				glEnable(GL_BLEND);
				switch (layerBlend[4]) {
					case 0: glBlendFunc(GL_SRC0_ALPHA, GL_ONE); break;
					case 1: glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
					case 2: glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
					case 3: glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR); break;
					case 4: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
					case 5: glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE); break;
					case 6: glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
				} //end switch blend
				glColor4f(layerRed[4],layerGreen[4],layerBlue[4],layerOpacity[4]);;
				
				if (layerInvert[4] == 1) {
					videoTexture.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
					if (previewMonitor == 1) videoTexture.draw(191,61,160,120);
				} else {
					vidGrabber.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
					if (previewMonitor == 1) vidGrabber.draw(191,61,160,120);
				}
				
				//vidGrabber.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
				
			} // end if not flip draw
			
			
		} // end if light paint or not
		
		glDisable(GL_BLEND);
		
	} // end if live cam
	

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  3D draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (layerVisibility[5] == 1) { // layer 6, index 5 - 3D
		//glLoadIdentity();
		glTranslatef(1024+(screenSizeX/2),screenSizeY/2,0); //draw in middle of the screen
		//tumble according to mouse
		//glRotatef(mouseY,1,0,0);
		//glRotatef(mouseX,0,1,0);
		switch (rot3DAxis) {
			case 0: glRotatef(rot3D,1,0,0); break;
			case 1: glRotatef(rot3D,0,1,0); break;
			case 2: glRotatef(rot3D,0,0,1); break;
		}
		float s = min(screenSizeX,screenSizeY)*0.3*size3D;
		glScalef(s,s,s);
		glEnable(GL_BLEND); glBlendFunc(GL_SRC0_ALPHA, GL_ONE);
		glColor4f(layerRed[5],layerGreen[5],layerBlue[5],layerOpacity[5]); // layer color and alpha
		//glViewport(1024, 0, 800, 600);
		object3D.draw();
		glDisable(GL_BLEND);
		ofSetupScreen();
	} // end if layer 6 - 3D



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  still image draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	// image thumb draw, regardless of image layer visibility
	glEnable(GL_BLEND); glBlendFunc(GL_SRC0_ALPHA, GL_ONE);
	glColor4f(layerRed[6],layerGreen[6],layerBlue[6],layerOpacity[6]); // layer color
	images[currentImage].draw(823,414,64,48); // draws image layer thumb
		
	if (layerVisibility[6] == 1) { // layer 7, index 6 = image layer
		if (nImages > 0) {
			switch (layerBlend[6]) {
				case 0: glBlendFunc(GL_SRC0_ALPHA, GL_ONE); break;
				case 1: glBlendFunc(GL_SRC_COLOR, GL_ONE); break;
				case 2: glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); break;
				case 3: glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_DST_COLOR); break;
				case 4: glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA); break;
				case 5: glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR); break;
				case 6: glBlendFunc(GL_SRC_ALPHA, GL_ONE); break;
			} //end switch
			glColor4f(layerRed[6],layerGreen[6],layerBlue[6],layerOpacity[6]); // layer color and alpha
			images[currentImage].draw(interfaceSizeX,0,screenSizeX,screenSizeY);
			// preview monitor
			if (previewMonitor == 1){
				if (layerInvert[6] == -1){ // if not invert, draw normal image preview
					images[currentImage].draw(191,61,160,120); // draw image preview
				}
				else {
					int w = images[currentImage].width;
					int h = images[currentImage].height;
					int totalPixels = w*h*3;
					imageInvert1B = new unsigned char[w*h*3];
					unsigned char * pixels = images[currentImage].getPixels();
					for (int i = 0; i < totalPixels; i++) {imageInvert1B[i] = 255 - pixels[i];}
					imageInvert1A.allocate(w,h, GL_RGB);
					imageInvert1A.loadData(imageInvert1B, w, h, GL_RGB);
					imageInvert1A.draw(interfaceSizeX,0,screenSizeX,screenSizeY); // output
					imageInvert1A.draw(191,61,160,120); // preview
				} // end if invert
			} // end if preview
		}
	}



	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	//  text draw
	//
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (layerVisibility[7] == 1) {
		glEnable(GL_BLEND);
		glColor4f(layerRed[7],layerGreen[7],layerBlue[7],(layerOpacity[7])); // layer color and alpha        cout << layerRed[7];
		switch (currentFont){
			case 1: fontArialBlack64.drawString(textInput, 1024+textHorPos, textVertPos); break;
			case 2: fontAsimov64.drawString(textInput, 1024+textHorPos, textVertPos); break;
			case 3: fontGreek64.drawString(textInput, 1024+textHorPos, textVertPos); break;
			case 4: fontGoodtime64.drawString(textInput, 1024+textHorPos, textVertPos); break;
			case 5: fontSteppes64.drawString(textInput, 1024+textHorPos, textVertPos); break;
			case 6: fontTimes64.drawString(textInput, 1024+textHorPos, textVertPos); break;
		} // end switch font
	}
	// break;




	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // recording options draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #ifdef TARGET_LINUX
        // nothing
    #else // Mac and Windows
        //if (saver.bAmSetupForRecording()){
            if (bRecording){
                ofSetColor(0x00ff00);
                sprintf(helpText, "Recording Rec%s.mov - M key stops.", fileNameSufix);
                fontVerdana8.drawString(helpText, 8, 750);
            } else {
                ofSetColor(255,255,255);
                sprintf(helpText, "Press N to record.");
                fontVerdana8.drawString(helpText, 8, 750);
            } // end if bRecording
        // } // end if saver.bAmSetupForRecording
    #endif



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // ofxGui draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	glDisable(GL_BLEND);
    gui->draw();

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    // splash screen draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    glDisable(GL_BLEND);
    if (ofGetFrameNum() < 84) {
        splashScreen.draw(0,0,1024,768); // draws splashscreen
    }
    if (ofGetFrameNum() == 60) { // stops drawing splashscreen
        redrawInterface = 1;
        QCresetTimers();
    }



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  preview full draw
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if (previewFull == 1) {
        texScreen.loadScreenData(interfaceSizeX,0,screenSizeX,screenSizeY);
        glDisable(GL_BLEND);
        texScreen.draw(0,0,interfaceSizeX,interfaceSizeY);
    }



    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  help draw over gui
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if (redrawInterface == 4) {
		switch (languageCode[0]) {
			case 'P': 
				tempString = ofToString(languageCode[0], 0) + "\n\nQuase-Cinema 2 - atalhos\n\n"+
				"1 a 4: seleciona os canais de video de 1 a 4.\n"+
				"5: seleciona o canal de camera ao vivo (canal 5).\n"+
				"6: seleciona o canal de imagem 3D (canal 6).\n"+
				"7: seleciona o canal de imagem parada (canal 7).\n"+
				"8: seleciona o canal de texto (canal 8).\n"+
				"seta p/ baixo: seleciona canal seguinte.\n"+
				"seta p/ cima: seleciona canal anterior.\n"+
				
				"\n"+
				"delete (backspace): liga/desliga a visibilidade do canal selecionado.\n"+
				"barra de espaco: inverte a direcao de playback do canal de video selecionado (1 a 4).\n"+
				"seta p/ esquerda: diminui a velocidade de execucao do canal de video selecionado.\n"+
				"seta p/ direita: aumenta a velocidade de execucao do canal de video selecionado.\n"+
				"r: muda posicao (tempo) do video do canal selecionado.\n"+
				"shift R: muda randomicamente video (a partir da pasta aberta).\n"+
				
				"\n"+
				"d: muda diretorio de videos (pasta no disco rigido).\n"+
				"shift D: muda diretorio de videos aleatoriamente.\n"+
				
				"\n"+
				"i: inverte as cores do canal selecionado.\n"+
				"t: aciona digitacao de texto (return/enter para finalizar digitacao).\n"+
				
				"\n"+
				"s: salva uma imagem da composicao no disco rigido como arquivo .bmp\n"+
				"n: inicia gravacao de arquivo de video (como arquivo Quicktime).\n"+
				"m: finaliza gravacao de arquivo de video.\n"+
				
				"\n"+
				"Teclas de configuracao:\n"+
				"F1: diminui a resolucao da interface.\n"+
				"F2: aument	a a resolucao da interface.\n"+
				"F3: diminui a resolucao da saida de video.\n"+
				"F4: aumenta a resolucao da saida de video.\n"+
				"F11: muda lingua da interface.\n"+
				"F12: mostra tela de ajuda.\n"+
				"f: alterna entre o modo de tela cheia e modo de janela.\n"+
				"v: aciona a janela de configuracao da camera ao vivo (acionar o modo de janela (f) primeiro).\n"+
				"shift P: toggles full screen preview on / off.\n"+
				
				"\n"+
				"Feito com openFrameworks.\n"+
				
				"\n"+
				"Alexandre Rangel\n"+
				"www.quasecinema.org\n";
				
				break;
			case 'E': 
				tempString = ofToString(languageCode[0], 0) + "\n\nQuase-Cinema 2 shortcuts\n\n"+
				"1 to 4: selects channels 1 to 4.\n"+
				"5: selects the live camera channel.\n"+
				"6: selects the 3D image channel.\n"+
				"7: selects the still image channel.\n"+
				"8: selects the text channel.\n"+
				"down arrow: selects next channel.\n"+
				"up arrow: selects previous channel.\n"+
				
				"\n"+
				"delete (backspace) Ð toggles the visibility of the selected channel.\n"+
				"space bar: inverts the direction of the playback of the selected video channel (1 to 4).\n"+
				"left arrow: slows down the speed of the selected video channel (1 to 4).\n"+
				"right arrow: speeds up the playback of the selected video channel (1 to 4).\n"+
				"r: changes the position (time) of the video on the selected channel.\n"+
				"shift R: changes video randomly (picking from the open folder).\n"+
				
				"\n"+
				"d: changes video directory (folder on hard disk).\n"
				"shift D: changes video directory randomly.\n"
				
				"\n"+
				"i: inverts the colors of the selected video.\n"+
				"t: starts the input of text (hit return/enter to finish typing).\n"+
				
				"\n"+
				"s: saves the output frame on the hard disk as a .BMP file.\n"+
				"n: starts the recording of the performance (as a Quicktime file).\n"+
				"m: finishes recording of movie file.\n"+
				
				"\n"+
				"\nSetup keys:\n"+
				"F1: decreases interface resolution.\n"+
				"F2: increases interface resolution.\n"+
				"F3: decreases output resolution.\n"+
				"F4: increases output resolution.\n"+
				"F11: switches interface language.\n"+
				"F12: shows help screen.\n"+
				"f: toggles between windowed and full screen modes.\n"+
				"v: opens the live video configuration screen (enter window mode (f) first).\n"+
				"shift P: toggles full screen preview on/off.\n"+
				
				"\n"+
				"Made with openFrameworks.\n"+
				
				"\n"+
				"Alexandre Rangel\n"+
				"www.quasecinema.org.\n";
				break;
		} // end switch languageCode
		glEnable(GL_BLEND); glColor4f(1.0,1.0,1.0,0.7);
		ofFill(); ofRect(0, 0, interfaceSizeX, interfaceSizeY);
		glDisable(GL_BLEND); glColor4f(0.1,0.1,0.1,1.0);
		fontVerdana10.drawString(tempString, 20, -10); // help text
		
	} // end if redrawInterface == 4


    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    //  master fader
    //
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if (masterFader > 0.0) {
        glEnable(GL_BLEND); glColor4f(0.0,0.0,0.0,masterFader); // layer color and alpha
        glBlendFunc(GL_SRC0_ALPHA,GL_ZERO);
        ofFill(); ofRect(interfaceSizeX,0,screenSizeX,screenSizeY); ofRect(191,61,160,120); // fader black rectangle
        glDisable(GL_BLEND);
    }
	
	
	// scale
	//glPopMatrix();
	
		
} // end draw


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------



void testApp::keyPressed (int key){

    float x;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //          keystrokes              ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //          all modules             ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    switch (key) {

		case 'f' : // fullscreen on/off
			//bFullscreen = !bFullscreen;
//			if (bFullscreen == 0) {
//				ofSetFullscreen(false);
//			} else {
//				ofSetFullscreen(true);
//			}
			
			#ifdef TARGET_WIN32
				if(!bFullscreen){
					ofBeginCustomFullscreen(0,0,2048, 768);
				}else{
					ofEndCustomFullscreen();
				}
				bFullscreen = !bFullscreen;
			#else
				bFullscreen = !bFullscreen;
				if (bFullscreen == 0) {
					ofSetFullscreen(false);
				} else {
					ofSetFullscreen(true);
				}
			#endif
			
			break;

        case OF_KEY_END: // adds page
            //
            // if browsing video clips
            //
            if ((browsingClips == 1) and (float(videoThumbsPage) < ((nVideos / 45)+1))) {
                videoThumbsPage++;
                //cout << "\n videoThumbsPage: " << videoThumbsPage;
                QCchangePageStepPrepare();
            }
            //
            // if browsing directories
            //
            if ( (browsingDirs == 1) and (float(browsingDirsPage) < ((nFolders / 22)+1)) ) {
                browsingDirsPage++;
                QClistDirs();
            }
            break;
			
		case OF_KEY_F1: // decreases output resolution 
			interfaceSizeIndex--;
			if (interfaceSizeIndex < 1) { interfaceSizeIndex = 4; }
			QCchangeResolution();
            break;
		case OF_KEY_F2: // increases output resolution
			interfaceSizeIndex++;
			if (interfaceSizeIndex > 4) { interfaceSizeIndex = 1; }
			QCchangeResolution();
            break;
			
		case OF_KEY_F3: // decreases output resolution 
			screenSizeIndex--;
			if (screenSizeIndex < 1) { screenSizeIndex = 15; }
			QCchangeResolution();
            break;
		case OF_KEY_F4: // increases output resolution
			screenSizeIndex++;
			if (screenSizeIndex > 15) { screenSizeIndex = 1; }
			QCchangeResolution();
            break;
			
        case OF_KEY_HOME: // subtracts page
			// if browsing video clips
            if ((browsingClips == 1) and (videoThumbsPage > 1)) {
                videoThumbsPage--;
                QCchangePageStepPrepare();
            }
            // if browsing directories
            if ((browsingDirs == 1) and (browsingDirsPage > 1)) {
                browsingDirsPage--;
                QClistDirs();
            }
            break;
			
		// recording keys
		case 'n': // movie saver re setup
			#ifdef TARGET_LINUX
				// nothing
			#else // Mac and Windows
				// movie saver re setup
				bRecording = !bRecording;
				if (bRecording == false) saver.finishMovie();
				if (QCmovieSaver == 1){
					QCrecordingPrepare();
					bRecording = true;
				}
			#endif
			break;
		case 'm': // movie saver finish file
			#ifdef TARGET_LINUX
				// nothing
			#else // Mac and Windows
				// movie saver finish file
				if (QCmovieSaver == 1){
					saver.finishMovie();
					bRecording = false;
					string tempString = DirFolders.getPath(currentFolderNum); tempString.erase(0,eraseChars+1);
					if (tempString == "_Recordings") {
						QCchangeFolderStepPrepare();
						videoLoading = 1;
					}
				}
			#endif
			break;

    } // end switch keys all modules

  
	if (textInputActive == 1) { // listen to text input keystrokes
		switch (key){
			case OF_KEY_BACKSPACE:
				for (int x = 0; x <22; x++) textInput[x] = ' ';
				textInputCharPos = 0;
				//textInput[textInputCharPos] = ' ';
				//if (textInputCharPos > 0) textInputCharPos--;
				break;
			case OF_KEY_RETURN:
				textInputActive = -1;
				break;
			default:
				textInput[textInputCharPos] = key;
				if (textInputCharPos < 20) textInputCharPos++;
				break;
		} // end switch
	} else { // listen to shortcut keystrokes

		switch (key) {
			case 's': // save image toggle: trigger one fame save as .bmp
				bSnapshot = !(bSnapshot); break;

			case 'r': // random time
				int x = selectedLayer - 1;
				tempValue = ofRandom(0.01,0.99);
				videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPosition(tempValue);
				QCupdatePlayhead(x, tempValue);
				break;
				
			case 'R': // random video from active bin
				if (nVideos > 0){
					int x = selectedLayer-1;
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].closeMovie();
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = new ofVideoPlayer[nVideos];
					tempValue = int(ofRandom(0.0, nVideos));
					currentVideo[x+(layerSequenceItem[x]*4)] = tempValue;
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].loadMovie(DirVideos.getPath(currentVideo[x+(layerSequenceItem[x]*4)]));
					// sets new video speed
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]);
					// sets new video volume
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setVolume(layerVolume[x]);
					// draws layer thumb
					int verticalPosition = 10 + (192 * (selectedLayer-1));
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].draw(395+(layerSequenceItem[selectedLayer-1]*70),verticalPosition,64,48); // draws video thumb
				}
				break;

			case 'g': // previous video
				if ( (nVideos > 0) and (selectedLayer < 4) ) {
					int x = selectedLayer-1;
					//videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].closeMovie();
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = new ofVideoPlayer[nVideos];
					currentVideo[x+(layerSequenceItem[x]*4)]--;
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].loadMovie(DirVideos.getPath(currentVideo[x+(layerSequenceItem[x]*4)]));
					// sets new video speed:
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]);
					// sets new video volume:
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setVolume(layerVolume[x]);
				}
				break;

			case 'h': // next video
				if ( (nVideos > 0) and (selectedLayer < 4) ) {
					int x = selectedLayer-1;
					// videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].closeMovie();
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = new ofVideoPlayer[nVideos];
					currentVideo[x+(layerSequenceItem[x]*4)]++;
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].loadMovie(DirVideos.getPath(currentVideo[x+(layerSequenceItem[x]*4)]));
					// sets new video speed:
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]);
					// sets new video volume:
					videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setVolume(layerVolume[x]);
				}
				break;

			case OF_KEY_BACKSPACE:
				switch (selectedLayer) {
					case 1: case 2: case 3: case 4:
						layerVisibility[selectedLayer-1] = -layerVisibility[selectedLayer-1];
						if (layerVisibility[selectedLayer-1] == -1) {
							//QCstopMoviesMainModule();
							QCstopOneMovie();
						}else{
							QCresumeCurrentMovie();
						}
						break;
					case 5:
						layerVisibility[4] = - layerVisibility[4];
						// livecam visibility
						livecam = !(livecam);
						if (layerVisibility[4] == 1) { lightPaintStretchXadd = 0; lightPaintStretchYadd = 0; } ; // resets feedback value xxxxx
						if ( (bWebcamInit == 0) and (layerVisibility[4] == 1) ) QCinitWebcam(); // initializes livecam
						break;
					case 6: layerVisibility[5]= - layerVisibility[5]; break; // 3D layer
					case 7: layerVisibility[6]= - layerVisibility[6]; break; // image layer
					case 8: layerVisibility[7]= - layerVisibility[7]; break; // text layer
				}
				break;

			case OF_KEY_RIGHT: // faster, foward or backward
				if (selectedLayer < 5) { // only for video layers 1 to 4
					if (layerSpeed[selectedLayer-1] != 0) {
						switch (layerSpeed[selectedLayer-1] > 0) {
							case true: // make faster
								x = (layerSpeed[selectedLayer-1]) + .05; break;
							case false: // make faster
								x = (layerSpeed[selectedLayer-1]) - .05; break;
						} // end switch layerSpeed
					}
					else {
						x = 0.1;
					}
					if (x > 5) x = 5; // limits speed in 5
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setSpeed(x);
					layerSpeed[selectedLayer-1]= x;
					QCupdateSpeedBar();
				} // end if selectedLayer < 5
				if (selectedLayer == 5) { // livecam
					// livecamDevice ++;
					// if (livecamDevice > 6) { livecamDevice = 0; } // resets to zero
					// QCinitWebcam();
				} // end if selectedLayer == 5
				break;

			case OF_KEY_LEFT: // slower, foward or backward
				if (selectedLayer < 5) { // only for video layers 1 to 4
					if ( (layerSpeed[selectedLayer-1] < 0.1) and (layerSpeed[selectedLayer-1] > -0.1) ) { // if == 0 ???
						x = 0;
					}
					else {
						if (layerSpeed[selectedLayer-1] < 0) {
							x = (layerSpeed[selectedLayer-1]) + .05;  // make slower
						}
						else {
							x = (layerSpeed[selectedLayer-1]) - .05;  // make slower
						}
					}
					videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setSpeed(x);
					layerSpeed[selectedLayer-1]= x;
					if (x < 0) x = -x; // turns x to positive for GUI
					switch (selectedLayer){ //ofxGui update
						case 1: gui->update(kParameter_LayerSpeed1, kofxGui_Set_Float, &x, sizeof(x)); break;
						case 2: gui->update(kParameter_LayerSpeed2, kofxGui_Set_Float, &x, sizeof(x)); break;
						case 3: gui->update(kParameter_LayerSpeed3, kofxGui_Set_Float, &x, sizeof(x)); break;
						case 4: gui->update(kParameter_LayerSpeed4, kofxGui_Set_Float, &x, sizeof(x)); break;
					} // end switch

				} // end if selectedLayer
				break;

			case '0': // zero, inverts playback duration
				switch (selectedLayer) {
					case 1: case 2: case 3: case 4: // video layers
						x = videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].getSpeed();
						x = - (x) ;
						layerSpeed[selectedLayer-1] = x;
						videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setSpeed(layerSpeed[selectedLayer-1]);
						break;
				}
				break;
				
			case ' ': // space bar: pause
				switch (selectedLayer) {
					case 1: case 2: case 3: case 4: // video layers
						if (videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].getSpeed() != 0){
							videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setPaused(true);
						}
						break;
				}
				break;

			case OF_KEY_DOWN: // select layer below
				selectedLayer++; if (selectedLayer > 8) selectedLayer = 8;
				break;

			case OF_KEY_UP: // select layer above
				if (selectedLayer > 0) {
					selectedLayer--;
					if (selectedLayer < 1) selectedLayer = 1;
				}
				break;
				
			case OF_KEY_RETURN: // movie auto advance when playdone
				if (selectedLayer < 5) layerSequenceEnabled[selectedLayer-1] = -(layerSequenceEnabled[selectedLayer-1]);
				break;

			case OF_KEY_PAGE_DOWN: // adds layer sequence item
				if (selectedLayer == 1 or selectedLayer == 2 or selectedLayer == 3 or selectedLayer == 4) { // video layers
					QCstopOneMovie();
					int x = (selectedLayer-1);
					layerSequenceItem[x]++; // adds sequence item
					if (layerSequenceItem[x] == 4) layerSequenceItem[x] = 0;
					QCresumeCurrentMovie();
					QCupdateSpeedBar();
				} // end if
				if (selectedLayer == 7) { // image layer
					currentImage++;
					if (currentImage == nImages) currentImage = 0;
				} // end if

				break;

			case OF_KEY_PAGE_UP: // subtracts layer sequence item
				if (selectedLayer == 1 or selectedLayer == 2 or selectedLayer == 3 or selectedLayer == 4) { // video layers
					QCstopOneMovie();
					int x = (selectedLayer-1);
					layerSequenceItem[x]--;
					if (layerSequenceItem[x] == -1) layerSequenceItem[x] = 3; // resets active slot to last
					QCresumeCurrentMovie();
					QCupdateSpeedBar();
				} // end if
				if (selectedLayer == 7) { // image layer
					currentImage--;
					if (currentImage == -1) currentImage = (nImages-1);
				} // end if
				break;

			case 'a':
				layerBlend[selectedLayer-1] = layerBlend[selectedLayer-1] + 1; //selected layer blend
				if (layerBlend[selectedLayer-1]>6) layerBlend[selectedLayer-1] = 0;
				if (layerBlend[4]>2) layerBlend[4] = 0; // light Paint
				
				break;

			case '1': // selects video 1 layer
				selectedLayer = 1;
				break;

			case '2': // selects video 2 layer
				selectedLayer = 2;
				break;

			case '3': // selects video 3 layer
				selectedLayer = 3;
				break;

			case '4': // selects video 4 layer
				selectedLayer = 4;
				break;

			case '5': // selects livecam layer
				selectedLayer = 5;
				break;

			case '6': // selects 3D layer
				selectedLayer = 6;
				break;

			case '7': // selects  layer
				selectedLayer = 7;
				break;

			case '8': // selects  layer
				selectedLayer = 8;
				break;

//			case '9': // selects  audio channel 1
//				selectedAudioChannel = 1;
//				break;
//
//			case '0': // selects  audio channel 2
//				selectedAudioChannel = 2;
//				break;

			case 'v':
				vidGrabber.videoSettings(); break;

			case 'p':
				previewMonitor = !(previewMonitor); break;

			case 'P':
				previewFull = !(previewFull);
				break;

			case 'e': // change active video folder - adds
				currentFolderNum ++;
				videoThumbsPage = 1;
				if (currentFolderNum == nFolders) currentFolderNum = 0;
				QCchangeFolderStepPrepare();
				break;

			case 'w': // change active video folder - subtracts
				currentFolderNum --;
				if (currentFolderNum < 0) currentFolderNum = (nFolders -1);
				QCchangeFolderStepPrepare();
				break;

			case 't' : // text input new
				textInputActive = 1;
				break;

			case 'T' : // show bin movie durations
				showBinDurations  = !(showBinDurations);
				break;

			case 'i' : // invert current video
				layerInvert[selectedLayer-1] = - layerInvert[selectedLayer-1];
				break;

			case 'd' : // lists directories
				QClistDirs();
				break;
				
			case 'D': // change active video folder Random
				currentFolderNum = int(ofRandom(0,nFolders));
				// if (tempValue == currentFolderNum) currentFolderNum = int(ofRandom(0,nFolders)); // shuffle again if equal
				QCchangeFolderStepPrepare();
				videoLoading = 1;
				break;

			case 'u': // dir up
				QClistDirs();
				break;
				
			case OF_KEY_F12 : // help
				if (redrawInterface != 4) { redrawInterface = 4;
				} else { redrawInterface = 0; }

				break;

			case 'l' : // light paint
				lightPaint[4] = !(lightPaint[4]);
				break;

			case 'M' : // layer mirror
				layerFlip[4] = !(layerFlip[4]);
				//bLearnBakground = true;
				break;

			case 'F' : // livecam feedback
				lightPaintFeedback = !(lightPaintFeedback);
				if (lightPaintFeedback == false) { // resets feedback stretch values
					lightPaintStretchXadd = 0; lightPaintStretchYadd = 0;
				}
				break;

			case OF_KEY_F11:
				
				switch (languageCode[0]) {
					case 'P':
						languageCode[0] = 'E';
						redrawInterface = 1;
						break;
					case 'E':
						languageCode[0] = 'P';
						redrawInterface = 1;
						break;
				}
				break;

				
			// arduino patching in progress
				
//			case OF_KEY_F1 : arduinoPatching[0] = true; break;
//			case OF_KEY_F2 : arduinoPatching[1] = true; break;
//			case OF_KEY_F3 : arduinoPatching[2] = true; break;
//			case OF_KEY_F4 : arduinoPatching[3] = true; break;
//			case OF_KEY_F5 : arduinoPatching[4] = true; break;
//			case OF_KEY_F6 : arduinoPatching[5] = true; break;

		} // end key switch
	} // end if textInput


} // end keypressed


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::keyReleased  (int key){
}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    gui->mouseDragged(x, y, button);
	//gui->mouseDragged((x/interfaceSizeX)*1024, (y/interfaceSizeY)*768, button);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){

	gui->mousePressed(x, y, button);

	// scale
	//gui->mousePressed((x/interfaceSizeX)*1024, (y/interfaceSizeY)*768, button);


    /////////////////////////////////////
    //
    //  turns off full preview, on click
    //
    /////////////////////////////////////

    if (previewFull == 1) previewFull = 0;



    //////////////////////////////////////
    //
    //  turns off help screen, on click
    //
    //////////////////////////////////////

    if (redrawInterface == 4) { redrawInterface = 0; }



    /////////////////////////////////////////
    //
    //  video and folders pages click check
    //  main & live cinema module ------make audio routine
    //
    /////////////////////////////////////////

    if (browsingClips == 1) { // if browsing clips, change page
        if ( (mouseY > 715) and (mouseY < 734) ) {
            if ( (mouseX >= 9) and (mouseX < 39) ) { videoThumbsPage = 1; QCchangePageStepPrepare(); }
            if ( (mouseX >= 39) and (mouseX < 69) and (nVideos > 45)  ) { videoThumbsPage = 2; QCchangePageStepPrepare(); }
            if ( (mouseX >= 69) and (mouseX < 99) and (nVideos > 90)  ) { videoThumbsPage = 3; QCchangePageStepPrepare(); }
			if ( (mouseX >= 99) and (mouseX < 129) and (nVideos > 135)  ) { videoThumbsPage = 4; QCchangePageStepPrepare(); }
			if ( (mouseX >= 129) and (mouseX < 159) and (nVideos > 180)  ) { videoThumbsPage = 5; QCchangePageStepPrepare(); }
			if ( (mouseX >= 159) and (mouseX < 189) and (nVideos > 225)  ) { videoThumbsPage = 6; QCchangePageStepPrepare(); }
			if ( (mouseX >= 189) and (mouseX < 219) and (nVideos > 270)  ) { videoThumbsPage = 7; QCchangePageStepPrepare(); }
			if ( (mouseX >= 219) and (mouseX < 249) and (nVideos > 315)  ) { videoThumbsPage = 8; QCchangePageStepPrepare(); }
			if ( (mouseX >= 249) and (mouseX < 279) and (nVideos > 360)  ) { videoThumbsPage = 9; QCchangePageStepPrepare(); }
			// if ( (mouseX >= 279) and (mouseX < 309) ) videoThumbsPage = 10; QCchangePageStepPrepare();
			videoLoadingNewPage = 1;
        } // end if mouseY
    } else {
		if (browsingDirs == 1) { // if browsing directories
			if ( (mouseY > 715) and (mouseY < 734) ) { // vertical check
				if ( (mouseX >=  9) and (mouseX < 39) ) { browsingDirsPage = 1; QClistDirs(); }
				if ( (mouseX >= 39) and (mouseX < 69) and (((nFolders / 22)+1) >= 2.0) ) { browsingDirsPage = 2; QClistDirs(); }
				if ( (mouseX >= 69) and (mouseX < 99) and (((nFolders / 22)+1) >= 3.0) ) { browsingDirsPage = 3; QClistDirs(); }
				if ( (mouseX >= 99) and (mouseX < 129) and (((nFolders / 22)+1) >= 4.0) ) { browsingDirsPage = 4; QClistDirs(); }
				if ( (mouseX >= 129) and (mouseX < 159) and (((nFolders / 22)+1) >= 5.0) ) { browsingDirsPage = 5; QClistDirs(); }
				if ( (mouseX >= 159) and (mouseX < 189) and (((nFolders / 22)+1) >= 6.0) ) { browsingDirsPage = 6; QClistDirs(); }
				if ( (mouseX >= 189) and (mouseX < 219) and (((nFolders / 22)+1) >= 7.0) ) { browsingDirsPage = 7; QClistDirs(); }
				if ( (mouseX >= 219) and (mouseX < 249) and (((nFolders / 22)+1) >= 8.0) ) { browsingDirsPage = 8; QClistDirs(); }
				if ( (mouseX >= 249) and (mouseX < 279) and (((nFolders / 22)+1) >= 9.0) ) { browsingDirsPage = 9; QClistDirs(); }
				// if ( (mouseX >= 279) and (mouseX < 309) ) browsingDirsPage = 10; QCchangeFolderStepPrepare();
			} // end if mouseY
		} // end if browsingDirs == 1
	}


    /////////////////////////////////////////
    //
    //  directories click check
    //  main & live cinema module
    //
    /////////////////////////////////////////

    if ( (browsingDirs == 1) and (mouseX < 360) and (mouseY < 715) ) { // if browsing directories
		currentFolderNum = int( ( (mouseY-195)/22) + ( (browsingDirsPage-1) *22) );
		videoLoading = 1;
		browsingClips = 1;
		browsingDirs = -1;
		QCchangeFolderStepPrepare();

    } else if ( (browsingAudioDirs == 1) and (mouseX < 360) and (mouseY < 715) ) { // if browsing directories
		currentAudioFolderNum = int(((mouseY-195)/22)+((browsingAudioDirsPage-1)*22));
		if ( (currentAudioFolderNum >= 0) and (currentAudioFolderNum < nAudioFolders) ) { // if valid dir
			QClistAudioOpenDir();
		}
	} else { // end if browsingAudioDirs == 1


                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //                            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //  main module click check   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //                            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


				//////////////////////////////////////
				//
				//  random directory, on icon click
				//
				//////////////////////////////////////

				if ( (mouseY > 690) and (mouseY < 711) and (mouseX > 330) and (mouseX < 351) ) {
					currentFolderNum = int(ofRandom(0,nFolders));
					// if (tempValue == currentFolderNum) currentFolderNum = int(ofRandom(0,nFolders)); // shuffle again if equal
					QCchangeFolderStepPrepare();
				}


                ///////////////////////////////////////////
                //
                //  video file from bin, mouse click check
                //
                ///////////////////////////////////////////

                if ( (browsingClips == 1) and (selectedLayer < 5) ) { // video layers 1 to 4
					// discover what thumb was clicked on
                    for (int line = 0; line < 9; line++) { // video thumbs - for by lines
                        if ( (mouseY > (thumbsVertPos+(54*line))) and (mouseY < (thumbsVertPos+(54*(line+1))) ) ) { // if by lines
                            for(int column = 0; column < 5; column++) { // video thumbs by columns
                                if ( (mouseX > (thumbsHorPos+(70*column))) and (mouseX < (thumbsHorPos+(70*(column+1)))) ) { // if by columns
                                    tempValue = ((line*5) + column) + ((videoThumbsPage-1)*45);
                                    if (tempValue < nVideos) {	
										int x = selectedLayer-1;
										videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].closeMovie();
                                        currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = tempValue;
                                        //cout << "\n\n" << DirVideos.getPath(currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]);
                                        //cout << " tempValue= " << tempValue << " nVideos= " << nVideos;
										videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = new ofVideoPlayer[nVideos];
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].loadMovie(DirVideos.getPath(currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]));
                                        // Linux new:
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setLoopState(OF_LOOP_NORMAL);
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setSpeed(layerSpeed[selectedLayer-1]); // sets new video speed
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setVolume(layerVolume[selectedLayer-1]); // sets new video volume
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].setPosition(0.001); // sets new video position
                                        // draws layer thumb
                                        verticalPosition = 10 + (192 * (selectedLayer-1));
                                        videos[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)]].draw(395+(layerSequenceItem[selectedLayer-1]*70),verticalPosition,64,48); // draws video thumb
                                    } // end if tempValue < nVideos
								} // end if by columns
                            } // end for by columns
                        } // end if lines
                    } // end for by lines
                } // end if video layers 1 to 4



                //////////////////////////////////
                //
                //  layer visibility click check
                //
                //////////////////////////////////

                if ( (mouseX >= 371) and (mouseX <= 389) ) { // layers 1 to 4
                    if ( (mouseY >= 7) and (mouseY <= 24) ) {
						x = 0;
                        layerVisibility[x] = - layerVisibility[x];
						switch (layerVisibility[x]) { // plays or stops
							case -1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(0); break;
							case 1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]); break;
						}
					}
                    if ( (mouseY >= 199) and (mouseY <= 216) ) {
                        x = 1;
						layerVisibility[x] = - layerVisibility[x];
						switch (layerVisibility[x]) { // plays or stops
							case -1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(0); break;
							case 1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]); break;
						}
					}
                    if ( (mouseY >= 391) and (mouseY <= 408) ){
                        x = 2;
						layerVisibility[x] = - layerVisibility[x];
						switch (layerVisibility[x]) { // plays or stops
							case -1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(0); break;
							case 1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]); break;
						}
					}
                    if ( (mouseY >= 583) and (mouseY <= 600) ) {
						x = 3;
						layerVisibility[x] = - layerVisibility[x];
						switch (layerVisibility[x]) { // plays or stops
							case -1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(0); break;
							case 1: videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]); break;
						}
					}

                } // end if layers 1 to 4

                if ( (mouseX >= 815) and (mouseX <= 834) ) { // layers 5 to 8
                    if ( (mouseY >= 7) and (mouseY <= 24) ) {
                        livecam = !(livecam);
						layerVisibility[4] = - layerVisibility[4];
						if ( (bWebcamInit == 0) and (layerVisibility[4] == 1) ) QCinitWebcam();
                    }
                    if ( (mouseY >= 199) and (mouseY <= 216) )
                        layerVisibility[5] = - layerVisibility[5];
                    if ( (mouseY >= 391) and (mouseY <= 408) )
                        layerVisibility[6] = - layerVisibility[6];
                    if ( (mouseY >= 583) and (mouseY <= 600) )
                        layerVisibility[7] = - layerVisibility[7];
                } // end if layers 5 to 8



                //////////////////////////////////
                //
                //  layer click check
                //
                //////////////////////////////////

                if ( (mouseX > 360) and (mouseX < 804) ) { // layers 1 to 4
                    if (mouseY <= 192) selectedLayer = 1;
                    if ( (mouseY >= 192) and (mouseY < 384) ) selectedLayer = 2;
                    if ( (mouseY >= 384) and (mouseY < 576) ) selectedLayer = 3;
                    if (mouseY >= 576) selectedLayer = 4;
                }
                if (mouseX >= 804) { // layers 5 to 8
                    if (mouseY <= 192) selectedLayer = 5;
                    if ( (mouseY >= 192) and (mouseY < 384) ) selectedLayer = 6;
                    if ( (mouseY >= 384) and (mouseY < 576) ) selectedLayer = 7;
                    if (mouseY >= 576) selectedLayer = 8;
                }



                //////////////////////////////////////
                //
				//  layers 1 to 4
                //  sequence item click check
                //  activelayer gets changed with click, code above does this
                //
                //////////////////////////////////////

                if ( (mouseX >= 394) and (mouseX < 668) ) { // only if layers 1 to 4
                    int x = (selectedLayer-1);
                    if ( (mouseY > (8+(x*192))) and (mouseY < (57+(x*192))) ) { // vertical check
                        if ( (mouseX >= 394) and (mouseX < 668) ) { // horizontal check

							QCstopOneMovie();

							if ( (mouseX >= 394) and (mouseX < 461) ) layerSequenceItem[x] = 0;
                            if ( (mouseX >= 461) and (mouseX < 530) ) layerSequenceItem[x] = 1;
                            if ( (mouseX >= 530) and (mouseX < 600) ) layerSequenceItem[x] = 2;
                            if ( (mouseX >= 600) and (mouseX < 668) ) layerSequenceItem[x] = 3;

							QCresumeCurrentMovie();

							// active sequence item light
                            videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]);

							QCupdateSpeedBar();
                        } // end if horizontal check
                    } // end if vertical check
                } // end if layers 1 to 4



                //////////////////////////////////////
                //
                //   audio file click check aaaaa
                //   main module
                //
                //////////////////////////////////////

                //
                // if browsing audio clips
                //
                if ( (browsingAudioClips == 1) and (mouseX < 360) and (mouseY > 200) ) {
					currentAudioFolderNum = int( ( (mouseY-200)/22) + ( (browsingAudioDirsPage-1) *22) );
                    if ( currentAudioFolderNum < (nAudioFiles) ) { // if valid audio file
                        string tempString =  DirAudioFiles.getPath(currentAudioFolderNum); // hard coded ?
                        switch (selectedAudioChannel) {
                            case 1:
                                audioChannel1.loadSound(tempString, false);
                                audioChannel1.play();
                                //audioChannel1.setVolume(LCaudioChannel1Volume);
                                break;
                            case 2:
                                audioChannel2.loadSound(tempString, false);
                                audioChannel2.play();
                                //audioChannel2.setVolume(LCaudioChannel2Volume);
                                break;
                        } // end switch selectedAudioChannel
						browsingAudioClips = -1;
						browsingClips = 1; // back to browsing video clips
                    }
                } // end if browsingAudioDirs == 1



				/////////////////////////////////
                //
				//  livecam layer
                //  icons click check
                //
                /////////////////////////////////

				// light paint on/off
				if ( (mouseX > 895) and (mouseX < 917) and (mouseY > 8) and (mouseY < 29) ) lightPaint[4] = !(lightPaint[4]);

				// light paint feedback on/off
				if ( (mouseX > 919) and (mouseX < 942) and (mouseY > 8) and (mouseY < 29) ) {
					lightPaintFeedback = ! (lightPaintFeedback);
					if (lightPaintFeedback == false) { // resets feedback stretch values
						lightPaintStretchXadd = 0; lightPaintStretchYadd = 0;
					}
				}

				// livecam mirror on/off
				if ( (mouseX > 943) and (mouseX < 965) and (mouseY > 8) and (mouseY < 29) ) layerFlip[4] = !(layerFlip[4]);



                /////////////////////////////////
                //
				//  text layer
                //  font change click check
                //
                /////////////////////////////////

				// text input
				if ( (mouseX > 815) and (mouseX < 840) and (mouseY > 603) and (mouseY < 627) ) textInputActive = -(textInputActive);

				// change font
                if ( (mouseX > 849) and (mouseX < 874) and (mouseY > 603) and (mouseY < 627) ) QCchangeFont();



                /////////////////////////////////
                //
				// image layer
                // image change click check
                //
                /////////////////////////////////

                if ( (mouseX > 818) and (mouseX < 842) and (mouseY > 466) and (mouseY < 491) ) { // changes to previous image
                    currentImage--;
                    if (currentImage == -1) currentImage = (nImages-1);
                }
                else {
					if ( (mouseX > 854) and (mouseX < 878) and (mouseY > 466) and (mouseY < 491) ) { // changes to next image
						currentImage++;
						if (currentImage == nImages) currentImage = 0;
					}
				}




	} // end if click 
	


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                       ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //  buttons click check                  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                       ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


	if ( (mouseY > 688) and (mouseY < 712) and (mouseX > 7) and (mouseX < 31) ) {  // random icon click
	
		currentFolderNum = int(ofRandom(0,nFolders));
		// if (tempValue == currentFolderNum) currentFolderNum = int(ofRandom(0,nFolders)); // shuffle again if equal
		QCchangeFolderStepPrepare();
		videoLoading = 1;
		
	} else if ( (mouseY > 688) and (mouseY < 712) and (mouseX > 32) and (mouseX < 57) ) { // folder icon click
		QClistDirs();
	} else if ( (mouseY > 718) and (mouseY < 742) and (mouseX > 337) and (mouseX < 362) ) { // help icon click
		redrawInterface = 4;
	}

		//else if ( (mouseX >= 104) and (mouseX < 125) ) { // 4th icon
//			// audio icon click
//			QClistDirsAudio();



} // end mouse pressed


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::mouseReleased(int x, int y, int button){

    gui->mouseReleased(mouseX, mouseY, 0);
	
	// scale
	//gui->mouseReleased((x/interfaceSizeX)*1024.0, (y/interfaceSizeY)*768.0, button);
	
	//bMousePressed = false; // 3D manipulation

}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::windowResized(int w, int h){

}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangeResolution(){
	switch (screenSizeIndex) {
		case 1: screenSizeX = 180; screenSizeY = 120; break;
		case 2: screenSizeX = 240; screenSizeY = 180; break;
		case 3: screenSizeX = 320; screenSizeY = 240; break;
		case 4: screenSizeX = 480; screenSizeY = 360; break;
		case 5: screenSizeX = 640; screenSizeY = 480; break;
		case 6: screenSizeX = 800; screenSizeY = 600; break;
		case 7: screenSizeX = 1024; screenSizeY = 768; break;
		case 8: screenSizeX = 1280; screenSizeY = 720; break;
		case 9: screenSizeX = 1920; screenSizeY = 1080; break;
		case 10: screenSizeX = 1280; screenSizeY = 480; break; // 2x 640x480
		case 11: screenSizeX = 1920; screenSizeY = 480; break; // 3x 640x480
		case 12: screenSizeX = 1600; screenSizeY = 600; break; // 2x 800x600
		case 13: screenSizeX = 2400; screenSizeY = 600; break; // 3x 800x600
		case 14: screenSizeX = 2048; screenSizeY = 768; break; // 2x 1024x768
		case 15: screenSizeX = 3072; screenSizeY = 768; break; // 3x 1024x768
	}
	switch (interfaceSizeIndex) {
		case 1: interfaceSizeX = 1024; interfaceSizeY = 768; break;
		case 2: interfaceSizeX = 1280; interfaceSizeY = 800; break;
		case 3: interfaceSizeX = 1440; interfaceSizeY = 900; break;
		case 4: interfaceSizeX = 1680; interfaceSizeY = 1050; break;
		//case 5: interfaceSizeX = 1920; interfaceSizeY = 1200; break;
	}
	
	if (interfaceSizeY > screenSizeY) {
		ofSetWindowShape( (interfaceSizeX+screenSizeX), interfaceSizeY);
	} else {
		ofSetWindowShape( (interfaceSizeX+screenSizeX), screenSizeY);
	}
	
	#ifdef TARGET_LINUX
	// nothing
	#else // Mac and Windows
	// movie saver stop
	if (bRecording == true) saver.finishMovie();
	bRecording = false;
	#endif
	texScreen.allocate(screenSizeX,screenSizeY,GL_RGB);
}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCredrawInterface(){
    ofSetWindowShape(1824,768);
    ofSetWindowPosition(0,0);
    ofSetRectMode(OF_RECTMODE_CORNER); // draws rectangles from corner
    interfaceBackground.draw(0,0);
    interfaceLayers.draw(366,0);
    glEnable(GL_BLEND); ofSetColor(255,255,255);
    layerOutlineA.draw(366,(3+((selectedLayer-1)*192)));
    glDisable(GL_BLEND); ofSetColor(51,51,51); // clears first layer with black
    ofFill(); ofRect(interfaceSizeX,0,screenSizeX,screenSizeY);

    QCvideoThumbs();
    QClayerThumbs();
    QCresetTimers();
    redrawInterface = 0;


}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCredrawInterfaceText(){
	// Interface video info
	// Layer Speed draw
	//for(int x = 0; x<4; x++){
	//    ofSetRectMode(OF_RECTMODE_CENTER); // draws rectangles from center
	//    ofSetColor(51,51,51); // dark gray bg
	//    ofFill(); // draws filled shape
	//    ofRect(445,(40+(x*192)),60,20); // clears video speed field
	//    ofSetColor(200,200,200); // light grey text
	//    ofDrawBitmapString(layerSpeedString[x],435,(40+(x*192))); // draws video speed text
	//    ofSetRectMode(OF_RECTMODE_CORNER);  // draws rectangles from center (app default)
	//    } // end for
} // end QCdrawInterfaceText


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangeFolder(){ //changes current directory

	if (currentFolderNum < 0) currentFolderNum = 0;

    nVideos = DirVideos.listDir(DirFolders.getPath(currentFolderNum));
    videoThumbsPage = 1; // resets thumbnails page to 1

    if (nVideos > 45) nVideosLimited = 45; // limits ofVideoPlayer
    else nVideosLimited = nVideos;

    // Linux new:
    videoThumbs = new ofVideoPlayer[nVideosLimited];
    for(int x=0; x<nVideosLimited; x++) {
        videoThumbs[x].loadMovie(DirVideos.getPath(x));
        videoThumbs[x].setLoopState(OF_LOOP_NORMAL);
    }

}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------




void testApp::QCchangeFolderStepPrepare(){ // changes current directory
    delete [] videoThumbs;
    nVideos = DirVideos.listDir(DirFolders.getPath(currentFolderNum));
    videoThumbsPage = 1; // resets thumbnails page to 1
    if (nVideos > 45) nVideosLimited = 45; // limits ofVideoPlayer
    else nVideosLimited = nVideos;
    videoThumbs = new ofVideoPlayer[nVideosLimited];

	videoLoading = 1;
    videoLoadStep = 0;

}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangePageStepPrepare(){ // changes current directory page
    nVideosLimited = nVideos - ((videoThumbsPage-1)*45);
    if (nVideosLimited > 45) {
        nVideosLimited = 45; // limits ofVideoPlayer
    }

	videoLoadingNewPage = 1;
    videoLoadStep = 0;

}



//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangeFolderStep(){ // step loads movies
    if (ofRandom(0.0,2.0)>1.0) { // 50% chance
        if (videoLoadStep < nVideosLimited) {
            videoThumbs[videoLoadStep].loadMovie(DirVideos.getPath(videoLoadStep+((videoThumbsPage-1)*45)));
            videoLoadStep++;
        } else {
            // QCvideoThumbs();
            videoLoading = 0;
        }
    } // end if random
}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangePageStep(){ // step loads movies
    if (ofRandom(0.0,2.0)>1.0){ // 50% chance
        if (videoLoadStep < nVideosLimited) {
            videoThumbs[videoLoadStep].loadMovie(DirVideos.getPath(videoLoadStep+((videoThumbsPage-1)*45)));
            videoLoadStep++;
        } else {
            QCvideoThumbs();
            for(int x = videoLoadStep; x<45; x++){
                videoThumbs[x].loadMovie("interface/null.mov");
            }
            videoLoadingNewPage = 0;
        }
    } // end if random

}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCvideoThumbs(){ // updates video thumbs
    currentVideoThumb = 0; // thumbs page beginning
    glDisable(GL_BLEND); // turn off alpha blending

	// stops all videos on bin
	for(int x = 0; x < nVideosLimited; x++) videoThumbs[x].setSpeed(0.0);

	for(int line = 0; line < 9; line++){ // video thumbs by lines
        for(int column = 0; column < 5; column++){ // video thumbs by columns
            if (currentVideoThumb < nVideos){ // checks if thumb is valid
                ofSetColor(255,255,255); // white
                //videoThumbs[currentVideoThumb].idleMovie(); // Linux
                videoThumbs[currentVideoThumb].draw(((column*70)+thumbsHorPos),((line*54)+thumbsVertPos),64,48);
				
				// draw durations
				if ( (videoLoading == 0) and (showBinDurations == 1) ){
					// draw duration
					int tempValue2 = videoThumbs[currentVideoThumb].getDuration();
					int minutes = tempValue2 / 60; int seconds = tempValue2 % 60;

					if (seconds < 10){
						tempString = ofToString (minutes) + ":0" + ofToString (seconds,0);
					} else {
						tempString = ofToString (minutes) + ":" + ofToString (seconds,0);
					}
					if (minutes < 10){
						ofSetColor(0,0,0); fontVerdana8.drawString(tempString, ((column*70)+thumbsHorPos)+36+1, ((line*54)+thumbsVertPos)+46+1); // time shadow
						ofSetColor(0,255,0); fontVerdana8.drawString(tempString, ((column*70)+thumbsHorPos)+36, ((line*54)+thumbsVertPos)+46); // time
					} else {
						ofSetColor(0,0,0);		// time shadow
						ofSetColor(0,255,0); fontVerdana8.drawString(tempString, ((column*70)+thumbsHorPos)+36-8, ((line*54)+thumbsVertPos)+46); // time
					}
				}
					
                currentVideoThumb++;
            } else{ // clears empty video spots
                ofSetColor(51,51,51); // dark gray
                ofFill(); ofRect(((column*70)+thumbsHorPos),((line*54)+thumbsVertPos),64,48);
            }
        } // end for columns
    } // end for lines
} // end QCvideoThumbs()


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QClayerThumbs(){ //updates layers video thumbs
    // draws layer thumbs
    for (int line = 0; line < 4; line++){
        for (int column = 0; column < 4; column++){
            int verticalPosition = 10 + (192 * line);
            ofFill(); ofSetColor(0,255,0); // green
            ofRect(395+(layerSequenceItem[line]*70),58+(line*192),64,6); // active sequence item light
            ofSetColor(255,255,255);
            //videos[line+(column*4)][currentVideo[line+(column*4)]].idleMovie(); // Linux
            videos[line+(column*4)][currentVideo[line+(column*4)]].draw(395+(column*70),verticalPosition,64,48); // draws video thumb
        }
    }
} // end QClayerThumbs


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCupdateSpeedBar(){
    float tempValue = layerSpeed[selectedLayer -1];
    // cout << "layerSpeed: ";
    // cout << tempValue;
    if (tempValue < 0) tempValue = -tempValue;
    switch (selectedLayer){ //ofxGui update
        case 1: gui->update(kParameter_LayerSpeed1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 2: gui->update(kParameter_LayerSpeed2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 3: gui->update(kParameter_LayerSpeed3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 4: gui->update(kParameter_LayerSpeed4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
    } // end switch
}


//---------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCupdatePlayhead(int layerInfluenced, float tempValue){
    switch (layerInfluenced){ //ofxGui update
        case 1:
            gui->update(kParameter_LayerPlayhead1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 2:
            gui->update(kParameter_LayerPlayhead2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 3:
            gui->update(kParameter_LayerPlayhead3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
        case 4:
            gui->update(kParameter_LayerPlayhead4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); break;
    } // end switch
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


// void testApp::QCupdateColorSlider(int layerInfluenced, float tempValue){
//    switch (layerInfluenced){ //ofxGui update
//        case 1:
//            gui->update(kParameter_LayerColor1, kofxGui_Set_Color, &tempValue, sizeof(tempValue)); break;
//        case 2:
//            gui->update(kParameter_LayerColor2, kofxGui_Set_Color, &tempValue, sizeof(tempValue)); break;
//        case 3:
//            gui->update(kParameter_LayerColor3, kofxGui_Set_Color, &tempValue, sizeof(tempValue)); break;
//        case 4:
//            gui->update(kParameter_LayerColor4, kofxGui_Set_Color, &tempValue, sizeof(tempValue)); break;
//        // do until 8
//    } // end switch
//}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::QCchangeSequenceItem(int x){
	if (x <4) {
		layerSequenceItem[x]++; // adds sequence item
		if (layerSequenceItem[x] == 4) layerSequenceItem[x] = 0;
		// active sequence item light
		ofSetColor(0,255,0); // green
		ofRect(395+(layerSequenceItem[x]*70),58+(x*192),64,6);
		//videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]);
		QCupdateSpeedBar();
	}
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QClistDirs(){ // lists available video directories
    browsingDirs = 1; // triggers display on draw routine
	browsingAudioDirs = -1;
	browsingClips = -1;
	browsingAudioClips = -1;
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QClistDirsAudio(){ // lists available video directories
	browsingAudioDirs = 1; // triggers display on draw routine
	browsingAudioDirsPage = 1;
	browsingDirs = -1;
	browsingClips = -1;
	browsingAudioClips = -1;
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------



void testApp::QClistDirsDraw(){ // lists available video directories
	ofSetColor(200,200,200);
	for(int x=0; x<22; x++) {
		tempValueInt = int (((browsingDirsPage-1)*22) + x);
		if (tempValueInt < nFolders) {
			tempString = DirFolders.getPath(tempValueInt);
			tempString.erase(0,eraseChars);
			//tempString = ofToDataPath(DirFolders.getPath(tempValueInt));
			
			fontVerdana11.drawString(tempString, 15, 210 + (22*x));
		}
	}

	//
	// directory paging icons draw
	//
	ofSetColor(255,255,255);
	iconPageNotActive.draw (9,715); // icon clips page 1
	if (nFolders > 22) iconPageNotActive.draw (39,715); // icon folders page 2
	if (nFolders > 44) iconPageNotActive.draw (69,715); // icon folders page 3
	if (nFolders > 66) iconPageNotActive.draw (99,715); // icon folders page 4
	if (nFolders > 88) iconPageNotActive.draw (129,715); // icon folders page 5
	if (nFolders > 110) iconPageNotActive.draw (159,715); // icon folders page 6
	if (nFolders > 132) iconPageNotActive.draw (189,715); // icon folders page 7
	if (nFolders > 154) iconPageNotActive.draw (219,715); // icon folders page 8
	if (nFolders > 176) iconPageNotActive.draw (249,715); // icon folders page 9
	if (nFolders > 198) iconPageNotActive.draw (279,715); // icon folders page 10

	iconPageActive.draw(9+int( ((browsingDirsPage-1)*30) ),715); // icon active page

}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QClistAudioOpenDir(){ // lists available audio directories
    browsingAudioClips = 1;
	browsingAudioDirs = -1;
    nAudioFiles = DirAudioFiles.listDir(DirAudioFolders.getPath(currentAudioFolderNum));

}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------



void testApp::QClistDirsAudioDraw(){ // lists available audio directories
	glDisable(GL_BLEND); ofSetColor(200,200,200);
	for (int x=0; x<22; x++) {
		tempValueInt = int (((browsingAudioDirsPage-1)*22) + x);
		if (tempValueInt < nAudioFolders) {
			tempStringAudio = DirAudioFolders.getPath(tempValueInt);
			tempStringAudio.erase(0,eraseChars); // platform dependant variable: eraseChars
			fontVerdana11.drawString(tempStringAudio, 15, 210 + (22*x));
		}
	}


	//
	// directory paging icons draw
	//
	ofSetColor(255,255,255);
	iconPageNotActive.draw (9,715); // icon clips page 1
	if (nAudioFolders > 22) iconPageNotActive.draw (39,715); // icon folders page 2
	if (nAudioFolders > 44) iconPageNotActive.draw (69,715); // icon folders page 3
	if (nAudioFolders > 66) iconPageNotActive.draw (99,715); // icon folders page 4
	if (nAudioFolders > 88) iconPageNotActive.draw (129,715); // icon folders page 5
	if (nAudioFolders > 110) iconPageNotActive.draw (159,715); // icon folders page 6
	if (nAudioFolders > 132) iconPageNotActive.draw (189,715); // icon folders page 7
	if (nAudioFolders > 154) iconPageNotActive.draw (219,715); // icon folders page 8
	if (nAudioFolders > 176) iconPageNotActive.draw (249,715); // icon folders page 9
	if (nAudioFolders > 198) iconPageNotActive.draw (279,715); // icon folders page 10

	iconPageActive.draw(9+(int ( (browsingAudioDirsPage-1)*30) ),715); // icon active page

}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------



void testApp::QClistClipsAudioDraw(){ // lists audio files
	ofSetColor(200,200,200);
	for (int x=0; x<22; x++) {
		tempValueInt = int (((browsingAudioDirsPage -1)*22) + x);
		if (tempValueInt < nAudioFiles) {
			tempStringAudio = DirAudioFiles.getPath(tempValueInt); tempStringAudio.erase(0,eraseChars);
			fontVerdana11.drawString(tempStringAudio, 15, 210 + (22*x));
		}
	} // end for


	//
	// audio clips paging icons draw
	//
	ofSetColor(255,255,255);
	iconPageNotActive.draw (9,715); // icon clips page 1
	if (nAudioFiles > 22) iconPageNotActive.draw (39,715); // icon folders page 2
	if (nAudioFiles > 44) iconPageNotActive.draw (69,715); // icon folders page 3
	if (nAudioFiles > 66) iconPageNotActive.draw (99,715); // icon folders page 4
	if (nAudioFiles > 88) iconPageNotActive.draw (129,715); // icon folders page 5
	if (nAudioFiles > 110) iconPageNotActive.draw (159,715); // icon folders page 6
	if (nAudioFiles > 132) iconPageNotActive.draw (189,715); // icon folders page 7
	if (nAudioFiles > 154) iconPageNotActive.draw (219,715); // icon folders page 8
	if (nAudioFiles > 176) iconPageNotActive.draw (249,715); // icon folders page 9
	if (nAudioFiles > 198) iconPageNotActive.draw (279,715); // icon folders page 10

	iconPageActive.draw(9+((browsingDirsPage-1)*30),715); // icon active page

}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCchangeFont(){ // changes text font
    currentFont++;
    if (currentFont == 7) currentFont = 1;
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCstopMoviesMainModule(){ // stops all overlay videos on main module (thumbs)
	for (int y = 0; y < 16; y++) videos[y][currentVideo[y]].setPaused(true);
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCstopOneMovie(){ // pauses one video
	videos[(selectedLayer-1)+(layerSequenceItem[(selectedLayer-1)]*4)][currentVideo[(selectedLayer-1)+(layerSequenceItem[(selectedLayer-1)]*4)]].setPaused(true) ; // pauses
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCstopMovieOnLayer(int x){ // pauses one video
	videos[(x)+(layerSequenceItem[(x)]*4)][currentVideo[(x)+(layerSequenceItem[(x)]*4)]].setPaused(true) ; // pauses
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCresumeCurrentMovie(){ // resumes current video
	int x = selectedLayer-1;
	videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPaused(false); // resumes
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCresumeCurrentMovieOnLayer(int x){ // resumes current video
	videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPaused(false); // resumes
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::QCresetTimers() { //updates layers video thumbs
    for (int x=0; x <4; x++) {
        timeStep[x] = 0;
        previousTimeStep[x] = 0;
        timePlayheadRandom[x] = 0;
        previousTimePlayheadRandom[x] = 0;
    }
    for (int x=0; x <8; x++) {
        timeBlink[x] = 0;
        previousTimeBlink[x] = 0;
        timeColorRandom[x] = 0;
        previousTimeColorRandom[x] = 0;
        timeInvert[x] = 0;
        previousTimeInvert[x] = 0;
    }
	timeSize3D = 0;
	previousTimeSize3D = 0;
	timeRot3D = 0;
	previousTimeRot3D = 0;
	previousTimeFpsAverage = 0;
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::QCinitWebcam() { //updates layers video thumbs
	// try to grab at screen size
	//camWidth = screenSizeX;
	//camHeight = screenSizeY;

	camWidth = 800;
	camHeight = 600;

	vidGrabber.close();

	vidGrabber.setVerbose(true);
	vidGrabber.listDevices();

	vidGrabber.setDeviceID(livecamDevice);
	vidGrabber.initGrabber(camWidth,camHeight);

	printf("\n\n Quase-Cinema asked for %i x %i - actual size is %i by %i \n", camWidth, camHeight, vidGrabber.width, vidGrabber.height);

	// did init ok? variable
	videoInverted = new unsigned char[camWidth*camHeight*3];
	videoTexture.allocate(camWidth,camHeight, GL_RGB);
	bWebcamInit = 1;
}


//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::QCrecordingPrepare(){ //updates layers video thumbs

	// gets date
	time_t    curr;
	tm       local;
	time(&curr);
	local   =*(localtime(&curr));
	sprintf (fileNameSufix," %d-%02d-%02d %02d.%02d.%02d",(local.tm_year+1900),(local.tm_mon+1),local.tm_mday,local.tm_hour,local.tm_min,local.tm_sec);
	//ofLog(OF_LOG_WARNING,"Filename sufix: %s", fileNameSufix);

	bRecording = false;
	char fileName[255];
	sprintf(fileName, "QCrec%s.mov", fileNameSufix);
	saver.setup(screenSizeX,screenSizeY,fileName);
	imageToSave.allocate(screenSizeX,screenSizeY,OF_IMAGE_COLOR);
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::QCtimeDisplay(){ // updates time
	time_t    curr;
	tm       local;
	time(&curr);
	local   =*(localtime(&curr));
	sprintf (helpText,"%02d:%02d:%02d",local.tm_hour,local.tm_min,local.tm_sec);
	ofSetColor(200, 200, 200);
	fontAutomat6.drawString(helpText, 316, 764);
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::setupArduino(){

	// this is where you setup all the pins and pin modes, etc
	//for (int i = 0; i < 13; i++){
	//	ard.sendDigitalPinMode(i, ARD_OUTPUT);
	//}
	//ard.sendDigitalPinMode(13, ARD_OUTPUT);
	for (int i = 0; i < 6; i++){
		ard.sendAnalogPinReporting(i, ARD_ANALOG);	// AB: report data
	}
	//ard.sendDigitalPinMode(11, ARD_PWM);		// on diecimelia: 11 pwm?*/
}



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::updateArduino(){

	// update the arduino, get any data or messages:
	ard.update();
	//ard[1].update();
	//ard.sendPwm(11, (int)(128 + 128 * sin(ofGetElapsedTimef())));   // pwm...

	// arduino pins 0 to 5
	for (int x=0; x<6; x++) patchArduino(x);

}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::QCclickChangeMovie(int tempValueInt){
	cout << tempValueInt;
	if (tempValueInt < nVideos) { // valid video thumb
		int x = selectedLayer-1;
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].closeMovie();
		currentVideo[(selectedLayer-1)+(layerSequenceItem[selectedLayer-1]*4)] = tempValueInt;
		videos[x+(layerSequenceItem[x]*4)] = new ofVideoPlayer[nVideos];
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].loadMovie(DirVideos.getPath(currentVideo[x+(layerSequenceItem[x]*4)]));
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setLoopState(OF_LOOP_NORMAL);
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setSpeed(layerSpeed[x]); // sets new video speed
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setVolume(layerVolume[x]); // sets new video volume
		//videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].setPosition(0.001); // sets new video position
		// draws layer thumb
		verticalPosition = 10 + (192 * x);
		videos[x+(layerSequenceItem[x]*4)][currentVideo[x+(layerSequenceItem[x]*4)]].draw(395+(layerSequenceItem[x]*70),verticalPosition,64,48); // draws video thumb
	} // end if valid tempValue
	
}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------



//void testApp::audioReceived 	(float * input, int bufferSize, int nChannels){	
//	// samples are "interleaved"
//	for (int i = 0; i < bufferSize; i++){
//		left[i] = input[i*2];
//		right[i] = input[i*2+1];
//	}
//	bufferCounter++;
//}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------

void testApp::patchArduino(int pin){

	tempValue = ard.getAnalog(pin);

	if (arduinoControlling[pin] == "layerSpeed1") {
		int layerIndex = 0;
		tempValue = tempValue * 5;
		videos[(layerIndex)+(layerSequenceItem[layerIndex]*4)][currentVideo[(layerIndex)+(layerSequenceItem[(layerIndex)]*4)]].setSpeed(tempValue);
		layerSpeed[layerIndex] = tempValue;
		gui->update(kParameter_LayerSpeed1 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerSpeed2") {
		int layerIndex = 1;
		tempValue = tempValue * 5;
		videos[(layerIndex)+(layerSequenceItem[layerIndex]*4)][currentVideo[(layerIndex)+(layerSequenceItem[(layerIndex)]*4)]].setSpeed(tempValue);
		layerSpeed[layerIndex] = tempValue;
		gui->update(kParameter_LayerSpeed2 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerSpeed3") {
		int layerIndex = 2;
		tempValue = tempValue * 5;
		videos[(layerIndex)+(layerSequenceItem[layerIndex]*4)][currentVideo[(layerIndex)+(layerSequenceItem[(layerIndex)]*4)]].setSpeed(tempValue);
		layerSpeed[layerIndex] = tempValue;
		gui->update(kParameter_LayerSpeed3 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerSpeed4") {
		int layerIndex = 3;
		tempValue = tempValue * 5;
		videos[(layerIndex)+(layerSequenceItem[layerIndex]*4)][currentVideo[(layerIndex)+(layerSequenceItem[(layerIndex)]*4)]].setSpeed(tempValue);
		layerSpeed[layerIndex] = tempValue;
		gui->update(kParameter_LayerSpeed4 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "layerOpacity1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity1 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity2 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity3 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity4 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity5") {
		int layerIndex = 4;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity5 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity6") {
		int layerIndex = 5;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity6 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity7") {
		int layerIndex = 6;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity7 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerOpacity8") {
		int layerIndex = 7;
		tempValue = (tempValue / 1023);
		layerOpacity[layerIndex] = tempValue;
		gui->update(kParameter_LayerOpacity8 , kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "layerVolume1") {
		int layerIndex = 0;
		tempValue = tempValue * 100;
		layerVolume[layerIndex] = tempValue;
		videos[layerIndex][currentVideo[layerIndex]].setVolume(layerVolume[layerIndex]);
		gui->update(kParameter_LayerVolume1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerVolume2") {
		int layerIndex = 1;
		tempValue = tempValue * 100;
		layerVolume[layerIndex] = tempValue;
		videos[layerIndex][currentVideo[layerIndex]].setVolume(layerVolume[layerIndex]);
		gui->update(kParameter_LayerVolume2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerVolume3") {
		int layerIndex = 2;
		tempValue = tempValue * 100;
		layerVolume[layerIndex] = tempValue;
		videos[layerIndex][currentVideo[layerIndex]].setVolume(layerVolume[layerIndex]);
		gui->update(kParameter_LayerVolume3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerVolume4") {
		int layerIndex = 3;
		tempValue = tempValue * 100;
		layerVolume[layerIndex] = tempValue;
		videos[layerIndex][currentVideo[layerIndex]].setVolume(layerVolume[layerIndex]);
		gui->update(kParameter_LayerVolume4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "layerPlayhead1") {
		int layerIndex = 0;
		tempValue = tempValue / 1023.0;
		videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setPosition(tempValue);
		gui->update(kParameter_LayerPlayhead1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerPlayhead2") {
		int layerIndex = 1;
		tempValue = tempValue / 1023.0;
		videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setPosition(tempValue);
		gui->update(kParameter_LayerPlayhead2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerPlayhead3") {
		int layerIndex = 2;
		tempValue = tempValue / 1023.0;
		videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setPosition(tempValue);
		gui->update(kParameter_LayerPlayhead3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerPlayhead4") {
		int layerIndex = 3;
		tempValue = tempValue / 1023.0;
		videos[layerIndex+(layerSequenceItem[layerIndex]*4)][currentVideo[layerIndex+(layerSequenceItem[layerIndex]*4)]].setPosition(tempValue);
		gui->update(kParameter_LayerPlayhead4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "timeStep1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023.0) * 480;
		timeStep[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeStep1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeStep2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023.0) * 480;
		timeStep[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeStep2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeStep3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023.0) * 480;
		timeStep[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeStep3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeStep4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023.0) * 480;
		timeStep[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeStep4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "timeBlink1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink5") {
		int layerIndex = 4;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink6") {
		int layerIndex = 5;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink6, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink7") {
		int layerIndex = 6;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink7, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeBlink8") {
		int layerIndex = 7;
		tempValue = (tempValue / 1023.0) * 480;
		timeBlink[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeBlink8, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "timePlayheadRandom1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023.0) * 480;
		timePlayheadRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timePlayheadRandom1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timePlayheadRandom2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023.0) * 480;
		timePlayheadRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timePlayheadRandom2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timePlayheadRandom3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023.0) * 480;
		timePlayheadRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timePlayheadRandom3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timePlayheadRandom4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023.0) * 480;
		timePlayheadRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timePlayheadRandom4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "timeColorRandom1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeColorRandom2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeColorRandom3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeColorRandom4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeColorRandom5") {
		int layerIndex = 4;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	// not 6
	if (arduinoControlling[pin] == "timeColorRandom7") {
		int layerIndex = 6;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom7, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeColorRandom8") {
		int layerIndex = 7;
		tempValue = (tempValue / 1023.0) * 480;
		timeColorRandom[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeColorRandom8, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "timeInvert1") {
		int layerIndex = 0;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert1, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeInvert2") {
		int layerIndex = 1;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert2, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeInvert3") {
		int layerIndex = 2;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert3, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeInvert4") {
		int layerIndex = 3;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert4, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeInvert5") {
		int layerIndex = 4;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert5, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "timeInver7") {
		int layerIndex = 6;
		tempValue = (tempValue / 1023.0) * 480;
		timeInvert[layerIndex] = int (60000/tempValue);
		gui->update(kParameter_timeInvert7, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "masterFader") {
		tempValue = (tempValue / 1023.0);
		masterFader = tempValue / 100;
		gui->update(kParameter_masterFader, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "layerComposite1") {
		int layerIndex = 0;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite1, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerComposite2") {
		int layerIndex = 1;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite2, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerComposite3") {
		int layerIndex = 2;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite1, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerComposite4") {
		int layerIndex = 3;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite3, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerComposite5") {
		int layerIndex = 4;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite4, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "layerComposite7") {
		int layerIndex = 6;
		tempValue = int ( (tempValue / 1023.0) * 7);
		layerBlend[layerIndex] = tempValue;
		gui->update(kParameter_Composite5, kofxGui_Set_Int, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "textHorPos") {
		textHorPos = (screenSizeX * ( (tempValue / 1023) / 100) );
		gui->update(kParameter_textPosX, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "textVertPos") {
		textVertPos = (screenSizeY * ( (tempValue / 1023) / 100) );
		gui->update(kParameter_textPosY, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}

	if (arduinoControlling[pin] == "lightPaintTime") {
		tempValue = (tempValue / 1023); // match arduino input to slider range
		lightPaintTime = tempValue * 1000;
		gui->update(kParameter_lightPaintTime, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "lightPaintStretchX") {
		tempValue = (tempValue / 1023); // match arduino input to slider range
		lightPaintStretchX = tempValue * 1000;
		gui->update(kParameter_lightPaintFeedbackX, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "lightPaintStretchY") {
		tempValue = (tempValue / 1023); // match arduino input to slider range
		lightPaintStretchY = tempValue;
		gui->update(kParameter_lightPaintFeedbackY, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}
	if (arduinoControlling[pin] == "lightPaintStretchSpeed") {
		tempValue = (tempValue / 1023); // match arduino input to slider range
		lightPaintStretchSpeed = tempValue;
		gui->update(kParameter_lightPaintStretchSpeed, kofxGui_Set_Float, &tempValue, sizeof(tempValue)); // draw interface
	}


}

//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------








//    //
//    // live cinema array
//    //
//    for(int x = 0; x < 36; x++){
//	    LCvideos[x] = new ofVideoPlayer[nVideos]; // 36 video player instances
//	    currentVideo[x] = 1;
//	    videos[x][currentVideo[x]].loadMovie('interface/null.mov');
//      videos[x][currentVideo[x]].idleMovie();
//	}


//
// thumbnails setup
//
//QCchangeFolder();
//QCvideoThumbs();




//    // draws layer thumbs
//    for (int line = 0; line < 4; line++){
//        for (int column = 0; column < 4; column++){
//            int verticalPosition = 10 + (192 * line);
//            ofFill(); ofSetColor(0,255,0); // green
//            ofRect(395+(layerSequenceItem[line]*70),58+(line*192),64,6); // active sequence item light
//            ofSetColor(255,255,255);
//            videos[line+(column*4)][currentVideo[line+(column*4)]].draw(395+(column*70),verticalPosition,64,48); // draws video thumb
//        }
//    }
// end QClayerThumbs



//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------------------


void testApp::handleGui(int parameterId, int task, void* data, int length){
    //cout << "handleGui running. frame: " << ofGetFrameNum() << "\n";
    //cout << "parameter Id: " << parameterId << "\n";
	switch (parameterId){

			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//                                  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//       main module Gui            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			//                                  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		case kParameter_Panel1a: case kParameter_Panel2a: case kParameter_Panel3a: case kParameter_Panel4a:
		case kParameter_Panel5a: case kParameter_Panel6a: case kParameter_Panel7a: case kParameter_Panel8a:
		case kParameter_Panel1b: case kParameter_Panel2b: case kParameter_Panel3b: case kParameter_Panel4b:
		case kParameter_Panel5b: case kParameter_Panel6b: case kParameter_Panel7b: case kParameter_Panel8b:
		case kParameter_Panel1c: case kParameter_Panel2c: case kParameter_Panel3c: case kParameter_Panel4c:
		case kParameter_lightPaintPanel:
            break;

		case kParameter_LayerSpeed1:
			if(task == kofxGui_Set_Float) {
				videos[(0)+(layerSequenceItem[0]*4)][currentVideo[(0)+(layerSequenceItem[(0)]*4)]].setSpeed(*(float*)data);
				layerSpeed[0] = *(float*)data;
			}
			// arduino patching
			for (int x = 0; x<6; x++) {
				if (arduinoPatching[x] == true) {
					arduinoControlling[x] = "layerSpeed1";
					arduinoPatching[x] = false;
				} // end if
			} // end for
			break;

        case kParameter_LayerSpeed2:
			if(task == kofxGui_Set_Float)
				videos[1+(layerSequenceItem[1]*4)][currentVideo[1+(layerSequenceItem[1]*4)]].setSpeed(*(float*)data);
			layerSpeed[1] = *(float*)data;;
			break;
        case kParameter_LayerSpeed3:
			if(task == kofxGui_Set_Float)
				videos[2+(layerSequenceItem[2]*4)][currentVideo[2+(layerSequenceItem[2]*4)]].setSpeed(*(float*)data);
			layerSpeed[2] = *(float*)data;
			break;
        case kParameter_LayerSpeed4:
			if(task == kofxGui_Set_Float)
				videos[3+(layerSequenceItem[3]*4)][currentVideo[3+(layerSequenceItem[3]*4)]].setSpeed(*(float*)data);
			layerSpeed[3] = *(float*)data;
			break;

		case kParameter_LayerOpacity1:
			if(task == kofxGui_Set_Float) layerOpacity[0] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity1"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity2:
			if(task == kofxGui_Set_Float) layerOpacity[1] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity2"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity3:
			if(task == kofxGui_Set_Float) layerOpacity[2] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity3"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity4:
			if(task == kofxGui_Set_Float) layerOpacity[3] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity4"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity5:
			if(task == kofxGui_Set_Float) layerOpacity[4] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity5"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity6:
			if(task == kofxGui_Set_Float) layerOpacity[5] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity6"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity7:
			if(task == kofxGui_Set_Float) layerOpacity[6] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity7"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerOpacity8:
			if(task == kofxGui_Set_Float) layerOpacity[7] = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerOpacity8"; arduinoPatching[x] = false; } } // arduino patching
			break;

        case kParameter_LayerPlayhead1:
			if(task == kofxGui_Set_Float) videos[0+(layerSequenceItem[0]*4)][currentVideo[0+(layerSequenceItem[0]*4)]].setPosition(*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerPlayhead1"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerPlayhead2:
			if(task == kofxGui_Set_Float) videos[1+(layerSequenceItem[1]*4)][currentVideo[1+(layerSequenceItem[1]*4)]].setPosition(*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerPlayhead2"; arduinoPatching[x] = false; } } // arduino patching

			break;
        case kParameter_LayerPlayhead3:
			if(task == kofxGui_Set_Float) videos[2+(layerSequenceItem[2]*4)][currentVideo[2+(layerSequenceItem[2]*4)]].setPosition(*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerPlayhead3"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerPlayhead4:
			if(task == kofxGui_Set_Float) videos[3+(layerSequenceItem[3]*4)][currentVideo[3+(layerSequenceItem[3]*4)]].setPosition(*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerPlayhead4"; arduinoPatching[x] = false; } } // arduino patching
			break;

        case kParameter_LayerVolume1:
			if(task == kofxGui_Set_Float) layerVolume[0] = (*(float*)data);
			videos[0][currentVideo[0]].setVolume(layerVolume[0]);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerVolume1"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerVolume2:
			if(task == kofxGui_Set_Float) layerVolume[1] = (*(float*)data);
			videos[1][currentVideo[1]].setVolume(layerVolume[1]);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerVolume2"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerVolume3:
			if(task == kofxGui_Set_Float) layerVolume[2] = (*(float*)data);
			videos[2][currentVideo[2]].setVolume(layerVolume[2]);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerVolume3"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_LayerVolume4:
			if(task == kofxGui_Set_Float) layerVolume[3] = (*(float*)data);
			videos[3][currentVideo[3]].setVolume(layerVolume[3]);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerVolume4"; arduinoPatching[x] = false; } } // arduino patching
			break;

        case kParameter_LayerColor1:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[0] = tempColor.r; layerGreen[0] = tempColor.g; layerBlue[0] = tempColor.b;
			break;
        case kParameter_LayerColor2:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[1] = tempColor.r; layerGreen[1] = tempColor.g; layerBlue[1] = tempColor.b;
			break;
        case kParameter_LayerColor3:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[2] = tempColor.r; layerGreen[2] = tempColor.g; layerBlue[2] = tempColor.b;
			break;
        case kParameter_LayerColor4:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[3] = tempColor.r; layerGreen[3] = tempColor.g; layerBlue[3] = tempColor.b;
			break;
        case kParameter_LayerColor5:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[4] = tempColor.r; layerGreen[4] = tempColor.g; layerBlue[4] = tempColor.b;
			break;
        case kParameter_LayerColor6:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[5] = tempColor.r; layerGreen[5] = tempColor.g; layerBlue[5] = tempColor.b;
			break;
        case kParameter_LayerColor7:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[6] = tempColor.r; layerGreen[6] = tempColor.g; layerBlue[6] = tempColor.b;
			break;
        case kParameter_LayerColor8:
            if(task == kofxGui_Set_Color)
				tempColor = *(ofRGBA*)data;
			layerRed[7] = tempColor.r; layerGreen[7] = tempColor.g; layerBlue[7] = tempColor.b;
			break;

        case kParameter_timeStep1:
			if(task == kofxGui_Set_Float) timeStep[0] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeStep1"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_timeStep2:
			if(task == kofxGui_Set_Float) timeStep[1] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeStep2"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_timeStep3:
			if(task == kofxGui_Set_Float) timeStep[2] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeStep3"; arduinoPatching[x] = false; } } // arduino patching
			break;
        case kParameter_timeStep4:
			if(task == kofxGui_Set_Float) timeStep[3] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeStep4"; arduinoPatching[x] = false; } } // arduino patching
			break;

        case kParameter_timeBlink1:
            if(task == kofxGui_Set_Float) timeBlink[0] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink1"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink2:
            if(task == kofxGui_Set_Float) timeBlink[1] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink2"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink3:
            if(task == kofxGui_Set_Float) timeBlink[2] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink3"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink4:
            if(task == kofxGui_Set_Float) timeBlink[3] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink4"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink5:
            if(task == kofxGui_Set_Float) timeBlink[4] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink5"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink6:
            if(task == kofxGui_Set_Float) timeBlink[5] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink6"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink7:
            if(task == kofxGui_Set_Float) timeBlink[6] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink7"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeBlink8:
            if(task == kofxGui_Set_Float) timeBlink[7] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeBlink8"; arduinoPatching[x] = false; } } // arduino patching
            break;

        case kParameter_timePlayheadRandom1:
            if(task == kofxGui_Set_Float) timePlayheadRandom[0] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timePlayheadRandom1"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timePlayheadRandom2:
            if(task == kofxGui_Set_Float) timePlayheadRandom[1] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timePlayheadRandom2"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timePlayheadRandom3:
            if(task == kofxGui_Set_Float) timePlayheadRandom[2] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timePlayheadRandom3"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timePlayheadRandom4:
            if(task == kofxGui_Set_Float) timePlayheadRandom[3] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timePlayheadRandom4"; arduinoPatching[x] = false; } } // arduino patching
            break;

        case kParameter_timeColorRandom1:
            if(task == kofxGui_Set_Float) timeColorRandom[0] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor1"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom2:
            if(task == kofxGui_Set_Float) timeColorRandom[1] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor2"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom3:
            if(task == kofxGui_Set_Float) timeColorRandom[2] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor3"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom4:
            if(task == kofxGui_Set_Float) timeColorRandom[3] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor4"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom5:
            if(task == kofxGui_Set_Float) timeColorRandom[4] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor5"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeRot3D:
            if(task == kofxGui_Set_Float) timeRot3D = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeRot3D"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom7:
            if(task == kofxGui_Set_Float) timeColorRandom[6] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor7"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeColorRandom8:
            if(task == kofxGui_Set_Float) timeColorRandom[7] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeColor"; arduinoPatching[x] = false; } } // arduino patching
            break;

        case kParameter_timeInvert1:
            if(task == kofxGui_Set_Float) timeInvert[0] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert1"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeInvert2:
            if(task == kofxGui_Set_Float) timeInvert[1] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert2"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeInvert3:
            if(task == kofxGui_Set_Float) timeInvert[2] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert3"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeInvert4:
            if(task == kofxGui_Set_Float) timeInvert[3] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert4"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeInvert5:
            if(task == kofxGui_Set_Float) timeInvert[4] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert5"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_timeSize3D:
            if(task == kofxGui_Set_Float) timeSize3D = int (60000/(*(float*)data));
            break;
        case kParameter_timeInvert7:
            if(task == kofxGui_Set_Float) timeInvert[6] = int (60000/(*(float*)data));
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "timeInvert7"; arduinoPatching[x] = false; } } // arduino patching
            break;

        case kParameter_Composite1:
            if(task == kofxGui_Set_Int) layerBlend[0] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite1"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_Composite2:
            if(task == kofxGui_Set_Int) layerBlend[1] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite2"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_Composite3:
            if(task == kofxGui_Set_Int) layerBlend[2] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite3"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_Composite4:
            if(task == kofxGui_Set_Int) layerBlend[3] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite4"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_Composite5:
            if(task == kofxGui_Set_Int) layerBlend[4] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite5"; arduinoPatching[x] = false; } } // arduino patching
            break;
        case kParameter_Composite6:
            if(task == kofxGui_Set_Int) layerBlend[5] = (*(int*)data);
            break;
        case kParameter_Composite7:
            if(task == kofxGui_Set_Int) layerBlend[6] = (*(int*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "layerComposite7"; arduinoPatching[x] = false; } } // arduino patching
            break;
			// master fader
        case kParameter_masterFader:
            if(task == kofxGui_Set_Float) masterFader = ((*(float*)data)/100.0);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "masterFader"; arduinoPatching[x] = false; } } // arduino patching
            break;
			// text position
		case kParameter_textPosX:
			if(task == kofxGui_Set_Float) textHorPos = screenSizeX*((*(float*)data)/100);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "textHorPos"; arduinoPatching[x] = false; } } // arduino patching
			break;
		case kParameter_textPosY:
			if(task == kofxGui_Set_Float) textVertPos = screenSizeY*((*(float*)data)/100);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "textVertPos"; arduinoPatching[x] = false; } } // arduino patching
			break;
		// light paint time
		case kParameter_lightPaintTime:
			if(task == kofxGui_Set_Float) lightPaintTime = int ((*(float*)data)*1000);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "lightPaintTime"; arduinoPatching[x] = false; } } // arduino patching
			break;
		case kParameter_lightPaintFeedbackX:
			if(task == kofxGui_Set_Float) lightPaintStretchX = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "lightPaintStretchX"; arduinoPatching[x] = false; } } // arduino patching
			break;
		case kParameter_lightPaintFeedbackY:
			if(task == kofxGui_Set_Float) lightPaintStretchY = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "lightPaintStretchY"; arduinoPatching[x] = false; } } // arduino patching
			break;
		case kParameter_lightPaintStretchSpeed:
			if(task == kofxGui_Set_Float) lightPaintStretchSpeed = (*(float*)data);
			for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "lightPaintStretchSpeed"; arduinoPatching[x] = false; } } // arduino patching
			break;
			
		case kParameter_LayerContrast4:
			if(task == kofxGui_Set_Float) layerContrast4 = (*(float*)data);
			//for (int x=0;x<6;x++) { if(arduinoPatching[x]==1) { arduinoControlling[x] = "lightPaintStretchSpeed"; arduinoPatching[x] = false; } } // arduino patching
			break;
			

	} // end switch
}



/// temp stuff

// flip

// setup openCV
//colorImg.setFromPixels(vidGrabber.getPixels(), vidGrabber.width, vidGrabber.height);
//grayImage = colorImg;

//if (bLearnBakground == true){
//	grayBg = grayImage;		// the = sign copys the pixels from grayImage into grayBg (operator overloading)
//	bLearnBakground = false;
//}
// take the abs value of the difference between background and incoming and then threshold:
//grayDiff.absDiff(grayBg, grayImage);
//grayDiff.threshold(threshold);
// find contours which are between the size of 20 pixels and 1/3 the w*h pixels. also, find holes is set to true so we will get interior contours as well....
//contourFinder.findContours(grayDiff, 20, ((vidGrabber.width)*( vidGrabber.height))/3, 10, true);	// find holes
//ofSetColor(0xffffff);
//colorImg.draw(interfaceSizeX,0,screenSizeX,screenSizeY);
//grayImage.draw(interfaceSizeX,0,screenSizeX,screenSizeY);

// we could draw the whole contour finder
//contourFinder.draw(interfaceSizeX,0,screenSizeX,screenSizeY);

// or, instead we can draw each blob individually,
// this is how to get access to them:
//for (int i = 0; i < contourFinder.nBlobs; i++){
//	contourFinder.blobs[i].draw(interfaceSizeX,0);
//}
