/*
 * cap_sample.c
 * キャプチャサンプルロビー
 */

#include "cap_sample.h"
#include "cap_common.h"
#include "sample_common.h"
#include "com.h"

#include "cap_simple.h"
#include "cap_histogram.h"
#include "cap_labeling.h"
#include "cap_framecalc.h"

extern int32_t gCAPErrCode;		/* エラーチェック用 */

/* プロトタイプ */
static int32_t CAP_Help();
static int32_t CAP_Simple();
static int32_t CAP_Histogram();
static int32_t CAP_Labeling();
static int32_t CAP_FrameCalc();

static int32_t (*func[])() = {
	CAP_Help,
	CAP_Simple,
	CAP_Histogram,
	CAP_Labeling,
	CAP_FrameCalc,
};


/* 関数 */
void CAP_main(uint8_t param)
{
	int32_t		rc = AG903_ENONE;
	uint8_t		mode = 0;
	char		input[2+2];

	((void)param);

	/* 共通初期化処理 */
	rc = sys_meminit(AG903_SAMPLE_VRAM_ALLOC_SIZE,
					 (void *)AG903_SAMPLE_VRAM_ADDR,
					 SYSMEM_NORMAL_CACHE_OFF);
	if (rc != AG903_ENONE)
	{
		CAP_ErrPrintf("ERROR: System memory init failed.\r\n");
	}

	func[0](); /* Help */
	while (mode != 0xFF) {
		CAP_Printf(" -- Choose sample number (00h<HELP> to FFh): ");
		COM_GetNum_Wait(input, sizeof(input));
		mode = (ASCtoBIN(input[0]) << 4)
			   | (ASCtoBIN(input[1]) << 0);

		if(0xFF == mode) {
			break;
		}
		if(mode >= (sizeof(func)/sizeof(void*))) {
			func[0](); /* Help */
		}
		else {
			func[mode]();	/* Sample func実行 */
		}
	}

	/* 共通終了処理 */
	sys_memfinal();

	return;
}

static int32_t CAP_Help()
{
	CAP_Printf("\t# 00 ... Help\r\n");
	CAP_Printf("\t# 01 ... Simple\r\n");
	CAP_Printf("\t# 02 ... Histogram\r\n");
	CAP_Printf("\t# 03 ... Labeling\r\n");
	CAP_Printf("\t# 04 ... FrameCalc\r\n");
	CAP_Printf("\t# FF ... Exit Sample\r\n");
	return AG903_ENONE;
}

