#include "jcabc2ps.h"
#include "parse.h"
#include "prsAnn.h"
#include <ctype.h>

#define ANNLENGTH 200	// Max length of annotation buffer
Ann annname[] = {
	{D_GRACE,   "GRACE"},        /*  1 */
	{D_STACC,   "STACC"},        /*  2 */
	{D_SLIDE,   "SLIDE"},        /*  3 */
	{D_EMBAR,   "EMBAR"},        /*  4 */
	{D_HOLD,    "HOLD"},         /*  5 */
	{D_HOLD,    "fermata"},      /*  5 */
	{D_UPBOW,   "UPBOW"},        /*  6 */
	{D_UPBOW,   "up"},           /*  6 */
	{D_DOWNBOW, "DOWNBOW"},      /*  7 */
	{D_DOWNBOW, "down"},         /*  7 */
	{D_ROLL,    "ROLL"},         /*  8 */
	{D_TRILL,   "TRILL"},        /*  9 */
	{D_HAT,     "HAT"},          /* 10 */
	{D_ATT,     "ATT"},          /* 11 */
	{D_SEGNO,   "segno"},        /* 12 */
	{D_CODA,    "coda"},         /* 13 */
	{D_CRESC1,  "crescendo("},   /* 14 */
	{D_CRESC2,  "crescendo)"},   /* 15 */
	{D_DIMIN1,  "diminuendo("},  /* 16 */
	{D_DIMIN2,  "diminuendo)"},  /* 17 */
	{0},
};

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Parse an annotation.  This has the syntax !text!, where the text is any of a
* list  of  official musical symbols.  This is a "preliminary" implementation;
* there is still work to be done on this topic.

*/
int prsAnn()
{	char *F = "prsAnn";
	char *q;
	int   c, i, l;
	int   n=0;		// Annotation count
	float yy;
    char ann_t[200];
    double ann_x, ann_y;
    int ann_p = 0;
    char marker;

	V3 "%s: Called at <%s>\n",F,P V;
    marker = *P;
	if (*P != '!' && *P != '+') {
        V5 "%s: No annotation\n",F V; return 0;
    }
	if (!P[1])     {V5 "%s: Trailing '%c'\n",F,marker V; return 0;}
	if (!ann) {
		V5 "%s: No current annotation\n",F V;
		TextInit(&ann,32);
	}
	q = P;				/* Note position of opening quote */
	P++;				/* Skip to first char of string */
	ann_p = 0;
	ann_x = ann_y = 0.0;
    l = 0;
	switch (c = *P) {	/* Check for position char */
	case '^':			/* Above staff */
		if (P[1] == '!') {	// !^! is a marcato
			V3 "  Annotation is marcato (hat) c='%c'\n",c V;
			P +=2; ann_p = D_HAT; break;
		}
		V3 "  Annotation position '%c' above staff.\n",c V;
		P++; ann_p = P_ABOVE; ann_y = 38; break;
	case '<':			/* Left of note */
		V3 "  Annotation position '%c' left of note.\n",c V;
		P++; ann_p = P_LEFT; break;
	case '=':			/* Next to note */
		V3 "  Annotation position '%c' next to note.\n",c V;
		P++; ann_p = P_NEXT; break;
	case '>':			/* Right of note */
		V3 "  Annotation position '%c' right of note.\n",c V;
		P++; ann_p = P_RIGHT; break;
	case '_':			/* Below staff */
		V3 "  Annotation position '%c' below staff.\n",c V;
		P++; ann_p = P_BELOW; ann_y = -12; break;
	}
	V3 "%s: Position is %d ann_y=%.3f\n",F,ann_p,ann_y V;
	while ((c = *P) && (c != marker) && (c != ' ')) {
		ann_t[l++] = c;
		ann_t[l] = 0;
		if (c == '@') {
			if (sscanf(P+1,"%f",&yy) > 0) {
				ann_y = yy;
				V5 "%s: Matched ann_y=%6.3f\n",F,yy V;
			}
		}
		V7 "%s: ann=\"%s\"\n",F,ann_t V;
		if (l >= ANNLENGTH) {
			syntax("String for annotation too long", q);
			return 1; // this behavior strikes me as questionable
		}
		P++;
	}
	if (c != marker) {
		if (!c) V3 "%s: EOL reached while parsing annotation.\n",F V;
		if ( c) V3 "%s: '%c' found  while parsing annotation.\n",F,c V;
		P = q + 1;			/* Reposition just after the ! */
		while ((c = *P) && isspace(c)) P++;
//		TextInit(&ann,64);		/* Discard accumulated chars */ -- no longer needed
		V3 "%s: Continue at <%3.3s>\n",F,P V;
		return 0;			/* Ignore it; it's an abc2win ! */
	}
	P++;

    // skip trailing whitespaces
	while ((c = *P) && ((c == ' ') || (c == '\t'))) {	// Actually, either  parenthization will work ;-)
		P++;
	}

	V3 "  parsed annotation <%s>\n",ann_t V;
	for (i=0; annname[i].value; i++) {
		if (!strcasecmp(ann_t,annname[i].value)) {
			V2 "%s: Matched annotation %d name %s type %d.\n",F,i,ann_t,annname[i].type V;
            addDeco(annname[i].type);
//			V5 "%s: Deco dtype[%d] is %d \"%s\"\n",F,decos,dtype[decos],TextStr(ann) V;
			++n;	// Number of decos found
			switch (annname[i].type) {			// Experimental: Recognize crescdo/diminuendo markings
			case D_CRESC1:		// "crescendo("   /* 14 */
			//	strncpy(ann_t,"<...",ANNLENGTH);
				ann_t[9] = '<';
				break;
			case D_CRESC2:		// "crescendo)"   /* 15 */
			//	strncpy(ann_t,"...>",ANNLENGTH);
				ann_t[9] = '>';
				break;
			case D_DIMIN1:		// "diminuendo("  /* 16 */
			//	strncpy(ann_t,">...",ANNLENGTH);
				ann_t[10] = '>';
				break;
			case D_DIMIN2:		// "diminuendo)"  /* 17 */
			//	strncpy(ann_t,"...<",ANNLENGTH);
				ann_t[10] = '<';
				break;
			}
			break;
		}
	}

    if (n == 0) {	// if no decoration found, treat as annotation
    	if (ann->l > 0) {		/* Only one allowed at present */
    		syntax("Overwrite earlier annotation", q);
    		TextInit(&ann,64);
    	}
        strcpy (ann->t, ann_t);
        ann->l = l;
        ann->x = ann_x;
        ann->y = ann_y;
        ann->p = ann_p;
    }

//	V3 "%s: %d decos found, %d total.\n",F,n,decos V;
	V3 "%s: Return 1 for ann %c%s%c\n",F,marker,TextStr(ann),marker V;
	return 1;
}

