#ifndef _TEST_APP
#define _TEST_APP

#include "ofMain.h"

#include "ofx3DModelLoader.h"
#include "ofxDirList.h"
#include "ofxGui.h"
#include "ofxVectorMath.h"
#include "ofxXmlSettings.h"
#include "math.h"
#include "time.h"
#include "stdio.h"
#include "ofxOpenCv.h"
#include "ofxOsc.h"
//#include "fft.h"

#ifdef TARGET_WIN32
    #include "ofxQtVideoSaver.h"
	#include "winUtils.h" //utils for fake horz span on win32
#elif defined(TARGET_OSX)
    #include "ofxQtVideoSaver.h"
#elif defined(TARGET_LINUX)
    // no video saver
#endif

// OSC listen on port 12345
#define PORT 12345

// FFT1
//#define BUFFER_SIZE 256
//#define NUM_WINDOWS 80

class testApp : public ofBaseApp, public ofxGuiListener{

	enum {

        ///////////////////////////////
        //
        //  ofxGui.xml
        //  and ofxLiveCinema.xml
        //  connections:
        //
        ///////////////////////////////

		kParameter_Panel1a, //id 0
		kParameter_Panel2a, //id 1
		kParameter_Panel3a, //id 2
		kParameter_Panel4a, //id 3
		kParameter_Panel5a, //id 4
		kParameter_Panel6a, //id 5
		kParameter_Panel7a, //id 6
		kParameter_Panel8a, //id 7

		kParameter_LayerSpeed1, //id 8
		kParameter_LayerSpeed2, //id 9
		kParameter_LayerSpeed3, //id 10
		kParameter_LayerSpeed4, //id 11
		kParameter_LayerSpeed5, //id 12
		kParameter_LayerSpeed6, //id 13
		kParameter_LayerSpeed7, //id 14
		kParameter_LayerSpeed8, //id 15

		kParameter_LayerOpacity1, //id 16
		kParameter_LayerOpacity2, //id 17
		kParameter_LayerOpacity3, //id 18
		kParameter_LayerOpacity4, //id 19
		kParameter_LayerOpacity5, //id 20
		kParameter_LayerOpacity6, //id 21
		kParameter_LayerOpacity7, //id 22
		kParameter_LayerOpacity8, //id 23

		kParameter_LayerPlayhead1, //id 24
		kParameter_LayerPlayhead2, //id 25
		kParameter_LayerPlayhead3, //id 26
		kParameter_LayerPlayhead4, //id 27

        kParameter_Panel1b, //id 28
        kParameter_Panel2b, //id 29
        kParameter_Panel3b, //id 30
        kParameter_Panel4b, //id 31
        kParameter_Panel5b, //id 32
        kParameter_Panel6b, //id 33
        kParameter_Panel7b, //id 34
        kParameter_Panel8b, //id 35

        kParameter_LayerColor1, //id 36
        kParameter_LayerColor2, //id 37
        kParameter_LayerColor3, //id 38
        kParameter_LayerColor4, //id 39

        kParameter_LayerVolume1, //id 40
        kParameter_LayerVolume2, //id 41
        kParameter_LayerVolume3, //id 42
        kParameter_LayerVolume4, //id 43

        kParameter_Panel1c, // id 44
        kParameter_Panel2c, // id 45
        kParameter_Panel3c, // id 46
        kParameter_Panel4c, // id 47

        kParameter_timeStep1, // id 48
        kParameter_timeStep2, // id 49
        kParameter_timeStep3, // id 50
        kParameter_timeStep4, // id 51

        kParameter_LayerColor5, // id 52
        kParameter_LayerColor6, // id 53
        kParameter_LayerColor7, // id 54
        kParameter_LayerColor8, // id 55

        kParameter_timeBlink1, // id 56
        kParameter_timeBlink2, // id 57
        kParameter_timeBlink3, // id 58
        kParameter_timeBlink4, // id 59
        kParameter_timeBlink5, // id 60
        kParameter_timeBlink6, // id 61
        kParameter_timeBlink7, // id 62
        kParameter_timeBlink8, // id 63

        kParameter_timePlayheadRandom1, // id 64
        kParameter_timePlayheadRandom2, // id 65
        kParameter_timePlayheadRandom3, // id 66
        kParameter_timePlayheadRandom4, // id 67