static int32_t CAP_Simple()
{
	uint8_t		mdl = 0xff;
	char		input[1+2];
	int32_t		mode = CAP_MODE_MAX;
	int32_t		rc = AG903_ENONE;

	while (mode >= CAP_MODE_MAX) {
		CAP_Printf(" -- Choose input module (0=Analog, 1=Digital): ");
		COM_GetNum_Wait(input, sizeof(input));
		mdl = (ASCtoBIN(input[0]) << 0);
		if (mdl == 0) {
			CAP_Printf(" -- Choose output module (0=LVDS, 1=CMOS): ");
			COM_GetNum_Wait(input, sizeof(input));
			mdl = (ASCtoBIN(input[0]) << 0);
			if (mdl == 0) {
				mode = CAP_MODE_VIA_LVDS;
			} else {
				mode = CAP_MODE_VIA_CMOS;
			}
		} else {
			mode = CAP_MODE_VID;
		}
			
		switch(mode) {
			case CAP_MODE_VIA_LVDS:
				CAP_Printf("\r\n[Analog input, LVDS output -> Simple sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Simple_Demo(CAP_MODE_VIA_LVDS);
				CAP_ReleaseVIA();
				break;
			case CAP_MODE_VID:
				CAP_Printf("\r\n[Digital input, LVDS output -> Simple sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVID();
				rc = CAP_Simple_Demo(CAP_MODE_VID);
				CAP_ReleaseVID();
				break;
			case CAP_MODE_VIA_CMOS:
				CAP_Printf("\r\n[Analog input, CMOS output -> Simple sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Simple_Demo(CAP_MODE_VIA_CMOS);
				CAP_ReleaseVIA();
				break;
		}
	}
	CAP_Printf("\r\n");

	return rc;
}

static int32_t CAP_Histogram()
{
	uint8_t		mdl = 0xff;
	char		input[1+2];
	int32_t		mode = CAP_MODE_MAX;
	int32_t		rc = AG903_ENONE;

	while (mode >= CAP_MODE_MAX) {
		CAP_Printf(" -- Choose input module (0=Analog, 1=Digital): ");
		COM_GetNum_Wait(input, sizeof(input));
		mdl = (ASCtoBIN(input[0]) << 0);
		if (mdl == 0) {
			CAP_Printf(" -- Choose output module (0=LVDS, 1=CMOS): ");
			COM_GetNum_Wait(input, sizeof(input));
			mdl = (ASCtoBIN(input[0]) << 0);
			if (mdl == 0) {
				mode = CAP_MODE_VIA_LVDS;
			} else {
				mode = CAP_MODE_VIA_CMOS;
			}
		} else {
			mode = CAP_MODE_VID;
		}

		switch(mode) {
			case CAP_MODE_VIA_LVDS:
				CAP_Printf("\r\n[Analog input, LVDS output -> Histogram sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Histogram_Demo(CAP_MODE_VIA_LVDS);
				CAP_ReleaseVIA();
				break;
			case CAP_MODE_VID:
				CAP_Printf("\r\n[Digital input, LVDS output -> Histogram sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVID();
				rc = CAP_Histogram_Demo(CAP_MODE_VID);
				CAP_ReleaseVID();
				break;
			case CAP_MODE_VIA_CMOS:
				CAP_Printf("\r\n[Analog input, CMOS output -> Histogram sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Histogram_Demo(CAP_MODE_VIA_CMOS);
				CAP_ReleaseVIA();
				break;
		}
	}
	CAP_Printf("\r\n");

	return rc;
}

static int32_t CAP_Labeling()
{
	uint8_t		mdl = 0xff;
	char		input[1+2];
	int32_t		mode = CAP_MODE_MAX;
	int32_t		rc = AG903_ENONE;

	while (mode >= CAP_MODE_MAX) {
		CAP_Printf(" -- Choose input module (0=Analog, 1=Digital): ");
		COM_GetNum_Wait(input, sizeof(input));
		mdl = (ASCtoBIN(input[0]) << 0);
		if (mdl == 0) {
			CAP_Printf(" -- Choose output module (0=LVDS, 1=CMOS): ");
			COM_GetNum_Wait(input, sizeof(input));
			mdl = (ASCtoBIN(input[0]) << 0);
			if (mdl == 0) {
				mode = CAP_MODE_VIA_LVDS;
			} else {
				mode = CAP_MODE_VIA_CMOS;
			}
		} else {
			mode = CAP_MODE_VID;
		}

		switch(mode) {
			case CAP_MODE_VIA_LVDS:
				CAP_Printf("\r\n[Analog input, LVDS output -> Labeling sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Labeling_Demo(CAP_MODE_VIA_LVDS);
				CAP_ReleaseVIA();
				break;
			case CAP_MODE_VID:
				CAP_Printf("\r\n[Digital input, LVDS output -> Labeling sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVID();
				rc = CAP_Labeling_Demo(CAP_MODE_VID);
				CAP_ReleaseVID();
				break;
			case CAP_MODE_VIA_CMOS:
				CAP_Printf("\r\n[Analog input, CMOS output -> Labeling sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				rc = CAP_Labeling_Demo(CAP_MODE_VIA_CMOS);
				CAP_ReleaseVIA();
				break;
		}
	}
	CAP_Printf("\r\n");

	return rc;
}

static int32_t CAP_FrameCalc()
{
	uint8_t		mdl = 0xff;
	char		input[1+2];
	int32_t		mode = CAP_MODE_MAX;
	int32_t		rc = AG903_ENONE;

	while (mode >= CAP_MODE_MAX) {
		CAP_Printf(" -- Choose input module (0=Analog, 1=Digital): ");
		COM_GetNum_Wait(input, sizeof(input));
		mdl = (ASCtoBIN(input[0]) << 0);
		if (mdl == 0) {
			CAP_Printf(" -- Choose output module (0=LVDS, 1=CMOS): ");
			COM_GetNum_Wait(input, sizeof(input));
			mdl = (ASCtoBIN(input[0]) << 0);
			if (mdl == 0) {
				mode = CAP_MODE_VIA_LVDS;
			} else {
				mode = CAP_MODE_VIA_CMOS;
			}
		} else {
			mode = CAP_MODE_VID;
		}

		switch(mode) {
			case CAP_MODE_VIA_LVDS:
				CAP_Printf("\r\n[Analog input, LVDS output -> Interframe calculation sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				CAP_FrameCalc_Demo(CAP_MODE_VIA_LVDS);
				CAP_ReleaseVIA();
				break;
			case CAP_MODE_VID:
				CAP_Printf("\r\n[Digital input, LVDS output -> Interframe calculation sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVID();
				CAP_FrameCalc_Demo(CAP_MODE_VID);
				CAP_ReleaseVID();
				break;
			case CAP_MODE_VIA_CMOS:
				CAP_Printf("\r\n[Analog input, CMOS output -> Interframe calculation sample]\r\n\r\n");
				/* 外部関数のコール（サンプルの実処理） */
				CAP_SetupVIA();
				CAP_FrameCalc_Demo(CAP_MODE_VIA_CMOS);
				CAP_ReleaseVIA();
				break;
		}
	}
	CAP_Printf("\r\n");

	return rc;
}
