#include "../include/player.h"




/*
int OpenFileForPlay(PlayerData* player_data, AlsaData* alsa_data) {

	alsa_data->readfd = open(player_data->file, O_RDONLY);

	if (alsa_data->readfd < 0) {
	
		if (player_data->quit == false) {
		
			printf("ERROR: The file \"%s\" couldn't be read or doesn't exist.\n", player_data->file);
			player_data->file = NULL;
		}
		return -1;
	}

	//default params for 44.1 khz 16 bit stero audio
	WavPreparePCM(alsa_data, player_data->rate, 2, 2);

	FILE* ftype;
	ftype = fopen(player_data->file, "r");
	fseek(ftype, 0, SEEK_END);
	player_data->fileSize = ftell(ftype) / alsa_data->buff_size;
	fseek(ftype, 0, SEEK_SET);
	fclose(ftype);

	//update widget with text for current file name and size
	char sizeStr[20];
	sprintf(sizeStr, "%d", player_data->fileSize);

	for (int i = 0; i < widgetNum; i++) {
	
		
		switch (widgetArr[i]->actionType) {
		
			case 0:UpdateWidgetText(player_data->file, widgetArr[i]);break;
			case 2:UpdateWidgetText(sizeStr, widgetArr[i]);		 break;
			default:break;
		}
	}

	//unhide other buttons
	for (int i = 0; i < widgetNum; i++) { widgetArr[i]->active = true; }

	UpdateBackgroundImage(renderer, player_data->file, player_data);

	return 0;
}
*/


//update background image by assigning
//new texture in imageList if the
//corresponding index in imageStr
//is found in the current file path
void UpdateBackgroundImage(SDL_Renderer* renderer, char* file, PlayerData* data) {
			
	if (data->background != NULL) { SDL_DestroyTexture(data->background); }

	for (int i = 0; i < data->imageNum; i++) {
	
		if (strstr(file, data->imageStr[i]) != NULL) {
				
			SDL_Surface* surface = SDL_LoadBMP(data->imageList[i]);
			data->background = SDL_CreateTextureFromSurface(renderer, surface);
			SDL_FreeSurface(surface);
			return;
		}
	}
	SDL_Surface* surface = SDL_LoadBMP(data->bgimage);
	data->background = SDL_CreateTextureFromSurface(renderer, surface);
	SDL_FreeSurface(surface);
}


void AddImageToPlayer(char* imagePathStr, char* imageStrMatch, PlayerData* data) {

	if (data->imageNum < 128) {

		data->imageList[data->imageNum] = imagePathStr;
		data->imageStr[data->imageNum] = imageStrMatch;
		data->imageNum++;
	}
}


int IdentifyConfigCommand(char* str) {
	
	char* mainStr = "$MAIN";
	char* buttonStr = "$BUTTON";
	char* imageStr = "$IMAGE";
	char* waveStr = "$WAVE";
	char* commandList[4] = { mainStr, buttonStr, imageStr, waveStr };

	for (int i = 0; i < 4; i++) {
	
		char* checkStr = commandList[i];

		int j = 0;
		for (j; checkStr[j] != '\0'; j++) {
			
			if (str[j] != checkStr[j]) { break; }
		}
		if (j == strlen(checkStr)) { return i; }
	}
	return -1;
}


