/* ==================================
     zmd2mid sigファイルを読み込む
   ================================== */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "MThdINFO.h"
#include "etc.h"

/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
	#include "setjmp.h"
	#include "etc.h"
	extern jmp_buf g_ztommark;
#endif
/* <== ryk */

#define MAXLINELEN	512
/*
#define DEBUG
*/

#include "config.h"
void envread(FILEINFO f,char *instname[],WORD *envdata,char *copyright);
DWORD csearch(char str[],char a);

DWORD getbar(char *envstr,DWORD *bar);

/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
	#include "etc.h"
	#include "setjmp.h"
	extern jmp_buf g_ztommark;
#endif
/* <== */


/* ==========================
     sigファイルを読み込む
   ========================== */

void envread(FILEINFO f,char *instname[],WORD *envdata,char *copyright)
{
	FILE *fp;
	char filename[2048];
	char x[MAXLINELEN + 1],xx[MAXLINELEN + 1];
	DWORD i,instnum=0,envnum=0;

	if (f.sigfile[0]) {
		strcpy(filename,f.sigfile);
	} else {
		strcpy(filename,f.inpfile);
	}
	for (i = strlen(filename); i > 0; i--) {
		if (filename[i] == '.') {
			break;
		}
	}
	if (i < 0) {
		i = strlen(filename);
	}
	strcpy(&filename[i],".sig");

	fp = fopen(filename,"rt");
	if (fp != (FILE *)NULL) {
#ifndef ENGLISH
		ZTOMFormatMessage(stderr, "%s:signatureファイルを読み込みます。\n",filename);
#else
		ZTOMFormatMessage(stderr,"%s: reading signature file...\n",filename);
#endif
		while (1) {
			char *err = fgets(xx,MAXLINELEN,fp);

			if ( err == NULL ) {
				if (ferror(fp)) {
#ifndef ENGLISH
					ZTOMFormatMessage(stderr,"%s:読み込みに失敗しました。\n",filename );
#else
					ZTOMFormatMessage(stderr,"%s: failed to read.\n",filename);
#endif
					terminateProgram(1);
/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
					longjmp(g_ztommark, 1);
#endif
/* <== ryk */
				} else if ( feof(fp) ) {
					/* printf( "[%s]がＥＯＦ。\n",filename ); */
					break;
				} else {
					ZTOMFormatMessage(stderr,"%s: file error.\n",filename );
					terminateProgram(1);
/* ryk ==> */
#ifdef ZTOM_STATIC_LIB	/* Static lib */
					longjmp(g_ztommark, 1);
#endif
/* <== ryk */
				}
			}

			do {
				DWORD i = 0;
				while (xx[i] == '\t' || xx[i] == ' ') {
					i++;
				}
				strcpy(x,&xx[i]);
			} while (0);

			if (x[0] == '*' || x[0] == '#' || x[0] == '/') {
				continue;
			}

			if ( !strncmp(x,"楽:",3) ) {
				DWORD i = csearch(&x[3],'\n');
				if (i == -1) { 
					ZTOMFormatMessage(stderr, "%s:data format error.\n",x );
					continue;
				}
				if (i > 255) {
					i = 255;
				}
				strncpy( instname[instnum],&x[3],i );
				instname[instnum++][i]='\0';
				if (instnum >= TRKMAX) {
#ifndef ENGLISH
					ZTOMFormatMessage(stderr,"%s:楽器名が多すぎます。\n",filename);
#else
					ZTOMFormatMessage(stderr,"%s: Too many instrument name.\n",filename);
#endif
					continue;
				}
				/* printf( "楽%d：%s\n",instnum,instname[instnum-1]); */
			}
			if ( !strncmp(x,"著:",3) ) {
				DWORD i = csearch(&x[3],'\n');
				if (i == -1) { 
					ZTOMFormatMessage(stderr, "%s:data format error.\n",x );
					continue;
				}
				if (i > CRlen) {
					i = CRlen;
				}
				strncpy( copyright,&x[3],i );
				copyright[i]='\0';
			}
			if ( !strncmp(x,"拍:",3) ) {
				DWORD j = 3;
				do {
					DWORD i;
					j += getbar(&x[j],&i);		/* 小節数を得る */

					if ( x[j] != '=' && x[j] != '/' ) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"拍：format error.\n");
#else
						ZTOMFormatMessage(stderr,"beat:format error.\n");
#endif
						continue;
					}
					envdata[envnum++] = (x[j] == '/')? 1 : i;
					if (envnum > ENVMAX) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"signatureファイルの設定事項が多すぎます。\n");
#else
						ZTOMFormatMessage(stderr,"signature file overflows.\n");
#endif
						envdata[--envnum] = -1;
						continue;
					}
					if ( x[j] == '=' ) {
						i = 0;
						j++;
						while (x[j] == ' ' || x[j] == '\t') {
							j++;
						}
						while (isdigit(x[j])) {
							i = i * 10 + x[j++] - '0';	/* 分子の算出 */
						}
						while (x[j] == ' ') {
							j++;
						}
						if ( x[j] != '/' ) {
#ifndef ENGLISH
							ZTOMFormatMessage(stderr,"拍：format error.\n");
#else
							ZTOMFormatMessage(stderr,"beat:format error.\n");
#endif
							envdata[--envnum] = -1;
							continue;
						}
						j++;
					}
					envdata[envnum] = i * 32;
					i = 0;
					while (x[j] == ' ' || x[j] == '\t') {
						j++;
					}
					while (isdigit(x[j])) {
						i = i * 10 + x[j++] - '0';	/* 分母の算出 */
					}
					while (x[j] == ' ' || x[j] == '\t') {
						j++;
					}
					if ( x[j] != ',' && x[j] != '\n'  ) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"拍：format error.\n");
