/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * This file is part of SanKit -- A multiplatform set of C code
 * for reading and writing PGN formatted chess games. In addition
 * it can be used as an engine to determine in real time if proposed
 * moves are legal or not. It appears to generate near perfect PGN
 * from incorrectly formatted files.
 *
 * Copyright 1994 Steven J. Edwards All Rights Reserved.
 * Copyright 2009-2011 David Hoerl All Rights Reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice, this list of
 *       conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
 *       of conditions and the following disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY David Hoerl ''AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David Hoerl OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*>>> sanpgn.c: SAN project PGN (Portable Game Notation) output routines */

/* Revised: 1993.05.16 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "sandef.h"
#include "sanvar.h"

#include "sandsp.h"
#include "sanmne.h"
#include "sanpgn.h"
#include "sanrst.h"
#include "santag.h"
#include "sanutl.h"

siT line_wrap;	// DFH

/*** Locals */

/* the output file of interest */

static FILEptrT gms_fptr;

/* the current character column */

static siT col;

/*--> SANPGNSetUp: set up game move score processing */
static
void SANPGNSetUp(FILEptrT fptr)
{
	gms_fptr = fptr;
	col = 0;

	return;
}

/*--> SANPGNNL: produce newline */
static
void SANPGNNL(void)
{
	SANGateChar(gms_fptr, '\n');
	col = 0;

	return;
}

/*--> SANPGNResTag: produce reserved tag output line */
static
void SANPGNResTag(rsvtagT rsvtag)
{
	charptrT s;

	s = SANTagFormat(SANTagLocate(rsvtagv[rsvtag]));
	SANGateStr(gms_fptr, s);
	SANGateChar(gms_fptr, '\n');
	SANMemFree(s);

	return;
}

/*--> SANPGNResTag: produce all tag output line */
static
void SANPGNResTagDFH(tagptrT tagptr)
{
	charptrT s;

	s = SANTagFormat(tagptr);
	SANGateStr(gms_fptr, s);
	SANGateChar(gms_fptr, '\n');
	SANMemFree(s);

	return;
}

/*--> SANPGNWrapStr: produce wrapped string w/possibly prepended space */
static
void SANPGNWrapStr(charptrT s)
{
	siT length;
	siT lineWidth = line_wrap ? 80 : 0x7FFF;	// DFH

	length = strlen(s);
	if(col == 0) {
		col = length;
	} else
	if((col + 1 + length) < lineWidth) {
		SANGateChar(gms_fptr, ' ');
		col += (1 + length);
	} else {
		SANPGNNL();
		col = length;
	}
	SANGateStr(gms_fptr, s);

	return;
}

static
void SANPGNWrapText(charptrT s)
{
	siT lineWidth = line_wrap ? 80 : 0x7FFF;	// DFH

	while(*s) {
		if(col >= lineWidth && *s == ' ') {
			SANPGNNL();
			col = 0;
		} else {
			SANGateChar(gms_fptr, *s);
			++col;
		}
		++s;
	}
	return;
}

/*--> SANPGNScore: produce game score */
static
void SANPGNScore(void)
{
	siT first, hcn;
	hptrT hptr;
	sanT san;

	first = 1;
	hcn = 0;
	hptr = hbase;

	while(hcn < hn) {
		if(first || (hptr->h_e.e_actc == c_w)) {
			(void) sprintf(stv, "%hd.", hptr->h_e.e_fmvn);
			SANPGNWrapStr(stv);
		}

		if(first && (hptr->h_e.e_actc == c_b)) {
			SANPGNWrapStr("...");
		}

		first = 0;

		SANEncode(&hptr->h_m, san);
		SANPGNWrapStr(san);

		if(hptr->h_m.m_cmt) {
			SANPGNWrapText(" {");
			SANPGNWrapText(hptr->h_m.m_cmt);
			SANPGNWrapText("}");
		}
		if(hptr->h_m.m_rav) {
			SANPGNWrapText(" (");
			SANPGNWrapText(hptr->h_m.m_rav);
			SANPGNWrapText(")");
		}

		hcn++;
		hptr++;
	}

	if(gtc == gtc_norm) {
		SANPGNWrapStr(gtcstrv[cv_gtc_gsv[SANStatus()]]);
	} else {
		SANPGNWrapStr(gtcstrv[gtc]);
	}

	if(col != 0) {
		SANPGNNL();
	}

	return;
}

/*--> SANPGNCorrespondenceReport: produce correspondence report to file */
nonstatic
void SANPGNCorrespondenceReport(FILEptrT fptr)
{
	rankT rank;
	fileT file;
	cpT cp;

	SANPGNSetUp(fptr);

/* output color tags */

	SANPGNResTag(rsvtag_white);
	SANPGNResTag(rsvtag_black);
	SANPGNNL();

/* output game score */

	SANPGNScore();
	SANPGNNL();

/* output board */

	for(rank = rank_8; rank >= rank_1; rank--) {
		for(file = file_a; file <= file_h; file++) {
			if((cp = gb.bm[rank][file]) == cp_v0) {
				if((rank & bit) == (file & bit)) {
					SANGateStr(gms_fptr, "::");
				} else {
					SANGateStr(gms_fptr, "  ");
				}
			} else {
				SANGateChar(gms_fptr, accv[cv_c_cpv[cp]]);
				SANGateChar(gms_fptr, acpv[cv_p_cpv[cp]]);
			}
		}
		SANPGNNL();
	}
	SANPGNNL();

	return;
}

/*--> SANPGNEventReport: produce event report to file */
nonstatic
void SANPGNEventReport(FILEptrT fptr)
{
	SANPGNSetUp(fptr);

/* output event tags */


	rsvtagT rsvtag;
/* output event tags */
	for(rsvtag = 0; rsvtag < rsvtagL; rsvtag++) {
		SANPGNResTag(rsvtag);
	}

// DFH
	tagptrT tagptr = head_tagptr;
	while(tagptr) {
		if(!(tagptr->tag_flag & tagf_perm)) {
			SANPGNResTagDFH(tagptr);
		}
		tagptr = tagptr->tag_next;
	}



	SANPGNNL();

/* output game score */

	SANPGNScore();
	SANPGNNL();

	return;
}

/*<<< sanpgn.c: EOF */