int SaveProject(char* fileName, PlayerData* player_data, TimelineData* timeline_data) {

	//.kys file structure
	
	//header for general timeline info
	//# of samples 		(2 bytes)
	//bpm 			(2 bytes)
	//project length 	(4 bytes)
	//
	//sample structure
	//filename              (n bytes)
	//null terminating byte (1 byte)
	//track 		(1 byte)
	//beat offset           (4 bytes)
	//beat length 		(4 bytes)
	//front crop            (4 bytes)
	//back crop             (4 bytes)
	//crop offset           (4 bytes)
	//channel 		(1 byte)
	//flags 		(1 byte)
	//volume 		(4 bytes)
	//panning 		(4 bytes)

	
	FILE* file = fopen(fileName, "r");
	FILE* fileCopy = file;
	bool newFile = (file == NULL);
	
	//file does not exist yet so we need to create it
	if (newFile) { 
		
		file = fopen(fileName, "wb");

		if (file == NULL) {
		
			printf("Couldn't create save file.\n");
			return -1;
		}
	
	//save to current file
	} else {
		if (strcmp("dont_name_ur_file_this.kys", fileName) == 0) {
		
			printf("Why would you name your file that?\n");
			return -2;
		}
		file = fopen("dont_name_ur_file_this.kys", "wb");

		if (file == NULL) {
		
			printf("Couldn't save file.\n");
			return -1;
		}
	}

		
	//header data for project
	uint8_t projectHeader[8];
	projectHeader[0] = timeline_data->sampleNum >> 8;
	projectHeader[1] = timeline_data->sampleNum & 0xff;

	projectHeader[2] = timeline_data->bpm >> 8;
	projectHeader[3] = timeline_data->bpm & 0xff;

	projectHeader[4] = (timeline_data->projectLength >> 24);
	projectHeader[5] = (timeline_data->projectLength >> 16) & 0xff;
	projectHeader[6] = (timeline_data->projectLength >> 8) & 0xff;
	projectHeader[7] = (timeline_data->projectLength & 0xff);

	//fprintf(file, (char*)projectHeader);
	fwrite(projectHeader, sizeof(uint8_t), 8, file);
	
	//write each sample data
	for (int i = 0; i < timeline_data->sampleNum; i++) {
		
		Sample* sample = timeline_data->samples[i];

		//write file name
		fprintf(file, timeline_data->files[sample->fileIndex]);
			
		uint8_t sampleNode[32];
		for (int i = 0; i < 32; i++) { sampleNode[i] = 0x00; }
		
		sampleNode[0] = '\0';
		sampleNode[1] = sample->track;

		sampleNode[2] = (sample->beatOffset >> 24);
		sampleNode[3] = (sample->beatOffset >> 16) & 0xff;
		sampleNode[4] = (sample->beatOffset >> 8) & 0xff;
		sampleNode[5] = (sample->beatOffset & 0xff);
		
		sampleNode[6] = (sample->beatLength >> 24);
		sampleNode[7] = (sample->beatLength >> 16) & 0xff;
		sampleNode[8] = (sample->beatLength >> 8) & 0xff;
		sampleNode[9] = (sample->beatLength & 0xff);
		
		sampleNode[10] = (sample->beatCropFront >> 24);
		sampleNode[11] = (sample->beatCropFront >> 16) & 0xff;
		sampleNode[12] = (sample->beatCropFront >> 8) & 0xff;
		sampleNode[13] = (sample->beatCropFront & 0xff);
		
		sampleNode[14] = (sample->beatCropBack >> 24);
		sampleNode[15] = (sample->beatCropBack >> 16) & 0xff;
		sampleNode[16] = (sample->beatCropBack >> 8) & 0xff;
		sampleNode[17] = (sample->beatCropBack & 0xff);
		
		sampleNode[18] = (sample->cropOffset >> 24);
		sampleNode[19] = (sample->cropOffset >> 16) & 0xff;
		sampleNode[20] = (sample->cropOffset >> 8) & 0xff;
		sampleNode[21] = (sample->cropOffset & 0xff);

		sampleNode[22] = sample->channel;
		sampleNode[23] = sample->flags;
		
		/*
		sampleNode[24] = (sample->volume >> 24);
		sampleNode[25] = (sample->volume >> 16) & 0xff;
		sampleNode[26] = (sample->volume >> 8) & 0xff;
		sampleNode[27] = (sample->volume & 0xff);
		
		sampleNode[28] = (sample->panning >> 24);
		sampleNode[29] = (sample->panning >> 16) & 0xff;
		sampleNode[30] = (sample->panning >> 8) & 0xff;
		sampleNode[31] = (sample->panning & 0xff);
		*/

		//fprintf(file, (char*)sampleNode);
		fwrite(sampleNode, sizeof(uint8_t), 32, file);
	}
	fclose(file);

	//replace temp file
	if (!newFile) {
	
		remove(fileName);
		rename("dont_name_ur_file_this.kys", fileName);
		fclose(fileCopy);
	}

	return 0;
}