        kParameter_timeColorRandom1, // id 68
        kParameter_timeColorRandom2, // id 69
        kParameter_timeColorRandom3, // id 70
        kParameter_timeColorRandom4, // id 71
        kParameter_timeColorRandom5, // id 72
        kParameter_timeRot3D, // id 73
        kParameter_timeColorRandom7, // id 74
        kParameter_timeColorRandom8, // id 75

        kParameter_timeInvert1, //id 76
        kParameter_timeInvert2, //id 77
        kParameter_timeInvert3, //id 78
        kParameter_timeInvert4, //id 79
        kParameter_timeInvert5, //id 80
        kParameter_timeSize3D, //id 81
        kParameter_timeInvert7, //id 82
        kParameter_textPosX, //id 83

        kParameter_Composite1, //id 84
        kParameter_Composite2, //id 85
        kParameter_Composite3, //id 86
        kParameter_Composite4, //id 87
        kParameter_Composite5, //id 88
        kParameter_Composite6, //id 89
        kParameter_Composite7, //id 90
        kParameter_Composite8, //id 91

        // main module, master fader
        kParameter_masterFaderPanel, //id 92
        kParameter_masterFader, //id 93

		kParameter_textPosY, // id 94


		// light paint connections:

		kParameter_lightPaintPanel, // id 95
		kParameter_lightPaintTime, // id 96
		kParameter_lightPaintFeedbackX, // id 97
		kParameter_lightPaintFeedbackY, // id 98
		kParameter_lightPaintStretchSpeed, // id 99
		kParameter_LayerContrast4 // id 100

		//


        // ids have  to be in sequencial order !
		// last parameter, without comma at end of the last line

    };

public:

	//
	// platform dependant
	//

	int eraseChars;
	int eraseCharsAudio;

	//
	// general
	//

    void setup();
    void update();
    void draw();

    void keyPressed  (int key);
    void keyReleased (int key);

    void mouseMoved(int x, int y );
    void mouseDragged(int x, int y, int button);
    void mousePressed(int x, int y, int button);
    void mouseReleased(int x, int y, int button);
    void windowResized(int w, int h);

	// QC
	void QCchangeResolution();
	void QCredrawInterface();
    void QCredrawInterfaceText();
    void QCvideoThumbs();
    void QClayerThumbs();
    void QCchangeFolder();
    void QCchangeFolderStep();
    void QCchangePageStep();
    void QCchangeFolderStepPrepare();
    void QCchangePageStepPrepare();
    void QCupdateSpeedBar();
    void QCupdatePlayhead(int layerInfluenced, float x);
    void QCupdateColorSlider(int layerInfluenced, float x);
    void QCchangeSequenceItem(int x);
    void QClistDirs();
    void QClistDirsAudio();
	void QClistDirsDraw();
    void QClistAudioOpenDir();
	void QClistDirsAudioDraw();
	void QClistClipsAudioDraw();
    void QCchangeFont();
    void QCresetTimers();
	void QCstopMoviesMainModule();
	void QCstopOneMovie();
	void QCstopMovieOnLayer(int x);
	void QCresumeCurrentMovie();
	void QCresumeCurrentMovieOnLayer(int x);
	void QCinitWebcam();
	void QCrecordingPrepare();
	void QCtimeDisplay();
	void QCclickChangeMovie(int x);
	//void QCdirUpdate();


    //
    // interface
    //
    ofImage         splashScreen;
    ofImage         interfaceBackground;
    ofImage         interfaceLayers;
    ofImage         interfaceNeutralLayers;
    ofImage         layerOutlineA;
    ofImage         layerOutlineB;
    ofImage         iconAudio;
    ofImage         iconHelp;
    ofImage         iconAudioFile;
    ofImage         iconPageActive;
    ofImage         iconPageNotActive;
	ofImage			iconLightPaintOn;
	ofImage			iconLightPaintOff;
	ofImage			iconLightPaintFeedOn;
	ofImage			iconLightPaintFeedOff;
	ofImage			iconLightPaintMirrorOn;
	ofImage			iconLightPaintMirrorOff;
    int             redrawInterface;
    int             thumbsVertPos;
    int             thumbsHorPos;
    //int             clearThumbs;
    float           masterFader;
	char			languageCode[1];
	bool			bFullscreen;
	int				checkX;
	int				checkY;
	int				checkWidth;
	int				checkHeight;
	int				screenSizeIndex;
	int				interfaceSizeIndex;
	int				screenSizeX, screenSizeY;
	int				interfaceSizeX, interfaceSizeY;
	int				verticalPosition;
	//int				horizontalPosition;
	bool			showBinDurations;



