//  Copyright (C) 2016, mituhiromatuura all right reserved.

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

#include "beep.h"
#include "button.h"
#include "disp.h"
#include "fatfs.h"
#include "index.h"
#include "lcd.h"
#include "play.h"
#include "rec_avi.h"
#include "wait.h"

extern int read_JPEG_file (FILE *fobjp);
extern unsigned char avi_head[0x162e];

static
int play_jpg(int num)
{
	if(0 != (disk_initialize(0) & (STA_NOINIT | STA_NODISK)))goto error;

	FIL fobj;
	FRESULT res;
	UINT size;

	res = fatfs_mount(&fatfs, "", 0);
	if(FR_OK != res)goto error;

	char filename[260];

	while(1)
	{
		sprintf(filename, "%d.jpg", index_filenum(num));
		if(FR_NO_FILE != fatfs_stat(filename, NULL))
		{
			break;
		}
		sprintf(filename, "%d.avi", index_filenum(num));
		if(FR_NO_FILE != fatfs_stat(filename, NULL))
		{
			break;
		}
	}

	res = fatfs_open(&fobj, filename, FA_READ);
	if(FR_OK != res)goto error;

	if(NULL != strstr(filename, ".jpg"))
	{
		lcd_wr_cmd(0x0003);lcd_wr_data(0x1018); //Entry Mode (65K, BGR)

		lcd_wr_cmd(0x0020);lcd_wr_data(0x0000); // GRAM horizontal Address
		lcd_wr_cmd(0x0021);lcd_wr_data(0x0);//13F); // GRAM Vertical Address
		lcd_wr_cmd(0x0022);

		read_JPEG_file((FILE *)&fobj);

		display_area_set_m(0, 0, 240 - 1, 320 - 1);

		goto close;
	}

	if(NULL != strstr(filename, ".avi"))
	{
		res = fatfs_read(&fobj, (void*)&avi_head, sizeof(avi_head), &size);
		if((FR_OK != res) || (sizeof(avi_head) != size))goto error_close;

		char h[8];
		res = fatfs_read(&fobj, (void*)h, 8, &size);
		if((FR_OK != res) || (sizeof(h) != size))goto error_close;

		lcd_wr_cmd(0x0003);lcd_wr_data(0x1018); //Entry Mode (65K, BGR)

		lcd_wr_cmd(0x0020);lcd_wr_data(0x0000); // GRAM horizontal Address
		lcd_wr_cmd(0x0021);lcd_wr_data(0x0);//13F); // GRAM Vertical Address
		lcd_wr_cmd(0x0022);

		read_JPEG_file((FILE *)&fobj);

		display_area_set_m(0, 0, 240 - 1, 320 - 1);

		lcd_puts(4, 2, "PLAY", WHITE, RED);
		goto close;
	}

error_close:
	fatfs_close(&fobj);
error:
	lcd_puts(3, 2, "error", FCOLOR, BCOLOR);
	wait_busy(1000);
	return 0;

close:
	fatfs_close(&fobj);
	lcd_puts(0, 0, "-", RED, WHITE);
	lcd_puts(12, 0, "+", RED, WHITE);
	lcd_puts(LCD_LEFT, 4, filename, FCOLOR, BCOLOR);
	return 1;
}