int ReadProject(char* filename, PlayerData* player_data, TimelineData* timeline_data) {

	FILE* file = fopen(filename, "rb");

	if (file == NULL) {
	
		printf("Save file not found.\n");
		return -1;
	}

	fseek(file, 0, SEEK_END);
	uint32_t fileSize = ftell(file);
	fseek(file, 0, SEEK_SET);
		
	//allocate mem and read file data
	uint8_t* save_data = (uint8_t*)malloc(sizeof(uint8_t)*fileSize);
	
	if (save_data == NULL) {
	
		printf("wtf did you just try to open? r u dumb???\n");
		return -2;
	}

	fread(save_data, sizeof(uint8_t), fileSize, file);
	fclose(file);



	//free all old samples and file name data
	for (int i = 0; i < timeline_data->sampleNum; i++) {
		if (timeline_data->samples[i] != NULL) { DestroySample(timeline_data->samples[i]); }
	}
	for (int i = 0; i < timeline_data->fileNum; i++) {
		if (timeline_data->files[i] != NULL) { free(timeline_data->files[i]); }
	}



	//decode file
	//general project info
	timeline_data->sampleNum = 0;
	timeline_data->fileNum = 0;
	
	timeline_data->bpm = ((save_data[2] << 8) | save_data[3]);
	
	timeline_data->projectLength = ((save_data[4] << 24) 
					| (save_data[5] << 16)
					| (save_data[6] << 8)
					| (save_data[7]));

	uint32_t dataIndex = 8;
	uint16_t fileSampleNum = ((save_data[0] << 8) | save_data[1]);
	for (int i = 0; i < fileSampleNum; i++) {
	
		//get file name and add to timeline
		char sampleFileName[1024];
		memset(sampleFileName, 0, 1024);

		int j = 0;
		uint32_t dataIndexPrev = dataIndex;
		for (j = dataIndex; save_data[j] != '\0'; j++) {
		
			sampleFileName[j-dataIndex] = save_data[j];
		}
		sampleFileName[j-dataIndex] = '\0';
		dataIndex += (j-dataIndexPrev);

		uint8_t track = save_data[dataIndex+1];
		uint32_t beatOffset = ((save_data[dataIndex+2] << 24) 
					| (save_data[dataIndex+3] << 16)
					| (save_data[dataIndex+4] << 8)
					| (save_data[dataIndex+5]));
		
		//create sample
		if (ImportSample(timeline_data, sampleFileName, 0, 0) < 0) {
		
			printf("Error creating sample from %s.\n", sampleFileName);
		}

		Sample* sample = timeline_data->samples[timeline_data->sampleNum-1];
		sample->beatOffset = beatOffset;
		sample->track = track;

		sample->beatLength = ((save_data[dataIndex+6] << 24) 
					| (save_data[dataIndex+7] << 16)
					| (save_data[dataIndex+8] << 8)
					| (save_data[dataIndex+9]));
		
		sample->beatCropFront = ((save_data[dataIndex+10] << 24) 
					| (save_data[dataIndex+11] << 16)
					| (save_data[dataIndex+12] << 8)
					| (save_data[dataIndex+13]));
		
		sample->beatCropBack = ((save_data[dataIndex+14] << 24) 
					| (save_data[dataIndex+15] << 16)
					| (save_data[dataIndex+16] << 8)
					| (save_data[dataIndex+17]));
		
		sample->cropOffset = ((save_data[dataIndex+18] << 24) 
					| (save_data[dataIndex+19] << 16)
					| (save_data[dataIndex+20] << 8)
					| (save_data[dataIndex+21]));

		sample->channel = save_data[dataIndex+22];
		sample->flags = save_data[dataIndex+23];
		
		/*	
		sample->volume = ((save_data[dataIndex+24] << 24) 
					| (save_data[dataIndex+25] << 16)
					| (save_data[dataIndex+26] << 8)
					| (save_data[dataIndex+27]));
		
		sample->panning = ((save_data[dataIndex+28] << 24) 
					| (save_data[dataIndex+29] << 16)
					| (save_data[dataIndex+30] << 8)
					| (save_data[dataIndex+31]));
		*/
		dataIndex += 32;
	}
	//timeline_data->sampleNum = ((save_data[0] << 8) | save_data[1]);
	free(save_data);

	
	return 0;
}


