/*
** Copyright (C) 2001-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include	"sfconfig.h"

#include	<stdio.h>
#include	<string.h>
#include	<math.h>

#include	"sndfile.h"
#include	"common.h"

#define STRINGS_DEBUG 0

int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
{	char	new_str [128] ;
	size_t	str_len ;
	int		k, str_flags ;

	if (str == NULL)
		return SFE_STR_BAD_STRING ;

	str_len = strlen (str) ;

	/* A few extra checks for write mode. */
	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
	{	if ((psf->strings.flags & SF_STR_ALLOW_START) == 0)
			return SFE_STR_NO_SUPPORT ;
		if (psf->have_written && (psf->strings.flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_SUPPORT ;
		/* Only allow zero length strings for software. */
		if (str_type != SF_STR_SOFTWARE && str_len == 0)
			return SFE_STR_BAD_STRING ;
		} ;

	/* Find the next free slot in table. */
	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
	{	/* If we find a matching entry clear it. */
		if (psf->strings.data [k].type == str_type)
			psf->strings.data [k].type = -1 ;

		if (psf->strings.data [k].type == 0)
			break ;
		} ;

	/* Determine flags */
	str_flags = SF_STR_LOCATE_START ;
	if (psf->file.mode == SFM_RDWR || psf->have_written)
	{	if ((psf->strings.flags & SF_STR_ALLOW_END) == 0)
			return SFE_STR_NO_ADD_END ;
		str_flags = SF_STR_LOCATE_END ;
		} ;

	/* More sanity checking. */
	if (k >= SF_MAX_STRINGS)
		return SFE_STR_MAX_COUNT ;

	if (k == 0 && psf->strings.storage_used != 0)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->strings.storage_used != 0\n") ;
		return SFE_STR_WEIRD ;
		} ;

	if (k != 0 && psf->strings.storage_used == 0)
	{	psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->strings.storage_used == 0\n") ;
		return SFE_STR_WEIRD ;
		} ;

	/* Special case for the first string. */
	if (k == 0)
		psf->strings.storage_used = 0 ;

	switch (str_type)
	{	case SF_STR_SOFTWARE :
				/* In write mode, want to append libsndfile-version to string. */
				if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
				{	if (strstr (str, PACKAGE_NAME) == NULL)
					{	/*
						** If the supplied string does not already contain a
						** libsndfile-X.Y.Z component, then add it.
						*/
						if (strlen (str) == 0)
							snprintf (new_str, sizeof (new_str), "%s-%s", PACKAGE_NAME, PACKAGE_VERSION) ;
						else
							snprintf (new_str, sizeof (new_str), "%s (%s-%s)", str, PACKAGE_NAME, PACKAGE_VERSION) ;
						}
					else
						snprintf (new_str, sizeof (new_str), "%s", str) ;

					str = new_str ;
					} ;
				break ;

		case SF_STR_TITLE :
		case SF_STR_COPYRIGHT :
		case SF_STR_ARTIST :
		case SF_STR_COMMENT :
		case SF_STR_DATE :
		case SF_STR_ALBUM :
		case SF_STR_LICENSE :
		case SF_STR_TRACKNUMBER :
		case SF_STR_GENRE :
				break ;

		default :
			psf_log_printf (psf, "%s : SFE_STR_BAD_TYPE\n", __func__) ;
			return SFE_STR_BAD_TYPE ;
		} ;

	/* Plus one to catch string terminator. */
	str_len = strlen (str) + 1 ;

	if (psf->strings.storage_used + str_len + 1 > psf->strings.storage_len)
	{	char * temp = psf->strings.storage ;
		size_t newlen = 2 * psf->strings.storage_len + str_len + 1 ;

		newlen = newlen < 256 ? 256 : newlen ;

		char * new_storage = realloc(temp, newlen);
		if (new_storage == NULL)
		{
			return SFE_MALLOC_FAILED ;
			} else {
			psf->strings.storage = new_storage;
			} ;

		psf->strings.storage_len = newlen ;
		} ;

	psf->strings.data [k].type = str_type ;
	psf->strings.data [k].offset = psf->strings.storage_used ;
	psf->strings.data [k].flags = str_flags ;

	memcpy (psf->strings.storage + psf->strings.storage_used, str, str_len) ;
	psf->strings.storage_used += str_len ;

	psf->strings.flags |= str_flags ;

#if STRINGS_DEBUG
	printf ("storage_used         : %zd / %zd\n", psf->strings.storage_used, psf->strings.storage_len) ;
	psf_hexdump (psf->strings.storage, psf->strings.storage_used) ;
#endif

	return 0 ;
} /* psf_store_string */

int
psf_set_string (SF_PRIVATE *psf, int str_type, const char *str)
{	if (psf->file.mode == SFM_READ)
		return SFE_STR_NOT_WRITE ;

	return psf_store_string (psf, str_type, str) ;
} /* psf_set_string */

const char*
psf_get_string (SF_PRIVATE *psf, int str_type)
{	int k ;

	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
		if (str_type == psf->strings.data [k].type)
			return psf->strings.storage + psf->strings.data [k].offset ;

	return NULL ;
} /* psf_get_string */

int
psf_location_string_count (const SF_PRIVATE * psf, int location)
{	int k, count = 0 ;

	for (k = 0 ; k < SF_MAX_STRINGS ; k++)
		if (psf->strings.data [k].type > 0 && psf->strings.data [k].flags & location)
			count ++ ;

	return count ;
} /* psf_location_string_count */