#else
						ZTOMFormatMessage(stderr,"beat:format error.\n");
#endif
						envdata[--envnum] = -1;
						continue;
					}
					do {
						i /= 2;
						envdata[envnum]++;
					} while (i > 1);
					envdata[envnum] |= 0x2000;
					envdata[envnum++] &= 0xBFFF;
					envdata[envnum] = -1;
					if (envnum > ENVMAX) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"%s:設定事項が多すぎます。\n",filename);
#else
						ZTOMFormatMessage(stderr,"%s: too many settings.\n",filename);
#endif
						continue;
					}
				} while (x[j++] != '\n');
			}
			if ( !strncmp(x,"調:",3) ) {
				DWORD j = 3;
				do {
					DWORD i;
					j += getbar(&x[j],&i);		/* 小節数を得る */

					if (x[j] != '=' && !isalpha(x[j])) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"調：format error.\n");
#else
						ZTOMFormatMessage(stderr,"key:format error.\n");
#endif
						continue;
					}
					envdata[envnum++] = (x[j] == '=')? i : 1;
					if (envnum > ENVMAX) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"signatureファイルの設定事項が多すぎます。\n");
#else
						ZTOMFormatMessage(stderr,"signature file overflows.\n");
#endif
						envdata[--envnum] = -1;
						continue;
					}
					if ( x[j] == '=' ) {
						j++;
					}
					envdata[envnum] = 14;
					j--;
					do {
						char *cho="FCGDAEBb#m";
						j++;
						for (i = 0; i <= 9 ;i++) {
							if (x[j] == cho[i]) {
								break;
							}
						}
						switch (i) {
							case 7:		/* b */
								envdata[envnum] -= 14;
								break;
							case 8:		/* # */
								envdata[envnum] += 14;
								break;
							case 9:		/* m */
								envdata[envnum] -= (6-1);
								if (envdata[envnum] < 0)
#ifndef ENGLISH
									ZTOMFormatMessage(stderr,"調:MIDでは未サポートのコードです。\n");
#else
									ZTOMFormatMessage(stderr,"key: no-supported key in SMF.\n");
#endif
								break;
							case 10:	/* no found */
								i = -1;
								break;
							default:	/* FCGDAEB */
								envdata[envnum] += i * 2 - 2;
								break;
						}
					} while (i != -1);
					envdata[envnum++] &= 0x9FFF;
					envdata[envnum] = -1;
					if (envnum > ENVMAX) {
#ifdef ENGLISH
						ZTOMFormatMessage(stderr,"%s:設定事項が多すぎます。\n",filename);
#else
						ZTOMFormatMessage(stderr,"%s: too many settings.\n",filename);
#endif
						continue;
					}

					while (x[j] == ' ' || x[j] == 0x09) {
						j++;
					}
					if ( x[j] != ',' && x[j] != '\n'  ) {
#ifndef ENGLISH
						ZTOMFormatMessage(stderr,"調：format error.\n");
#else
						ZTOMFormatMessage(stderr,"key:format error.\n");
#endif
						continue;
					}
				} while (x[j++] != '\n');
			}




#ifdef DEBUG
		getch();
#endif
		}
		fclose(fp);
	}
}


/* =================================================
     文字列サーチ(ない時-1,ある時はその位置を返す)
   ================================================= */

DWORD csearch(char str[],char a)
{
	DWORD i, len = strlen(str);
	BYTE flag = 1;

	for (i = 0; i <= len - 1; i++) {
		if (str[i] == a) {
			flag = 0;
			break;
		}
	}
	if (flag) {
		i = -1;
	}
	return i;
}


/* ===============================================================
     小節数を取り込む(barに入る)。そこまでに何文字読んだかを返す
   =============================================================== */

DWORD getbar(char *str,DWORD *bar)
{
	char *str_ = str;

	*bar = 0;
	while (*str == ' ' || *str == '\t') {
		str++;
	}
	while (isdigit(*str)) {
		*bar = *bar * 10 + *str++ - '0';	/* 小節数の算出 */
	}
	while (*str == ' ' || *str == '\t') {
		str++;
	}

	return str - str_;
}