int ExportProject(char* fileName, PlayerData* player_data, TimelineData* timeline_data, AlsaData* alsa_data) {

	FILE* file = fopen(fileName, "r");
	FILE* fileCopy = file;
	bool newFile = (file == NULL);
		
	file = fopen("dont_name_ur_file_this.wav", "wb");

	if (file == NULL) {
		
		printf("Couldn't create temp data file.\n");
		return -1;
	}
	



	//go through project length and write audio data to file
	uint32_t totalDataSize = 0x00;
	
	for (timeline_data->currentBeat = 0; timeline_data->currentBeat < timeline_data->projectLength; timeline_data->currentBeat++) {
	
		uint8_t numOfPlayingSamples = 0;
	
		for (int i = 0; i < timeline_data->sampleNum; i++) {
		
			Sample* sample = timeline_data->samples[i];

			if (timeline_data->currentBeat >= sample->beatOffset+sample->beatCropFront 
			&& timeline_data->currentBeat < sample->beatOffset+sample->beatLength-sample->beatCropBack) {
			
				if (sample->playing == true) {
				
					for (int j = 0; (j < alsa_data->buff_size) && ((sample->dataOffset+j+1) < sample->dataSize); j+= 2) {
					
						uint16_t frameVal = (timeline_data->frame[j+1] << 8) | timeline_data->frame[j];
						uint16_t val = (sample->data[sample->dataOffset+j+1] << 8) | sample->data[sample->dataOffset+j];

						frameVal += val;
						timeline_data->frame[j+1] = (frameVal >> 8);
						timeline_data->frame[j] = (frameVal & 0xff);
					}
					sample->dataOffset += alsa_data->buff_size;
				} else {
					double sampleCurrentTime = ((((double)(timeline_data->currentBeat-sample->beatOffset))/16.0) * timeline_data->spb);
					sample->dataOffset = (uint32_t)(((double)sample->dataSize) * (sampleCurrentTime/sample->seconds)) 
												+ (sample->cropOffset * alsa_data->buff_size);
					
					sample->playing = true;
					if (sample->dataOffset % 2 == 1) { sample->dataOffset++; }
				}
				numOfPlayingSamples++;
			} else {
				sample->playing = false;
			}
		}

		//prevent audio corruption
		for (int i = 0; i < alsa_data->buff_size; i += 2) {
	
			int16_t frameVal = (timeline_data->frame[i+1] << 8) | timeline_data->frame[i];

			if ((frameVal == 32767 || frameVal == -32768) && numOfPlayingSamples > 1) {
		
				if ((i == 0) || (i >= alsa_data->buff_size - 3)) {
			
					frameVal = 0;
				} else {
					frameVal = (((timeline_data->frame[i-1] << 8) | timeline_data->frame[i-2]) 
						+ ((timeline_data->frame[i+3] << 8) | timeline_data->frame[i+2])) / 2;
				}
			}
			frameVal *= player_data->volume;
		
			timeline_data->frame[i+1] = (frameVal >> 8);
			timeline_data->frame[i] = (frameVal & 0xff);
		
		}

		//write audio data to file
		fwrite(timeline_data->frame, sizeof(uint8_t), alsa_data->buff_size, file);
		totalDataSize += alsa_data->buff_size;
	}
	fclose(file);
	
	
	//replace temp file
	if (!newFile) { remove(fileName); }
	file = fopen(fileName, "wb");

	
	//create wav header (little endian)
	uint8_t WavFileHeader[44];
	memset(WavFileHeader, 0x00, 44);


	memcpy(WavFileHeader, "RIFF", 4);
	
	//file size minus 8 bytes
	//memcpy(WavFileHeader+4, 0, 4);
	WavFileHeader[4] = (totalDataSize+44-8) & 0xff;
	WavFileHeader[5] = ((totalDataSize+44-8) >> 8) & 0xff;
	WavFileHeader[6] = ((totalDataSize+44-8) >> 16) & 0xff;
	WavFileHeader[7] = ((totalDataSize+44-8) >> 24) & 0xff;
	
	memcpy(WavFileHeader+8, "WAVE", 4);
	memcpy(WavFileHeader+12, "fmt ", 4);
	
	//chunk size minus 8 bytes
	//memcpy(WavFileHeader+16, 0x00, 4);
	WavFileHeader[16] = 0x10; 
	WavFileHeader[17] = 0x00;
	WavFileHeader[18] = 0x00;
	WavFileHeader[19] = 0x00;
	

	//audio format (1 for PCM)
	WavFileHeader[20] = 0x01; 
	WavFileHeader[21] = 0x00;
	
	//num of channels
	WavFileHeader[22] = 0x02; 
	WavFileHeader[23] = 0x00;
	
	WavFileHeader[24] = alsa_data->rate & 0xff;
	WavFileHeader[25] = (alsa_data->rate >> 8) & 0xff;
	WavFileHeader[26] = (alsa_data->rate >> 16) & 0xff;
	WavFileHeader[27] = (alsa_data->rate >> 24) & 0xff;
	
	uint16_t bytesPerBlock = (2*16/8);
	WavFileHeader[28] = (alsa_data->rate*bytesPerBlock) & 0xff;
	WavFileHeader[29] = ((alsa_data->rate*bytesPerBlock) >> 8) & 0xff;
	WavFileHeader[30] = ((alsa_data->rate*bytesPerBlock) >> 16) & 0xff;
	WavFileHeader[31] = ((alsa_data->rate*bytesPerBlock) >> 24) & 0xff;
	
	WavFileHeader[32] = bytesPerBlock & 0xff;
	WavFileHeader[33] = bytesPerBlock >> 8;
	
	//bits per sample
	WavFileHeader[34] = 0x10; 
	WavFileHeader[35] = 0x00;
	
	memcpy(WavFileHeader+36, "data", 4);
	
	//audio data size
	WavFileHeader[40] = totalDataSize & 0xff;
	WavFileHeader[41] = (totalDataSize >> 8) & 0xff;
	WavFileHeader[42] = (totalDataSize >> 16) & 0xff;
	WavFileHeader[43] = (totalDataSize >> 24) & 0xff;

	//write header data
	fwrite(WavFileHeader, sizeof(uint8_t), 44, file);


	uint8_t buff[alsa_data->buff_size];
	size_t bytes_read = 0;
	FILE* dataFile = fopen("dont_name_ur_file_this.wav", "wb");
	
	while ((bytes_read = fread(buff, 1, alsa_data->buff_size, dataFile)) > 0) {
	
		if (fwrite(buff, 1, bytes_read, file) != bytes_read) {
		
			printf("Something went wrong writing the audio data.\n");
			fclose(file);
			fclose(dataFile);
			return -2;
		}
		
	}


	fclose(file);
	fclose(dataFile);
	remove("dont_name_ur_file_this.wav");

	return 0;
}


