/*
	Copyright (C) 2008-2026 Mark Tyler

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program in the file COPYING.
*/

#include "ced_eval.h"



int cedparser_get_cell_value (
	CedParser	* const	state,
	PCellRef const	* const	cref,
	double		* const	result
	)
{
	int		r, c;
	CedCell		* cell;

	r = state->row    * cref->cellref.row_m + cref->cellref.row_d;
	c = state->column * cref->cellref.col_m + cref->cellref.col_d;

	if ( ! cref->sheet || r < 1 || c < 1 )
	{
		return 1;		// Invalid cell reference
	}

	cell = ced_sheet_get_cell ( cref->sheet, r, c );

	if ( cell && cell->type != CED_CELL_TYPE_NONE )
	{
		if ( cell->type != CED_CELL_TYPE_ERROR )
		{
			result[0] = cell->value;
		}
		else
		{
			return 1;	// Error in cell
		}
	}
	else
	{
		result[0] = 0;
	}

	return 0;	// Success
}

int pargset_arg_add (
	PArgSet		* const	argset,
	CedFuncArg	* const	arg
	)
{
	if ( argset->tot >= CED_FUNC_ARG_MAX )
	{
		return 1;
	}

	argset->arg[ argset->tot ] = arg[0];
	argset->tot ++;
	argset->arg[ argset->tot ].type = 0;

	return 0;
}

int ced_strtosheetref (
	char	const	* const	input,
				// Input string to parse NUL terminated
				// & ' character = start/finish, e.g.
				// 'Sheet 12'
				// '' = ' : 'Sheet '' 12' = Sheet ' 12
	CedSheet	** const result,
				// Put result here
	char	const *	* const next,
				// Next un-parsed character is put here,
				// (NULL = don't use
	CedBook		* const book
				// The book to search for this sheet
				// reference
	)
{
	if ( ! input || input[0] != '\'' || ! result || ! book )
	{
		return 1;
	}

	char * nst = strdup ( input + 1 );
	if ( ! nst )
	{
		return 1;
	}

	char		* dest;
	char	const	* ss;

	// Filter out occurences of '' and replace with ' + remove trailing '
	for (	dest = nst, ss = input + 1;
		ss[0] != 0;
		ss++, dest++ )
	{
		if ( ss[0] == '\'' )
		{
			if ( ss[1] == '\'' )
			{
				// ''
				ss++;
			}
			else
			{
				// Final trailing ' at end
				// Ensure next[0] points to next unparsed char
				ss++;
				break;
			}
		}

		dest[0] = ss[0];
	}

	dest[0] = 0;

	if ( next )
	{
		next[0] = ss;
	}

	mtTreeNode const * const node = mtkit_tree_node_find(book->sheets, nst);

	free ( nst );
	nst = NULL;

	if ( ! node )
	{
		return 1;
	}

	result[0] = (CedSheet *)(node->data);

	return 0;
}



#ifndef CED_USE_BISON_PARSER



CedParser ced_sheet_parse_text (
	CedSheet	* const	sheet,
	int		const	row,
	int		const	column,
	char	const	* const	text,
	CedCell		* const	cell
	)
{
	CedParser state = {
		.flag		= 0,
		.ced_errno	= 0,
		.sp		= 0,
		.data		= 0.0,
		.sheet		= sheet,
		.cell		= cell,
		.row		= row,
		.column		= column
	};

	if ( ced_parse_text ( text, &state ) )
	{
		state.flag |= CED_PARSER_FLAG_ERROR;
	}

	if ( cell )
	{
		// Update cell type according to errors/live references etc.

		if ( state.flag & CED_PARSER_FLAG_ERROR )
		{
			cell->type = CED_CELL_TYPE_ERROR;
			cell->value = state.ced_errno + 1000 * state.sp;
		}
		else if ( state.flag & CED_PARSER_FLAG_VOLATILE )
		{
			cell->type = CED_CELL_TYPE_FORMULA_EVAL;
		}
	}

	return state;
}



#endif	// CED_USE_BISON_PARSER

