/*	
 *	clipmmio.c
 *
 *	Win32 Multimedia API 互換ライブラリ
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2007 Naoyuki Sawa
 *
 *	* Fri Nov 16 16:28:45 JST 2007 Naoyuki Sawa
 *	- 1st リリース。
 */
#include "clip.h"

/****************************************************************************
 *	
 ****************************************************************************/

HMMIO
mmioOpen(const char* pszFileName, /*MMIOINFO*/void* pmmioinfo, int fdwOpen)
{
	if(pmmioinfo || fdwOpen) DIE(); /* 未対応 */
	return fopen(pszFileName, "rb");
}

int
mmioClose(HMMIO hmmio, int fuClose)
{
	if(fuClose) DIE(); /* 未対応 */
	return fclose(hmmio);
}

int
mmioDescend(HMMIO hmmio, MMCKINFO* pmmcki, const MMCKINFO* pmmckiParent, int fuDescend)
{
	int mmr;
	int pos;
	int len;
	MMCKINFO mmci;

	switch(fuDescend) {
	case 0:
		memset(&mmci, 0, sizeof(MMCKINFO));
		pos = ftell(hmmio);
		if(pos < 0) DIE();
		if(pmmckiParent) {
			if(pos >= (int)(pmmckiParent->dwDataOffset + pmmckiParent->cksize)) {
				return -1;
			}
		}
		len = mmioRead(hmmio, (char*)&mmci.ckid, 8);
		if(!len) return -1;
		if(len != 8) DIE();
		if((mmci.ckid == mmioFOURCC('R', 'I', 'F', 'F')) ||
		   (mmci.ckid == mmioFOURCC('L', 'I', 'S', 'T'))) {
			len = mmioRead(hmmio, (char*)&mmci.fccType, 4);
			if(len != 4) DIE();
		}
		mmci.dwDataOffset = pos + 8; /* RIFF,LISTの場合も+8です。+12ではありません */
		*pmmcki = mmci;
		return 0;
	case MMIO_FINDCHUNK:
		for(;;) {
			mmr = mmioDescend(hmmio, &mmci, pmmckiParent, 0);
			if(mmr) return mmr;
			if(mmci.ckid == pmmcki->ckid) break;
			mmr = mmioAscend(hmmio, &mmci, 0);
			if(mmr) DIE();
		}
		*pmmcki = mmci;
		return 0;
	case MMIO_FINDRIFF:
		for(;;) {
			mmr = mmioDescend(hmmio, &mmci, pmmckiParent, 0);
			if(mmr) return mmr;
			if((mmci.ckid == mmioFOURCC('R', 'I', 'F', 'F')) &&
			   (mmci.fccType == mmci.fccType)) break;
			mmr = mmioAscend(hmmio, &mmci, 0);
			if(mmr) DIE();
		}
		*pmmcki = mmci;
		return 0;
	case MMIO_FINDLIST:
		for(;;) {
			mmr = mmioDescend(hmmio, &mmci, pmmckiParent, 0);
			if(mmr) return mmr;
			if((mmci.ckid == mmioFOURCC('L', 'I', 'S', 'T')) &&
			   (mmci.fccType == mmci.fccType)) break;
			mmr = mmioAscend(hmmio, &mmci, 0);
			if(mmr) DIE();
		}
		*pmmcki = mmci;
		return 0;
	}
	DIE();
}

int
mmioAscend(HMMIO hmmio, MMCKINFO* pmmcki, int fuAscend)
{
	if(fuAscend) DIE(); /* 未対応 */
	return fseek(hmmio, pmmcki->dwDataOffset + ((pmmcki->cksize + 1/*pad*/) & ~1), SEEK_SET);
}

int
mmioRead(HMMIO hmmio, char* pch, int cch)
{
	return fread(pch, 1, cch, hmmio);
}

int
mmioSeek(HMMIO hmmio, int lOffset, int iOrigin)
{
	/* mmioSeek()とfseek()は戻り値の仕様が異なることに注意! */
	return fseek(hmmio, lOffset, iOrigin) ? -1 : ftell(hmmio);
}
