/*  gnutrition - a nutrition and diet analysis program.
 *  Copyright (C) 2000 Edgar Denny (e.denny@ic.ac.uk)
 *
 *  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 2 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; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#ifdef HAVE_CONFIG_H
#	include <config.h>
#endif

#include <limits.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

#include <gnome.h>
#include <ctype.h>

#include "text_util.h"

gchar *
extract_column( gchar *line, gint col_num, gint n_char)
{
	gchar col_sep = '^', padding = '~', end_line = '\n';
	gint n_col = 1, pos_line = 0, pos_column = 0, n_pad = 0;
	static gchar column[300];

	while ( line[ pos_line ] != end_line) 
	{
		if ( line[ pos_line ] == padding ) 
		{
			n_pad++;
		}
		else if ( line[ pos_line ] == col_sep ) 
		{
			n_col++;
			n_pad = 0;
			if ( n_col > col_num ) break;
		}
		else if ( n_col == col_num ) 
		{
			if ( n_pad == 2 ) break;
			if ( iscntrl( line[ pos_line])) break;
			column[ pos_column ] = line[ pos_line ];
			pos_column++;
			if ( pos_column > n_char ) break;
		}
		pos_line++;
	}
	column[ pos_column ] = '\0';

	return column;
}

/* Compare search_string with food description. If there is a match
 * return 1, else return 0 */
gint 
food_search_match( gchar *search_string, gchar *desc)
{
	gint i, j, len1, len2, count;

	if ( search_string[0] == '*') return 1;

	len1 = strlen( desc);
	len2 = strlen( search_string);

	for ( i=0; i<len1-len2+1; i++) 
	{
		if ( tolower( search_string[0]) == tolower( desc[i])) 
		{
			for( j=1, count=1; j<len2 && i+j<=len1; j++) 
			{
				if ( tolower( search_string[j]) == tolower( desc[i+j])) 
				{
					if ( ++count == len2) return 1;
				}
			}
		}
	}
	return 0;
}

/* Converts floating point number to a string with three numbers after
 * the decimal point. */
gchar * 
ftoa( gfloat number)
{
	static gchar s[30];
	gint i = 0, j;
	gint before_dec_pnt, after_dec_pnt;
	gchar c;

	before_dec_pnt = ( gint)number;

	/* Only interested in first three figures after the decimal point. */

	after_dec_pnt = ( gint)( ( number - ( gfloat)before_dec_pnt) * 1000.0);

	do 
	{
		s[i++] = after_dec_pnt % 10 + '0';
	} 
	while ( ( after_dec_pnt /= 10) > 0);

	s[i++] = '.';

	do 
	{
		s[i++] = before_dec_pnt % 10 + '0';
	} 
	while ( ( before_dec_pnt /= 10) > 0);

	s[i] = '\0';

	/* Now reverse the string. */

	for ( i = 0, j = strlen( s)-1; i < j; i++, j--) 
	{
		c = s[i];
		s[i] = s[j];
		s[j] = c;
	}

	return s;
}

/* converts an integer to a string. */
gchar *
itoa( int n)
{
	static gchar s[30];
	gchar c;
	int i = 0, j;

	do
	{
		s[i++] = n % 10 + '0';
	} 
	while ( ( n /= 10) > 0);

	s[i] = '\0';

	for ( i = 0, j = strlen( s)-1; i < j; i++, j--) 
	{
		c = s[i];
		s[i] = s[j];
		s[j] = c;
	}
	return s;
}

/* test that all chars in a string are digits. */
gint
all_digits( gchar *text)
{
	gint i, count=0, len;

	len = strlen( text);

	if ( len == 0) return 0;

	for( i=0; i<len; i++) if ( isdigit( text[i])) count++;

	if ( count == len) return 1;
	return 0;
}

/* returns 1 if the text is of zero length. */
gint
empty_text( gchar *text)
{
	gint len = strlen( text);

	if ( len == 0) return 1;

	return 0;
}


/* See if the directory exits. If not, try to create it. */
void
gnutr_dir_test( gchar *pathname)
{
	struct stat buf;
	gchar *dir;
	gint len, i;

	len = strlen( pathname);

	for ( i=1; i<=len; i++) 
	{
		if ( pathname[i] == '/' || pathname[i] == '\0') 
		{
			dir = g_strndup( pathname, i);

			/* get directory status, if it fails, try to create 
			 * the directory. */
			if ( stat( dir, &buf) != 0) 
			{
				int new_dir;
				new_dir = mkdir( dir, S_IRUSR | S_IWUSR | S_IXUSR);
				if ( new_dir == -1) 
				{
					g_warning( "Couldn't create directory: ");
					return;
				}
			}
			g_free( dir);
		}
	}
}

/* See if a file exists. */
gboolean
gnutr_file_test( gchar *fn)
{
	struct stat buf;
	
	if ( stat( fn, &buf) == 0)
			return TRUE;

	return FALSE;
}
