#ifndef TYPES_H
#define TYPES_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <alsa/asoundlib.h>
#include <alsa/mixer.h>
#include <alsa/pcm.h>
#include <time.h>


//define structs and functions for creating/destroying


typedef struct {

	//dimensions
	uint16_t x;
	uint16_t y;
	uint16_t w;
	uint16_t h;
	float dividex;
	float dividey;
	float dividew;
	float divideh;
	
	uint16_t savex;
	uint16_t savey;
	uint16_t savew;
	uint16_t saveh;

	//color
	uint8_t r;
	uint8_t g;
	uint8_t b;
	uint8_t a;
	uint8_t r2;
	uint8_t g2;
	uint8_t b2;
	uint8_t a2;
	float shade;

	//image if provided
	SDL_Texture* texture;
	SDL_Texture* texture2;
	int texture2_w;
	int texture2_h;

	//what happens when you
	//click on button
	uint8_t actionType;
	uint8_t sliderType;
	float slide;

	//text
	char* text;
	uint16_t textx;
	uint16_t texty;

	//flags n shit
	bool active;
	bool hover;
	bool stretchWidth;
	bool stretchHeight;
	bool offsetX;
	bool offsetY;
	bool offsetW;
	bool offsetH;

	//stuff for lists/menus
	bool list;
	uint16_t listNum;
	uint16_t listOffset;

} Widget;


typedef struct {

	char* PCM_DEVICE;
	snd_pcm_t* pcm_handle;
	snd_pcm_sframes_t g_frames;
	snd_pcm_format_t format;
	int rate;
	int channels;

	unsigned int pcm, tmp, dir;
	snd_pcm_hw_params_t* params;
	snd_pcm_uframes_t frames;
	int8_t* buff;
	int buff_size;
	int readfd;
	int readval;
	int rms;

	double rateDelay;

} AlsaData;


typedef struct {

	SDL_Event event;

	//player
	char* file;
	bool quit;
	bool stop;
	bool playing;
	uint16_t delay;
	SDL_Texture* background;
	char* font;
	char* bgimage;

	//files
	uint32_t fileIndex;
	uint32_t fileSize;
	uint32_t fileCount;
	uint32_t fileTarget;
	char* fileList[1024];
	uint32_t fileCountCopy;
	char* fileListCopy[1024];
	char fileSearch[64];
	uint8_t fileSearchIndex;
	char* dragFile;
	

	//images	
	uint16_t imageNum;
	char* imageList[128];
	char* imageStr[128];

	//input
	uint8_t key;
	int x;
	int y;
	Widget* widgetTarget;

	//graphical stuff
	uint16_t w;
	uint16_t h;
	uint8_t waveFreq;
	uint8_t waveAmp;
	bool waveVert;
	bool waveFade;
	uint8_t r;
	uint8_t g;
	uint8_t b;

	//audio
	float volume;
	uint32_t rate;
	uint8_t rateInputIndex;
	char rateStr[6];

} PlayerData;


//sample in this sense means an 
//audio object to be manipulated
//in the DAW, not a literal wav sample
typedef struct {

	bool playing;
	
	//flag to not double free data
	bool copy;
	bool copySource;
	uint8_t fileIndex;

	uint8_t track;
	uint8_t channel;
	uint8_t flags;
	uint32_t beatOffset;
	uint32_t beatLength;
	
	uint32_t cropOffset;
	uint32_t beatCropFront;
	uint32_t beatCropBack;
	
	uint8_t* data;
	uint32_t dataOffset;
	uint32_t dataSize;
	double seconds;

	uint32_t color;
	uint8_t* dataPoints;
	uint32_t dataSizeGUI;
} Sample;


typedef struct {

	bool active;
	char projectFile[128];
	uint8_t projectFileIndex;

	//tool selection
	uint8_t mode;

	//1 beat is 1 quarter note
	//4 beats in 1 bar
	uint16_t bpm;
	char bpmStr[8];
	double spb;

	//for timing bpm and audio sync
	struct timeval t1;
	struct timeval t0;
	
	//audio frame
	uint8_t* frame;

	//all audio file names and data
	Sample* samples[65535];
	char* files[65535];
	uint16_t sampleNum;
	uint16_t fileNum;
	Sample* sampleTarget;
	Sample* sampleLastClicked;
	

	//# of beats of audio
	uint32_t beatLength;
	uint32_t targetBeat;
	uint32_t previousBeat;
	uint32_t currentBeat;
	uint8_t intrabeatOffset;

	//gui (scroll is measured in beats)
	uint32_t projectLength;
	uint32_t scrollLength;
	uint32_t scrollOffset;
	bool autoScroll;

	//audio tracks
	uint32_t previousTrack;
	uint32_t currentTrack;

} TimelineData;





void CreateWidget(uint16_t x, uint16_t y, 
		uint16_t w, uint16_t h,
		uint32_t color, uint32_t color2, float shade,
		bool active, bool stretchWidth, bool stretchHeight,
		bool offsetX, bool offsetY, bool offsetW, bool offsetH,
		uint8_t dividex, uint8_t dividey, uint8_t dividew, uint8_t divideh,
		char* text, uint16_t textx, uint16_t texty,
		char* image, char* image2,
		uint8_t actionType, uint8_t sliderType,
		SDL_Renderer* renderer,
		Widget* arr[256], uint8_t* widgetNum);
void DestroyWidget(uint8_t deleteIndex, Widget* arr[256], uint8_t* widgetNum);
void DestroyWidgets(Widget* arr[256], uint8_t* widgetNum);


AlsaData* InitAlsaData();
void DestroyAlsaData(AlsaData* data);


PlayerData* InitPlayerData();
void DestroyPlayerData(PlayerData* data);


TimelineData* InitTimelineData(AlsaData* alsa_data);
void DestroyTimelineData(TimelineData* data);


Sample* CreateSample(char* audio_file, TimelineData* timeline, Sample* copySample, 
			uint32_t beatOffset, uint32_t cropOffset, 
			uint32_t beatCropFront, uint32_t beatCropBack,
			uint8_t track);
void DestroySample(Sample* sample);


#endif
