/*  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 <gnome.h>
#include <glade/glade.h>
#include <gnome-xml/tree.h>
#include <gnome-xml/parser.h>
#include <ctype.h>

#include "text_util.h"
#include "food.h"
#include "recipe.h"
#include "support.h"
#include "recipe_win.h"
#include "nutrgoal_io.h"
#include "nutr_goal_dlg.h"
#include "rdi.h"

static GladeXML *xml = NULL;
static void load_xml( void);
static void nutr_goal_load_data( Recipe_t *);
static gboolean get_changed_nutr_goal( void);

/* List of nutrients and widget names - IH 29/7/00 */

#define NUM_GOALS 80

struct t_nutr_goal {
	char *widget; /* name of Glade widget */
	int idx; /* index to nutrient array */
};

struct t_nutr_goal ng_data[NUM_GOALS] = 
{
	/* macro-nutrients */
	{"protein",0},{"fat",1},{"sat_fat",52},{"mono_fat",76},{"poly_fat",77},
	{"carb",2},{"chol",51},{"fiber",11},{"kj",9},{"kcal",4},
	/* micro-nutrients. */
	{"vita",22},{"vite",24},{"vitc",25},{"thia",26},
	{"ribo",27},{"nia",28},{"panto",29},{"vitb6",30},{"fol",31},
	{"vitb12",32},{"ca",12},{"fe",13},{"mg",14},{"p",15},
	{"k",16},{"na",17},{"zn",18},{"cu",19},{"mn",20},{"se",21},
	/* proteins */
	{"tryp",33},{"thre",34},{"isol",35},
	{"leuc",36},{"lysi",37},{"meth",38},{"cyst",39},{"phen",40},
	{"tyro",41},{"vali",42},{"argi",43},{"hist",44},{"alan",45},
	{"aspa",46},{"glut",47},{"glyc",48},{"prol",49},{"seri",50},
	/* fats */
	{"fat_4d0",53}, 
	{"fat_6d0",54},{"fat_8d0",55},{"fat_10d0",56},{"fat_12d0",57},
	{"fat_14d0",58},{"fat_16d0",59},{"fat_18d0",60},{"fat_20d0",61},
	{"fat_18d1",62},{"fat_18d2",63},{"fat_18d3",64},{"fat_20d4",65},
	{"fat_22d6",66},{"fat_22d0",67},{"fat_14d1",68},{"fat_16d1",69},
	{"fat_18d4",70},{"fat_20d1",71},{"fat_20d5",72},{"fat_22d1",73},
	{"fat_22d5",74},{"fat_15d0",78},{"fat_17d0",79},{"fat_24d0",80}, 
	/* miscelaneous */
	{"ash",3},{"alco",5},
	{"water", 6},{"phyto",75},{"theob",8},{"caff",7},{"sugar",10} 
};

/* load the glade xml if not already loaded. */
static void
load_xml()
{
	static gboolean loaded_xml = FALSE;

	/* load the glade interface. */
	if ( !loaded_xml)
	{
		xml = glade_xml_new( GNUTRITION_GLADEDIR "/nutr_goal_dlg.glade", NULL);
		loaded_xml = TRUE;

		if (  xml != NULL)
		{
			glade_xml_signal_autoconnect( xml);
		}
		else
		{
			g_log( "Gnutrition", G_LOG_LEVEL_ERROR,
					"cannot load: nutr_goal_dlg.glade\n");
			return;
		}
	}
}

/* Load values into dialogue  - IH 25/7/00 */
static void
nutr_goal_load_data( Recipe_t *recipe)

{
	GtkWidget *entry;
	gchar *text;
	gchar name[50];
	gint i;
  
	/* set the text entries. */
	for ( i=0; i<NUM_GOALS; i++)
	{
		strcpy( name, ng_data[i].widget);
		strcat( name, "_gdlg_entry");
		entry = glade_xml_get_widget( xml, name);
		text = ftoa( recipe->nutr->goal[ng_data[i].idx]);
		gtk_entry_set_text( GTK_ENTRY( entry), text);
	}
}

/* Display nutrient goal dialog. */
void
gnutr_show_nutr_goal_dlg()
{
	GtkWidget *widget;
	GtkNotebook *notebook;
	Recipe_t *recipe = gnutr_ret_recipe();
	static gboolean first_show = TRUE;

	if ( xml == NULL) load_xml();

	nutr_goal_load_data( recipe);

	/* first time the dialog is shown, show the "Calculate" page. */
	notebook = GTK_NOTEBOOK( glade_xml_get_widget( xml, "notebook_gdlg"));
    if ( first_show)
	{
		gtk_notebook_set_page( notebook, 5);
		first_show = FALSE;
	}

	/* display the dialog. */
	widget = glade_xml_get_widget( xml, "nutr_goal_dlg");
	gtk_widget_show( widget);
}

/* get the values from the nutrient goal dialog so that they can be saved
 * to file. FALSE if invalid data */