    //
    // video playback
    //
    int             currentVideo[16]; // smart array video 1 slots: 1, 5, 9, 13 ... video 2 slots: 2, 6, 10, 14...
    int             currentThumb[1];
    int             videoThumbsPage;
    int             currentVideoThumb; // draw
    int             selectedLayer; // possible values: 1 to 8
    int             layerVisibility[8];
    float           layerSpeed[4];
    float           layerOpacity[8];
    float           layerRed[8];
    float           layerGreen[8];
    float           layerBlue[8];
    //string        layerSpeedString[4];
    int             layerBlend[8];
    float           layerVolume[4];
	bool			layerFlip[8];
    int             previewMonitor;
    int             previewFull;
    int             layerSequenceEnabled[4];
    int             layerSequenceItem[4];
    ofTexture		texScreen; // full preview texture



    //
    // video directories
    //
    ofVideoPlayer * videos[16];
    ofVideoPlayer * videoThumbs;
    ofxDirList      DirFolders;
    ofxDirList      DirVideos;
    int             browsingDirs;
    int             browsingDirsPage;
    int             browsingClips;
    int             nFolders;
    int             currentFolderNum;
    int             nVideos;
    int             nVideosLimited;



	//
    // stepping video loading
    //
    int             videoLoading;
    int             videoLoadingNewPage;
    int             videoLoadStep;
    int             audioLoading;
    int             audioLoadStep;



    //
    // audio
    //
    ofSoundPlayer   audioChannel1;
    ofSoundPlayer   audioChannel2;
    ofxDirList      DirAudioFolders;
    ofxDirList      DirAudioFiles;
    int             browsingAudioDirs;
    int             browsingAudioDirsPage;
    int             browsingAudioClips;
    int             nAudioFolders;
    int             currentAudioFolderNum;
    int             nAudioFiles;
    int             nAudioFilesLimited;
    int             audioThumbsPage;
    int             currentAudioThumb; // draw
    int             selectedAudioChannel;



    //
    // images
    //
    int 		nImages;
    ofImage	* 	images;
    ofxDirList  DirImages;
    int         currentImage;



    //
    // livecam
    //
	bool				bWebcamInit;
    int                 livecam;
    int                 livecamAlpha;
    ofVideoGrabber 		vidGrabber;
	int                 livecamDevice;
    unsigned char * 	videoInverted;
    ofTexture			videoTexture;
    int 				camWidth, camHeight;
	int					layerContrast4;



    //
    // effects
    //
    unsigned char * 	videoInvert1B;
    ofTexture           videoInvert1A;
    int                 w, h;
    int                 layerInvert[8];
    unsigned char * 	imageInvert1B;
    ofTexture           imageInvert1A;
	unsigned char * 	videoFlipB;
    ofTexture           videoFlipA;


    //
    // image saver
    //
    bool 				bSnapshot;
    ofImage             img;
    int 				snapCounter;
    //char 				snapString[255];



	//
	// movie saver
	//
	bool    QCmovieSaver;
	char    fileNameSufix[255];
	char    helpText[255];


	#ifdef TARGET_LINUX
		// nothing
	#else // Mac and Windows
        bool				bRecording;
        ofxQtVideoSaver		saver;
        ofImage				imageToSave;
    #endif


    //
    // 3D
    //
    ofx3DModelLoader    object3D;
    bool                bMousePressed;
	float				size3D;
	float				rot3D;
	int					rot3DAxis;



