/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 * 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.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*>>> sanhst.c: SAN project playing history stack operations */

/* Revised: 1994.02.10 */

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

#include <time.h>

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

#include "sanhst.h"
#include "sanmsc.h"
#include "sanutl.h"
#include "sanval.h"

/*--> SANHistPush: push a history record on the history stack */
nonstatic
void SANHistPush(siT ordinal)
{
	sqT sq;

	if(hn == hL) {
		SANFatal("SANHistPush: overflow");
	} else {
		hcurr->h_o = ordinal;
		hcurr->h_e = curr_e;
		hcurr->h_m = *curr_g.g_curr;
		for(sq = sq_a1; sq <= sq_h8; sq++) {
			if((sq % 2) == 0) {
				hcurr->h_z[sq / 2] = gb.bv[sq];
			} else {
				hcurr->h_z[sq / 2] |= (gb.bv[sq] << 4);
			}
		}
		hcurr++;
		hn++;
	}

	return;
}

/*--> SANHistPop: pop a history record off the history stack */
nonstatic
void SANHistPop(void)
{
	sqT sq;

	if(hn == 0) {
		SANFatal("SANHistPop: underflow");
	} else {
		/* drop history pointer and count */

		hcurr--;
		hn--;

		/* restore previous environment */

		curr_e = hcurr->h_e;

		/* restore previous board */

		for(sq = sq_a1; sq <= sq_h8; sq++) {
			if((sq % 2) == 0) {
				gb.bv[sq] = hcurr->h_z[sq / 2] & 0x0f;
			} else {
				gb.bv[sq] = (hcurr->h_z[sq / 2] >> 4) & 0x0f;
			}
		}

		/* update to set generation */

		SANUpdate();

		/* indicate the move played from this postition */

		curr_g.g_curr = SANFindMove(&hcurr->h_m);
	}

	return;
}

/*--> SANHistClear: clear/resethistory information */
nonstatic
void SANHistClear(void)
{
	hptrT hptr = hbase;
	for(int idx=0; idx<hn; ++idx, ++hptr) {
		// if(hptr->h_m.m_cmt) printf("CMT %s\n", hptr->h_m.m_cmt);
		// if(hptr->h_m.m_rav) printf("RAV %s\n", hptr->h_m.m_rav);
		free(hptr->h_m.m_cmt);
		hptr->h_m.m_cmt = NULL;

		free(hptr->h_m.m_rav);
		hptr->h_m.m_rav = NULL;
	}
	hn = 0;
	hcurr = hbase;

	return;
}

/*--> SANHistInit: one time call to initialize history */
nonstatic
void SANHistInit(void)
{
	hbase = (hptrT) SANMemGrab(sizeof(hT) * hL);
	SANHistClear();

	return;
}

/*--> SANHistTerm: one time call to terminate history */
nonstatic
void SANHistTerm(void)
{
	SANMemFree(hbase);
	hbase = hcurr = NULL;
	hn = 0;

	return;
}

/*<<< sanhst.c: EOF */