static gboolean
get_changed_nutr_goal() 
{
	GtkWidget *entry, *errorbox;
	Recipe_t *recipe = NULL;
	gchar name[50];
	gint i;
	gfloat num;
	gchar *endpoint, *text;

	recipe = gnutr_ret_recipe();

	for ( i=0; i<NUM_GOALS; i++)
	{
		strcpy( name, ng_data[i].widget);
		strcat( name, "_gdlg_entry");
		entry = glade_xml_get_widget( xml, name);
		text =  gtk_entry_get_text( GTK_ENTRY( entry));
		num = strtod( text, &endpoint);

		if (text == endpoint) /* an error occurred */
		{
			text = g_strdup_printf( "Invalid number: %s", text);
			errorbox = gnome_error_dialog( text);
			gtk_widget_show( errorbox);
			g_free( text);
			return( FALSE);
		} 
		recipe->nutr->goal[ng_data[i].idx] = num;
	}
	return( TRUE);
}

/* When The "OK" button is released in the nutrient goal dialog - save 
 * the nutrient goals and hide the dialog. */
void
on_ok_gdlg_button_released( GtkButton *button,
                            gpointer   user_data)
{
	Recipe_t *recipe = gnutr_ret_recipe();
	GtkWidget *widget = glade_xml_get_widget( xml, "nutr_goal_dlg");

	if ( get_changed_nutr_goal())
	{ /* only if valid - IH */
		gnutr_write_nutr_goal( recipe->nutr);
		gtk_widget_hide( widget);
	}
}

/* When the "Cancel" button is released in the nutrient goal dialog - hide 
 * the nutrient goal dialog. */
void
on_cancel_gdlg_button_released( GtkButton *button,
                                gpointer   user_data)
{
	GtkWidget *widget = glade_xml_get_widget( xml, "nutr_goal_dlg");
	gtk_widget_hide( widget);
}

/* When the "Save" button released in the nutrient goal dialog - save the 
 * nutrient goals to file. */
void
on_save_gdlg_button_released( GtkButton *button,
                               gpointer   user_data)
{
	Recipe_t *recipe = gnutr_ret_recipe();

	if ( get_changed_nutr_goal())
		gnutr_write_nutr_goal( recipe->nutr);
}

/* When "female" button toggled - IH 25/7/00 */
void
on_female_gdlg_radio_toggled( GtkWidget *radio, 
                              gpointer data)
{
	GtkWidget *preg, *lac, *neither;

	preg = glade_xml_get_widget( xml, "pregnant_gdlg_radio");
	lac = glade_xml_get_widget( xml, "lactating_gdlg_radio");
	neither = glade_xml_get_widget( xml, "neither_gdlg_radio");

	if ( GTK_TOGGLE_BUTTON( radio)->active)
	{
		gtk_widget_set_sensitive( preg, TRUE);
		gtk_widget_set_sensitive( lac, TRUE);
		gtk_widget_set_sensitive( neither, TRUE);
	}
	else
	{ /* "Male" is selected, so not valid */
		gtk_widget_set_sensitive( preg, FALSE);
		gtk_widget_set_sensitive( lac, FALSE);
		gtk_widget_set_sensitive( neither, FALSE);
		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( neither), TRUE);
	}
}

/* When "calculate" button is pressed - IH 25/7/00 */
void
on_calculate_gdlg_button_released( GtkButton *button,
                                   gpointer user_data)
{
	Recipe_t *recipe = NULL; 
	GtkWidget *entry;
	GtkWidget *option_menu;
	gfloat age, weight;
	gboolean female, lactating, pregnant;

	recipe = gnutr_ret_recipe();

	entry = glade_xml_get_widget( xml, "age_gdlg_entry");
	age = atof( gtk_entry_get_text( GTK_ENTRY( entry)));
	entry = glade_xml_get_widget( xml, "weight_gdlg_entry");
	weight = atof( gtk_entry_get_text( GTK_ENTRY( entry)));

	/* convert pounds into kilos if the "lbs." menu option is
	 * chosen. */
	option_menu = glade_xml_get_widget( xml, "weight_gdlg_menu");
	if ( GTK_BIN( option_menu)->child)
	{
		GtkWidget *child = GTK_BIN( option_menu)->child;
		gchar *option_menu_text;

		if ( GTK_IS_LABEL( child))
		{
			gtk_label_get( GTK_LABEL( child), &option_menu_text);
		}
		if ( strcmp( option_menu_text, "lbs.") == 0)
		{
			weight *= 0.4536;
		}
	}

	entry = glade_xml_get_widget( xml, "female_gdlg_radio");
	female = GTK_TOGGLE_BUTTON( entry)->active;
	if ( female)
	{
		entry = glade_xml_get_widget( xml, "pregnant_gdlg_radio");
		pregnant = GTK_TOGGLE_BUTTON( entry)->active;
		entry = glade_xml_get_widget( xml, "lactating_gdlg_radio");
		lactating = GTK_TOGGLE_BUTTON( entry)->active;
	}
	else
	{
		pregnant = FALSE;
		lactating = FALSE;
	}
	rdi_calc_rdi( recipe->nutr, age, weight, female, pregnant, lactating);

	nutr_goal_load_data( recipe);
}
