// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): Jonathan Berry

// This software is copyrighted by the DIMACS Center at Rutgers, The State
// University of New Jersey.  IT IS PROVIDED AS IS, AND THE AUTHORS, DIMACS, AND
// RUTGERS, THE STATE UNIVERSITY OF NEW JERSEY  DISCLAIM
// ALL LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
// DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
// IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
// NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

// The authors hereby grant permission to use, copy, modify, distribute,
// and license this software and its documentation for any purpose, provided
// that existing copyright notices are retained in all copies and that this
// notice is included verbatim in any distributions. No written agreement,
// license, or royalty fee is required for any of the authorized uses.
// Modifications to this software may be copyrighted by their authors
// and need not follow the licensing terms described here, provided that
// the new terms are clearly indicated on the first page of each file where
// they apply.

// Last File Update: 31-Jul-1996
// 

#include <LINK/algorithm/AnimationData.h>
#include <iostream.h>

AnimationData::~AnimationData()
{	
	Iterator<String> get_cmd(&cmds);
	Iterator<String> get_undo(&undo_cmds);
	String cmd, undo;
	while (get_cmd(cmd) && get_undo(undo)) {
		delete cmd;
		delete undo;
	}
	cmds.clear();
	undo_cmds.clear();
}

void AnimationData::debug()
{
	cout << "---------------------------------------------------" << endl;
	cout << "--Animation Commands-------------------------------" << endl;
	cout << "---------------------------------------------------" << endl;
	cout << cmds << endl;
	cout << "- - - - - - - - - - - - - - - - - - - - - - - - - -" << endl;
	cout << undo_cmds << endl;
	cout << "---------------------------------------------------" << endl;
}

void AnimationData::appendCmd(String cmd, String undo_cmd)
{	
	cmds.append(cmd);
	undo_cmds.append(undo_cmd);
}

void AnimationData::markCurrent()
{
	// unmarked cmd:    "<scheme-cmd>  \0"
	//   marked cmd:    "<scheme-cmd>()\0"
	String cur_cmd = cmds.info(current_cmd);
	if (!cur_cmd) 
		return;
	int len = strlen(cur_cmd);
	cur_cmd[len-2] = '('; 
	cur_cmd[len-1] = ')';
}

int AnimationData::currentMarkedQ() const
{
	String cur_cmd = cmds.info(current_cmd);
	if (!cur_cmd)
		return TRUE;     // tell Run, Continue cmds to stop
	int len = strlen(cur_cmd);
	if ((cur_cmd[len-2] == '(') && (cur_cmd[len-1] == ')'))
		return TRUE;
	return FALSE;
}

int AnimationData::currentInitQ() const
{
	String cur_cmd = cmds.info(current_cmd);
	if (!cur_cmd)
		return FALSE;     // tell Run, Continue cmds to stop
	int len = strlen(cur_cmd);
//	cerr << "debug: AnimationData::currentQ()::cur_cmd = " << cur_cmd << endl;
	if (cur_cmd[len-3] == 't')
		return TRUE;
	else if (cur_cmd[len-3] == 'f')
		return FALSE;
	else {
		cerr << "error: AnimationData::currentInitQ()" << endl;
		return FALSE;
	}
}

void AnimationData::clearMarks()
{
	Iterator<String> get_cmd(&cmds);
	String cmd;
	int len;
	while (get_cmd(cmd)) {
		len = strlen(cmd);
		cmd[len-2] = ' '; 
		cmd[len-1] = ' ';
	}
}

String AnimationData::resetCmds()
{
	_direction = FORWARD;
	current_cmd = cmds._first;;
	current_undo_cmd = undo_cmds._first;
	return cmds.info(current_cmd);
}

String AnimationData::resetUndoCmds()
{
	_direction = BACKWARD;
	current_cmd = cmds._last;;
	current_undo_cmd = undo_cmds._last;
	return undo_cmds.info(current_undo_cmd);
}

String AnimationData::currentCmd() 
{
	if (_direction == FORWARD) {
		if (!current_cmd)
			return resetCmds();
		return cmds.info(current_cmd);
	} else {
		if (!current_undo_cmd)
			return resetUndoCmds();
		return undo_cmds.info(current_undo_cmd);
	}
}

String AnimationData::prevUndoCmd()
{
	_direction = BACKWARD;
	if (!current_cmd)
		resetUndoCmds();
	current_cmd = cmds.predecessor(current_cmd);
	current_undo_cmd = undo_cmds.predecessor(current_undo_cmd);
	return undo_cmds.info(current_undo_cmd);
}

String AnimationData::nextCmd()
{
	_direction = FORWARD;
	if (!current_cmd)
		resetCmds();
	current_cmd = cmds.successor(current_cmd);
	current_undo_cmd = undo_cmds.successor(current_undo_cmd);
	String result = cmds.info(current_cmd);
	return result;
}
		
int 
AnimationData::operator<(const AnimationData& c) const
{ 
	return id < c.id;
}

int 
AnimationData::operator==(const AnimationData& c) const
{ 
	return id == c.id;
}

int 
AnimationData::operator!=(const AnimationData& c) const
{ 
	return id != c.id;
}