static
int play_avi(int num)
{
	int fnum, ftim;
	SYSTIM tim_start, tim_end;

	if(0 != (disk_initialize(0) & (STA_NOINIT | STA_NODISK)))goto error;

	FIL f_avi;
	FRESULT res;
	UINT size;

	res = fatfs_mount(&fatfs, "", 0);
	if(FR_OK != res)goto error;

	char f_name_avi[128];

	sprintf(f_name_avi, "%d.avi", index_filenum(num));
	if(FR_NO_FILE == fatfs_stat(f_name_avi, NULL))goto error;

	beep();

	res = fatfs_open(&f_avi, f_name_avi, FA_READ);
	if(FR_OK != res)goto error;

	res = fatfs_read(&f_avi, (void*)&avi_head, sizeof(avi_head), &size);
	if((FR_OK != res) || (sizeof(avi_head) != size))goto error_close;

	int *intp;
	intp = (int *)&avi_head[0x30]; fnum = *intp;
	intp = (int *)&avi_head[0x20]; ftim = *intp / 1000;

	if(0 == fnum)goto error_close;

	char h[8];
	res = fatfs_read(&f_avi, (void*)h, 8, &size);
	if((FR_OK != res) || (sizeof(h) != size))goto error_close;

	char *last_buf = 0;
	int n;
	for(n = 0; ; n++)
	{
		get_tim(&tim_start);

		lcd_wr_cmd(0x0003);lcd_wr_data(0x1018); //Entry Mode (65K, BGR)

		lcd_wr_cmd(0x0020);lcd_wr_data(0x0000); // GRAM horizontal Address
		lcd_wr_cmd(0x0021);lcd_wr_data(0x0);//13F); // GRAM Vertical Address
		lcd_wr_cmd(0x0022);

		read_JPEG_file((FILE *)&f_avi);

		display_area_set_m(0, 0, 240 - 1, 320 - 1);
		if(!last_size)break;

		char buf[32];
		if(999999 != fnum)
			sprintf(buf, "%d/%d", n, fnum);
		else
			sprintf(buf, "%d", n);
		lcd_puts_s(0, 240/10-1, buf, WHITE, BLUE);

		if(fnum == n)break;
		if(button_a_is_on() || button_b_is_on())break;

		int f_pt = fatfs_tell(&f_avi) - last_size;
		res = fatfs_lseek(&f_avi, f_pt);
		if(FR_OK != res)goto error_close;

		last_buf = malloc(last_size + 11);
		res = fatfs_read(&f_avi, last_buf, last_size + 11, &size);
		if((FR_OK != res) || (last_size + 11 != size))goto error_free;
		int bp;
		for(bp = last_size; bp >= 0; bp--)
		{
			if(last_buf[bp+0] != 0xff)continue;
			if(last_buf[bp+1] != 0xd8)continue;
			if(last_buf[bp+2] != 0xff)continue;
			if(last_buf[bp+3] != 0xe0)continue;
//			if(last_buf[bp+4] != 0x00)continue;
//			if(last_buf[bp+5] != 0x10)continue;
			if(last_buf[bp+6] != 'A')continue;
			if(last_buf[bp+7] != 'V')continue;
			if(last_buf[bp+8] != 'I')continue;
			if(last_buf[bp+9] != '1')continue;
			if(last_buf[bp+10] != '\0')continue;
			break;
		}
		if(-1 == bp)
		{
			res = fatfs_lseek(&f_avi, f_pt + (DWORD)last_size);
			if(FR_OK != res)goto error_free;
		}
		else
		{
			res = fatfs_lseek(&f_avi, f_pt + (DWORD)bp);
			if(FR_OK != res)goto error_free;
		}

		free(last_buf);

		for(get_tim(&tim_end); (tim_start + ftim) >= tim_end; get_tim(&tim_end));
	}

	fatfs_close(&f_avi);
//	lcd_puts(LCD_LEFT, 4, f_name_avi, FCOLOR, BCOLOR);
	return 1;

error_free:
	free(last_buf);
error_close:
	fatfs_close(&f_avi);
error:
//	lcd_puts(3, 2, "error", FCOLOR, BCOLOR);
//	wait_busy(1000);
	return 0;
}

void play(void)
{
	int first_time = 1;
	int num = index_count();

	while(1)
	{
		if(0 == play_jpg(num))break;
		if(first_time)while(button_a_is_on() || button_b_is_on());
		first_time = 0;

		while(!button_a_is_on() && !button_b_is_on())
		{
			if(button_c_is_on())
			{
				if(play_avi(num))
				{
					lcd_puts(0, 0, "-", RED, WHITE);
					lcd_puts(12, 0, "+", RED, WHITE);
					lcd_puts(3, 2, "REPLAY", WHITE, RED);
					while(button_a_is_on() || button_b_is_on());
				}
			}
		}

		if(button_a_is_on() && button_b_is_on())break;

		if(button_a_is_on())
		{
			if(++num > index_count())
			{
				num = 0;
			}
		}
		else
		if(button_b_is_on())
		{
			if(--num < 0)
			{
				num = index_count();
			}
		}
	}
	return;
}
