/*<Header>==============================================================
*
*	ＣＤプレーヤ / "CDP.C"
*
*		[ EIN(tm) project : サンプルプログラム ]
*
*	COPYRIGHT  Nam  1994, All rights reserved.
*
*	配付・組込・改変・商利用すべて自由。ただし無保証っす
*
*-----------------------------------------------------------------------
*	V1.0L01α	94.04.07/Nam	プロトタイプ
*</Header>==============================================================*/
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<snd.h>
#include	<winb.h>
#include	<te.h>
#include	<fntb.h>
#include	<gui.h>
#include	<egb.h>
//#include	<file_dlg.h>
//#include	<tifflib.h>
#include	<msdos.cf>
#include	<loader.h>
#include	<math.h>
#include	<io.h>
#include	<guidbg.h>
#include	<wgb.h>
// ※ ここまでが平均的に使用されるヘッダ
#include	<time.h>
#include	<cdrfrb.h>

#include	"..\ein\eintm.h"	// EIN(TM)関連ライブラリのヘッダ


#define	ERR_RETRY	(10)
#define	STD_CD_NO	(0)

extern	int	updateCDdisp();

struct TIMEADRS	tracktime[100], disctime, endtime;
int				cdtype     = -1;	// 起動時演奏check用
int				starttrack = 0;
int				endtrack   = 0;
int				nowtrack   = 0;
struct TIMEADRS	trtime, dctime;		// mphaseで取得

int	clearCDstat()
{
	register int	i;

	cdtype = -1;

	nowtrack = -2;
	endtrack = -2;
	for (i=0; i<100; i++){
		tracktime[i].min=0;		// これは0クリアしないとcdr_cdinfoで誤動作する(T-T)
		tracktime[i].sec=0;
	}
	disctime.min=-2;
	disctime.sec=-2;
	trtime.min=-2;
	trtime.sec=-2;
	dctime.min=-2;
	dctime.sec=-2;
	
	return NOERR;
}

int	getPlayStatus()
{
	static int				stat;
	register int	ret, retry;

	// リトライ有り
	for ( retry=0; retry<ERR_RETRY; retry++){
		ret = cdr_mphase( STD_CD_NO, &stat, &nowtrack, &trtime, &dctime);
		if ( ret==0 ){
			break;
		}
	}
	// もしエラーなら-1を返す
	if ( ret!=0 ){
		clearCDstat();
		return -1;
	}
	// 停止中なら0を返す
	if ( stat==0 ){
		nowtrack=0;
		return stat;
	}
	// 演奏中なら曲番号を返す
	return nowtrack;
}

// CDのステータス取得
int	readTOC()
{
	register int	ret, retry;

	//まずCDを止めよう
	cdr_mstop( STD_CD_NO );
	// リトライ有り
	for ( retry=0; retry<ERR_RETRY; retry++){
		ret = cdr_cdinfo( STD_CD_NO, &cdtype, &starttrack, &endtrack,
						  &tracktime[0], &disctime );
		if ( ret==0 ){
			#ifdef DEBUG
			printf("    error_retry(%d): cdr_cdinfo=%x\n", retry, ret);
			#endif
			break;
		}
	}
	// 終了時間はframe--
	endtime = disctime;
	if ( endtime.frame > 0 ){
		endtime.frame--;
	} else {
		endtime.frame = 74;
		if ( endtime.sec > 0 ){
			endtime.sec--;
		} else {
			endtime.sec = 59;
			endtime.min--;
		}
	}
	#ifdef DEBUG
	printf("### cdr_cdinfo: type:%d  start:%d, end:%d   (%2d.%2d.%2d)\n",
			cdtype, starttrack, endtrack,
			disctime.min, disctime.sec, disctime.frame);
	#endif
	/* 読み取り時にERROR or データのみのCD ならば"Er"表示にして終了 */
	if ( ret!=0 || cdtype==2 ){
		updateCDdisp( 1 );
		return NOERR;
	}

	return NOERR;
}