    //
    // text
    //
    char                textInput[20];
    ofTrueTypeFont      fontArialBlack18;
    ofTrueTypeFont      fontArialBlack48;
    ofTrueTypeFont      fontArialBlack64;
    ofTrueTypeFont      fontArialBlack72;
	ofTrueTypeFont      fontAutomat6, fontAutomat8;
    ofTrueTypeFont      fontVerdana8;
	ofTrueTypeFont      fontVerdana10;
    ofTrueTypeFont      fontVerdana11;
    ofTrueTypeFont      fontArial18;
    ofTrueTypeFont      fontArial64;
    ofTrueTypeFont      fontAsimov18;
    ofTrueTypeFont      fontAsimov64;
    ofTrueTypeFont      fontGreek18;
    ofTrueTypeFont      fontGreek64;
    ofTrueTypeFont      fontGoodtime18;
    ofTrueTypeFont      fontGoodtime64;
    ofTrueTypeFont      fontSteppes18;
    ofTrueTypeFont      fontSteppes64;
    ofTrueTypeFont      fontTimes18;
    ofTrueTypeFont      fontTimes64;
    int                 textHorPos;
    int                 textVertPos;
    int                 currentFont;
    int                 textInputActive;
    int                 textInputCharPos;



    //
    // ofxGui
    //
	void		handleGui(int parameterId, int task, void* data, int length);
    float       tempValue;
	ofRGBA      tempColor;
	float		speed;
	ofxGui*		gui;



	//
	// timers
	//
	long   currentTime;
	unsigned long   timeStep[4];
	unsigned long   previousTimeStep[4];
	unsigned long   timeBlink[8];
	unsigned long   previousTimeBlink[8];
	unsigned long   timePlayheadRandom[4];
	unsigned long   previousTimePlayheadRandom[4];
	unsigned long   timeColorRandom[8];
	unsigned long   previousTimeColorRandom[8];
	unsigned long   timeInvert[8];
	unsigned long   previousTimeInvert[8];
	unsigned long   timeSize3D;
	unsigned long   previousTimeSize3D;
	unsigned long   timeRot3D;
	unsigned long   previousTimeRot3D;
	int             layerInfluenced;
	//int         layerComposite[8];
	
	

	//
	// light paint
	//
	bool			lightPaint[8];
	unsigned long	lightPaintTime;
	unsigned long	previousLightPaintTime;
	unsigned long	lightPaintRetrigger;
	unsigned long	offLightPaintTime;
	float			lightPaintStretchX;
	float			lightPaintStretchY;
	float			lightPaintStretchXadd;
	float			lightPaintStretchYadd;
	float			lightPaintStretchSpeed;
	bool			lightPaintFeedback;


	//
	// arduino
	//
	void		setupArduino();
	void		updateArduino();
	void		patchArduino(int pin);
	ofArduino	ard;
	bool		bSetupArduino;			// flag variable for setting up arduino once
	bool		arduinoIsSet;
	bool		arduinoPatching[6];
	string		arduinoControlling[6];


	//
	// openCV variables
	//
	ofxCvColorImage			colorImg;
	ofxCvGrayscaleImage 	grayImage;
	ofxCvGrayscaleImage 	grayBg;
	ofxCvGrayscaleImage 	grayDiff;
	ofxCvContourFinder		contourFinder;
	int						threshold;
	bool					bLearnBakground;


	//
	// other variables
	//
	int			tempValueInt;
	string		tempString;
	string		tempStringAudio;
	
	
	// OSC	
	ofxOscReceiver	receiver;
	
	// FFT1
//	void		audioReceived 	(float * input, int bufferSize, int nChannels); 
//			
//	float *	left;
//	float * right;
//	int 	bufferCounter;
//	fft		myfft;
//	
//	float	magnitude[BUFFER_SIZE];
//	float	phase[BUFFER_SIZE];
//	float	power[BUFFER_SIZE];
//	
//	float	freq[NUM_WINDOWS][BUFFER_SIZE/2];
//	float	freq_phase[NUM_WINDOWS][BUFFER_SIZE/2];
//	
//	float	avg_power;
	
	// FFT2
	
//	void	audioReceived 	(float * input, int bufferSize, int nChannels); 
//	float * left;
//	float * right;
//	float * fftSmoothed;
//	int		nBandsToGet;
//	int		numberOfFreqsToGet;
	
	
	// fps average
	
	unsigned long   previousTimeFpsAverage;
	long			frameCountFpsAverage;
	
	
};

#endif