int LoadFiles(char* config_path, SDL_Renderer* renderer, PlayerData* player_data, Widget* arr[256], uint8_t* widgetNum) {

	//file and dir paths
	FILE* file;
	char line[256];
	char* filePath = NULL;

	//user created widgets
	bool WidgetSpace = false;

	
	file = fopen(config_path, "r");
	
	if (file == NULL) { 
		
		printf("Config file '%s' could not be found or opened.\n", config_path);
		return EXIT_FAILURE; 
	}


	while (fgets(line, sizeof(line), file)) {

		//if not commented out
		if (line[0] != '#' && line[0] != '\n') {
		
			//go through line to check for shit
			struct stat buffer;
			int dirLen = strlen(line);
			line[dirLen-1] = '\0';

			//check for button/image/wave command
			int configCheck = IdentifyConfigCommand(line);
			int8_t configInitIndex = -1;
			char* arg = NULL;
			char* rest = line;
			

			//main config for window
			if (configCheck == 0) {
			
				while (arg = strtok_r(rest, ";", &rest)) {
				
					int val = atoi(arg);
					
					switch (configInitIndex) {
					
						case 0:player_data->w = val;break;
						case 1:player_data->h = val;break;
						case 2:
						       if (strcmp(arg, "null")) {
						       		
							       player_data->bgimage = malloc(sizeof(char)*strlen(arg));
							       strcpy(player_data->bgimage, arg);
						       }
						       break;
						case 3:
						       if (strcmp(arg, "null")) {
						       		
							       player_data->font = malloc(sizeof(char)*strlen(arg));
							       strcpy(player_data->font, arg);
						       }
						case 4:player_data->delay = val;break;
						default:break;
					}
					configInitIndex++;
				}

			//create custom widget
			} else if (configCheck == 1) {
		
				uint8_t actionType = 0; uint8_t sliderType = 0;
				uint16_t x = 0; uint16_t y = 0;
				uint16_t w = 0; uint16_t h = 0;
				bool xoffset = false; bool yoffset = false;
				bool woffset = false; bool hoffset = false;
				bool wstretch = false;bool hstretch = false;
				uint8_t xdivide = 0; uint8_t ydivide = 0;
				uint8_t wdivide = 0; uint8_t hdivide = 0;
				uint32_t color = 0; uint32_t color2 = 0; float shade = 0;
				char* widgetImage = NULL; char* widgetImage2 = NULL;
				char* text = NULL;
				uint16_t textx = 0; uint16_t texty = 0;

				
				while (arg = strtok_r(rest, ";", &rest)) {
	
					int val = atoi(arg);

					switch (configInitIndex) {
					
						case 0:actionType = val;break;
						case 1:sliderType = val;break;
						case 2:x = val;break;
						case 3:y = val;break;
						case 4:w = val;break;
						case 5:h = val;break;
						case 6:color = val;break;
						case 7:color2 = val;break;
						case 8:shade = ((float)val)/100.0;break;
						case 9:
						       if (strcmp(arg, "null")) {

							       widgetImage = malloc(sizeof(char)*strlen(arg));
							       strcpy(widgetImage, arg);
						       }
						       break;
						case 10:
						       if (strcmp(arg, "null")) {
						       		
							       widgetImage2 = malloc(sizeof(char)*strlen(arg));
							       strcpy(widgetImage2, arg);
						       }
						       break;
						
						case 11:wstretch = (bool)(val);break;
						case 12:hstretch = (bool)(val);break;
						case 13:xoffset = (bool)(val);break;
						case 14:yoffset = (bool)(val);break;
						case 15:woffset = (bool)(val);break;
						case 16:hoffset = (bool)(val);break;
						case 17:xdivide = val;break;
						case 18:ydivide = val;break;
						case 19:wdivide = val;break;
						case 20:hdivide = val;break;
						
						case 21:
						       if (strcmp(arg, "null")) {
						       		
							       text = malloc(sizeof(char)*strlen(arg));
							       strcpy(text, arg);
						       }
						       break;
						case 22:textx = val;break;
						case 23:texty = val;break;
						default:break;
					}
					configInitIndex++;
				}

				//if all args passed, create custom widget	
				if (configInitIndex >= 23) {
			
					CreateWidget(x, y, w, h, color, color2, shade, true, 
							wstretch, hstretch, 
							xoffset, yoffset, woffset, hoffset,
							xdivide, ydivide, wdivide, hdivide,
							text, textx, texty, 
							widgetImage, widgetImage2,
							actionType, sliderType, 
							renderer, arr, widgetNum);
				}

			//add custom image
			} else if (configCheck == 2) {
					
				char* image = NULL;
				char* strMatch = NULL;
				
				while (arg = strtok_r(rest, ";", &rest)) {
				
					switch (configInitIndex) {
					
						case 0:
							if (strcmp(arg, "null")) {

								image = malloc(sizeof(char)*strlen(arg));
								strcpy(image, arg);
							}
							break;
						case 1:
							if (strcmp(arg, "null")) {
							
								strMatch = malloc(sizeof(char)*strlen(arg));
								strcpy(strMatch, arg);
							}
							break;
						default:break;
					}
					configInitIndex++;
					if (configInitIndex >= 128) { break; }
				}
				AddImageToPlayer(image, strMatch, player_data);

			//wave config
			} else if (configCheck == 3) {

				while (arg = strtok_r(rest, ";", &rest)) {
	
					int val = atoi(arg);

					switch (configInitIndex) {
					
						case 0:player_data->r = val;break;
						case 1:player_data->g = val;break;
						case 2:player_data->b = val;break;
						case 3:player_data->waveVert = (bool)val;break;
						case 4:player_data->waveFade = (bool)val;break;
						case 5:player_data->waveAmp = val;break;
						case 6:player_data->waveFreq = val;break;
						default:break;
					}
					configInitIndex++;
				}	

			//if file/directory exists
			} else if (stat(line, &buffer) == 0) {

				//check for directory
				DIR* dir;
				struct dirent* ent;

				if ((dir = opendir(line)) != NULL) {
				
					//read files in directory
					while ((ent = readdir(dir)) != NULL) {
					
						int fileLen = strlen(ent->d_name);
						
						//allocate memory and copy directory with concat file
						char path[dirLen+fileLen];
						strcpy(path, line);
						strcat(path, ent->d_name);

						//add to file list of player
						player_data->fileList[player_data->fileCount] = (char*)malloc(sizeof(char)*(fileLen+dirLen));
						strcpy(player_data->fileList[player_data->fileCount], path);
						player_data->fileCount++;

						if (player_data->fileCount >= 1024) { break; }
					}
					closedir(dir);

				//add as an individual file
				} else {
					//allocate memory and copy string
					player_data->fileList[player_data->fileCount] = (char*)malloc(sizeof(char)*dirLen);
					strcpy(player_data->fileList[player_data->fileCount], line);
					player_data->fileCount++;

					if (player_data->fileCount >= 1024) { break; }
				}
			} else  {
				printf("Couldn't read file or directory '%s'.\n", line);
			}
		}
	}
	fclose(file);


	//widget inits
	//(put this in own function sometime)
	for (int i = 0; i < *widgetNum; i++) {
	
		switch (arr[i]->actionType) {
		
			case 0:
				arr[i]->listNum = player_data->fileCount;
				if (arr[i]->offsetY) {
		
					arr[i]->listOffset = arr[i]->listNum-1;
				}
				break;
			case 3:
				arr[i]->slide = 1.0;
				break;
			
			default:break;
		}

	}
	return 0;
}