int	func_Play()
{
	register int	ret, i, retry;

	/* 演奏状態の取得 */
	ret = getPlayStatus();
	// もし演奏中なら
	if ( ret > 0 ){
		// もし演奏中なら停止
		cdr_mstop( STD_CD_NO );
		updateCDdisp( 1 );
		clearCDstat();
		return NOERR;
	}
	// もし停止中ならCDのステータス取得
	readTOC();
	/* 最初のオーディオトラックを演奏 */
	updateCDdisp( 1 );
	for ( i=starttrack-1; i<endtrack; i++ ){
		#ifdef DEBUG
		printf("--> track %d: (%2d.%2d.%2d)-(%2d.%2d.%2d)\n", i,
				tracktime[i].min, tracktime[i].sec, tracktime[i].frame,
				endtime.min, endtime.sec, endtime.frame);
		#endif
		// データトラックでなければ演奏
		if ( (tracktime[i].min & 0x80)==0 ){
			// リトライ有り
			for ( retry=0; retry<ERR_RETRY; retry++){
				ret = cdr_mtrplay( STD_CD_NO, &tracktime[i], &endtime, 0 );
				if ( ret==0 ){
					break;
				}
				#ifdef DEBUG
				printf("    error_retry(%d): cdr_mtrplay=%x\n", retry, ret);
				#endif
			}
			updateCDdisp( 1 );
			break;
		}
	}

	return NOERR;
}

int	func_Rev()
{
	register int	ret, i, retry;

	/* 演奏状態の取得 */
	ret = getPlayStatus();
	// 起動時既に演奏しているなら, まずTOCを読み込む
	if ( cdtype<0 ){
		readTOC();
		if (nowtrack<1){
			nowtrack=1;
		}
	} else {
		// もし停止中ならplay
		if ( ret<1 ){
			func_Play();
			return NOERR;
		}
	}
	/* データのみのCD ならば"Er"表示にして終了 */
	if ( cdtype==2 ){
		updateCDdisp( 1 );
		return NOERR;
	}
	// もし演奏中なら一時停止
	ret = cdr_pause( STD_CD_NO );
	
	/* 前のオーディオトラックを演奏 */
	if ( (nowtrack > 1) && ((tracktime[starttrack].min & 0x80)==0) ){
		i = nowtrack-1-1;
	} else {
		// 現在位置が開始トラックで且つデータトラックなら
		i = endtrack -1;
	}
	for ( ; i>=0; i-- ){
		#ifdef DEBUG
		printf("--> track %d: (%2d.%2d.%2d)-(%2d.%2d.%2d)\n", i,
				tracktime[i].min, tracktime[i].sec, tracktime[i].frame,
				endtime.min, endtime.sec, endtime.frame);
		#endif
		// データトラックでなければ演奏
		if ( (tracktime[i].min & 0x80)==0 ){
			// リトライ有り
			for ( retry=0; retry<ERR_RETRY; retry++){
				ret = cdr_mtrplay( STD_CD_NO, &tracktime[i], &endtime, 0 );
				if ( ret==0 ){
					break;
				}
				#ifdef DEBUG
				printf("    error_retry(%d): cdr_mtrplay=%x\n", retry, ret);
				#endif
			}
			updateCDdisp( 1 );
			break;
		}
	}
	
	return NOERR;
}

int	func_FF()
{
	register int	ret, i, retry;

	/* 演奏状態の取得 */
	ret = getPlayStatus();
	
	// 起動時既に演奏しているなら, まずTOCを読み込む
	if ( cdtype<0 ){
		readTOC();
		if (nowtrack<1){
			nowtrack=0;
		}
	} else {
		// もし停止中ならplay
		if ( ret<1 ){
			func_Play();
			return NOERR;
		}
	}
	/* データのみのCD ならば"Er"表示にして終了 */
	if ( cdtype==2 ){
		updateCDdisp( 1 );
		return NOERR;
	}
	// もし演奏中なら一時停止
	ret = cdr_pause( STD_CD_NO );
	#ifdef DEBUG
	printf("--> track %d    endtrack:%d\n", nowtrack, endtrack);
	#endif
	/* 次のオーディオトラックを演奏 */
	if ( (nowtrack < endtrack) && ((tracktime[endtrack].min & 0x80)==0) ){
		i = nowtrack-1+1;
	} else {
		// 現在位置が最終トラックで且つデータトラックなら
		i = starttrack -1;
	}
	for ( ; i<endtrack; i++ ){
		#ifdef DEBUG
		printf("--> track %d: (%2d.%2d.%2d)-(%2d.%2d.%2d)\n", i,
				tracktime[i].min, tracktime[i].sec, tracktime[i].frame,
				endtime.min, endtime.sec, endtime.frame);
		#endif
		// データトラックでなければ演奏
		if ( (tracktime[i].min & 0x80)==0 ){
			// リトライ有り
			for ( retry=0; retry<ERR_RETRY; retry++){
				ret = cdr_mtrplay( STD_CD_NO, &tracktime[i], &endtime, 0 );
				if ( ret==0 ){
					break;
				}
				#ifdef DEBUG
				printf("    error_retry(%d): cdr_mtrplay=%x\n", retry, ret);
				#endif
			}
			updateCDdisp( 1 );
			break;
		}
	}
	
	return NOERR;
}

