#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "iodefine.h"
#include "integer.h"
#include "diskio.h"
#include "ff.h"
#include "shuffle_play.h"
#include "play.h"
#include "ui.h"
#include "key_ctrl.h"

extern FIL fobj;
#define LIST_MAX 4096				/* 最大管理可能曲数 */
static char check[(LIST_MAX / 8) + ((LIST_MAX % 8) ? 1 : 0)];	/* 一曲1ビット */
static char song_file[128];
static int mp3_count;	/* 再帰的に処理するのでグローバル変数 */

static FRESULT make_list(char* dirname)
{
	FRESULT res;
	DIR Dir;
	FILINFO Finfo = {.lfname = 0, .lfsize = 0};

	res = f_opendir(&Dir, dirname);
	if(res) goto make_list_return;

	for( ; mp3_count < LIST_MAX; )
	{
		res = f_readdir(&Dir, &Finfo);
		if(res != FR_OK) goto make_list_return;
		if(!Finfo.fname[0]) goto make_list_return;

		if(NULL != strstr(Finfo.fname, ".mp3")
		|| NULL != strstr(Finfo.fname, ".MP3"))
		{
			strcpy(song_file, dirname);
			strcat(song_file, "\\");
			strcat(song_file, Finfo.fname);
			check[mp3_count / 8] &= ~(1 << (mp3_count % 8));
			printf("[%d]%s\r\n", mp3_count, song_file);
			mp3_count++;
		}
		else
		if(Finfo.fattrib & AM_DIR)
		{
			if(0 != strcmp(Finfo.fname, "RECYCLER")
			&& NULL == strstr(Finfo.fname, "TRASHE")
			&& Finfo.fname[0] != '.')
			{
				char n[128];
				strcpy(n, dirname);
				strcat(n, "\\");
				strcat(n, Finfo.fname);
				printf("(%s)\r\n", n);
				res = make_list(n);
				if(res != FR_OK) break;
			}
		}
	}
make_list_return:
	return res;
}

static FRESULT get_song_file(char* dirname, unsigned int* c, char* song_file)
{
	FRESULT res;
	DIR Dir;
	char Lfname[_MAX_LFN];
	FILINFO Finfo = {.lfname = Lfname, .lfsize = sizeof(Lfname)};

	res = f_opendir(&Dir, dirname);
	if(res) goto get_song_file_return;

	for( ; (*c) + 1; )
	{
		res = f_readdir(&Dir, &Finfo);
		if(res != FR_OK) goto get_song_file_return;
		if(!Finfo.fname[0]) goto get_song_file_return;

		if(strstr(Finfo.fname, ".mp3")
		|| strstr(Finfo.fname, ".MP3"))
		{
			strcpy(song_file, dirname);
			strcat(song_file, "\\");
			strcat(song_file, Finfo.fname);
			(*c)--;
		}
		else
		if(Finfo.fattrib & AM_DIR)
		{
			if(strcmp(Finfo.fname, "RECYCLER")
			&& NULL == strstr(Finfo.fname, "TRASHE")
			&& Finfo.fname[0] != '.')
			{
				char n[128];
				strcpy(n, dirname);
				strcat(n, "\\");
				strcat(n, Finfo.fname);
				//printf("{%s}\r\n", n);
				res = get_song_file(n, c, song_file);
				if(res != FR_OK) break;
			}
		}
	}
	*Finfo.lfname ? printf("%s\r\n", Finfo.lfname) : printf("%s\r\n", Finfo.fname);
get_song_file_return:
	return res;
}

FRESULT shuffle_play(char* dirname)
{
	FRESULT res;
	int n = -1, count = 0;
	char song_file[128];
	unsigned int c;

	printf("song list\r\n");
	mp3_count = 0;
	res = make_list(dirname);
	if(res != FR_OK) return res;

	printf("play start\r\n");
	while(1)
	{
		if(!key_shuffle())
		{
			if(key_up())
				n = n ? (n - 1) % mp3_count : mp3_count - 1;
			else
				n = (n + 1) % mp3_count;
		}
		else
		{
			if(count++ >= mp3_count)break;
			while(1)
			{
				n = (rand() + CMT.CMCNT1.WORD) % mp3_count;
				if(0 == (check[n / 8] & (1 << (n % 8))))
				{
					check[n / 8] |= (1 << (n % 8));
					break;
				}
			}
		}

		c = n;
		get_song_file(dirname, &c, song_file);
		do{
			printf("%d/%d[%d]\r\n", count, mp3_count, n);
			res = (FRESULT)play(song_file);
			if(res != FR_OK) return res;
		}while(key_repeat());
	}
	return res;
}
