1 /* food.c */
2
3 /*
4 NUT nutrition software
5 Copyright (C) 1996-2014 by Jim Jozwiak.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "util.h"
23 #include "options.h"
24 #include "nutrient.h"
25 #include "abbrev.h"
26 #include "fdgrp.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30
31 struct food food_root, food_work, *new_food, recipe_root, *new_recipe, *FoodIndex[MAX_FOOD];
32
33 int DVMap[] =
34 {
35 DV_COUNT,ENERC_KCAL,
36 FAT,FASAT,FAMS,FAPU,OMEGA6,LA,AA,OMEGA3,ALA,EPA,DHA,CHOLE,CHOCDF,FIBTG,CHO_NONFIB,PROCNT,
37 VITA_IU,THIA,RIBF,NIA,PANTAC,VITB6A,FOL,VITB12,VITC,VITD,VITE,VITK1,
38 CA,CU,FE,MG,MN,P,K,SE,NA,ZN
39 };
40
41 int CarbAminoMap[] =
42 {
43 CARBAMINO_COUNT,CHOCDF,FIBTG,STARCH,SUGAR,FRUS,GALS,GLUS,LACS,MALS,SUCS,
44 PROCNT,ADPROT,ALA_G,ARG_G,ASP_G,CYS_G,GLU_G,GLY_G,HISTN_G,HYP,ILE_G,
45 LEU_G,LYS_G,MET_G,PHE_G,PRO_G,SER_G,THR_G,TRP_G,TYR_G,VAL_G
46 };
47
48 int MiscMap[] =
49 {
50 MISC_COUNT,ENERC_KJ,ASH,WATER,CAFFN,THEBRN,ALC,
51 FLD,BETN,CHOLN,FOLAC,FOLFD,FOLDFE,RETOL,VITA_RAE,
52 ERGCAL,CHOCAL,VITD_BOTH,
53 VITB12_ADDED,VITE_ADDED,
54 VITK1D,MK4,
55 TOCPHA,TOCPHB,TOCPHG,TOCPHD,TOCTRA,TOCTRB,TOCTRG,TOCTRD,CARTA,CARTB,CRYPX,LUT_ZEA,LYCPN,
56 CHOLE,PHYSTR,SITSTR,CAMD5,STID7
57 };
58
59 int SatMonoMap[] =
60 {
61 SATMONO_COUNT,FASAT,F4D0,F6D0,F8D0,F10D0,F12D0,F13D0,F14D0,F15D0,F16D0,
62 F17D0,F18D0,F20D0,F22D0,F24D0,
63 FAMS,F14D1,F15D1,F16D1,F16D1C,F17D1,
64 F18D1,F18D1C,F20D1,F22D1,F22D1C,F24D1C
65 };
66
67 int PolyTransMap[] =
68 {
69 POLYTRANS_COUNT,FAPU,F18D2,F18D2CN6,
70 F18D3,F18D3CN3,F18D3CN6,F18D4,F20D2CN6,F20D3,
71 F20D3N3,F20D3N6,
72 F20D4,F20D4N6,F20D5,F21D5,F22D4,F22D5,F22D6,
73 FATRN,FATRNM,F16D1T,F18D1T,F18D1TN7,F22D1T,
74 FATRNP,F18D2T,F18D2TT,F18D2I,F18D2CLA,F18D3I
75 };
76
77 int *ScreenMap[] =
78 {
79 DVMap,DVMap,CarbAminoMap,MiscMap,SatMonoMap,PolyTransMap
80 };
81
82 char *ScreenTitle[] =
83 {
84 "Daily Value Percentages","Daily Value Absolute Amounts",
85 "Carbohydrates and Amino Acids","Miscellaneous Nutrients",
86 "Saturated and Monounsaturated Fatty Acids","Polyunsaturated and Trans Fatty Acids"
87 };
88
89 int MaxFdGrp = FD_GRP_COUNT;
90
91 float DVBase[NUTRIENT_COUNT];
92
93 float DV[NUTRIENT_COUNT];
94
95 int DVnotOK;
96
97 float NoData;
98
99 int LookupNutrNo[NUTRIENT_COUNT - DERIVED];
100 int LookupNut[NUTRNO_ARRAYSIZE];
101
102 int FoodCount = 0;
103
initializations()104 void initializations()
105 {
106 int c;
107 NoData = atof("-0");
108 test_signsense(&NoData);
109 initialize_options();
110 for (c=0; c < NUTRIENT_COUNT; c++) DVBase[c] = 0;
111
112 DVBase[ENERC_KCAL] = 2000;
113 DVBase[PROCNT] = 50;
114 DVBase[FAT] = 65;
115 DVBase[CHOCDF] = 300;
116 DVBase[FIBTG] = 25;
117 DVBase[CHO_NONFIB] = DVBase[CHOCDF] - DVBase[FIBTG];
118 DVBase[CA] = 1000;
119 DVBase[P] = 1000;
120 DVBase[FE] = 18;
121 DVBase[NA] = 2400;
122 DVBase[K] = 3500;
123 DVBase[MG] = 400;
124 DVBase[ZN] = 15;
125 DVBase[CU] = 2;
126 DVBase[MN] = 2;
127 DVBase[SE] = 70;
128 DVBase[VITA_IU] = 5000;
129 DVBase[VITE] = 30;
130 DVBase[VITK1] = 80;
131 DVBase[THIA] = 1.5;
132 DVBase[RIBF] = 1.7;
133 DVBase[NIA] = 20;
134 DVBase[PANTAC] = 10;
135 DVBase[VITB6A] = 2;
136 DVBase[FOL] = 400;
137 DVBase[VITB12] = 6;
138 DVBase[VITC] = 60;
139 DVBase[FASAT] = 20;
140 DVBase[CHOLE] = 300;
141 DVBase[VITD] = 400;
142 DVBase[FAPU] = 8.9;
143 DVBase[AA] = 0.2;
144 DVBase[ALA] = 3.8;
145 DVBase[EPA] = 0.1;
146 DVBase[DHA] = 0.1;
147 DVBase[LA] = DVBase[FAPU] - DVBase[AA] - DVBase[ALA] - DVBase[EPA] - DVBase[DHA];
148 DVBase[OMEGA3] = DVBase[ALA] + DVBase[EPA] + DVBase[DHA];
149 DVBase[OMEGA6] = DVBase[LA] + DVBase[AA];
150 DVBase[FAMS] = 61.5 - DVBase[FASAT] - DVBase[FAPU];
151 for (c=0; c < NUTRNO_ARRAYSIZE; c++) LookupNut[c] = -1;
152 for (c=0; c < NUTRIENT_COUNT - DERIVED; c++) LookupNutrNo[c] = -1;
153 #include "lookup.h"
154 }
155
order_new_food()156 int order_new_food()
157 {
158 struct food *food_ptr = &food_root;
159 int foodnum = 0;
160 while (food_ptr->next != NULL && namestrcmp(new_food->name, food_ptr->next->name) >= 0)
161 {
162 food_ptr = food_ptr->next;
163 foodnum++;
164 }
165 new_food->next = food_ptr->next;
166 food_ptr->next = new_food;
167 return foodnum;
168 }
169
namestrcmp(char * name1,char * name2)170 int namestrcmp(char *name1, char *name2)
171 {
172 char namebuf1[61], namebuf2[61];
173 int count;
174 for (count = 0 ; count <= 60 ; count++)
175 {
176 if (name1[count] == ',') namebuf1[count] = '\a';
177 else namebuf1[count] = name1[count];
178 if (name2[count] == ',') namebuf2[count] = '\a';
179 else namebuf2[count] = name2[count];
180 }
181 return strcmp(namebuf1,namebuf2);
182 }
183
substring_finder(char * food_name,char * substr)184 int substring_finder(char *food_name, char *substr)
185 {
186 int i;
187 char *token;
188 char substring[61];
189 strcpy(substring,substr);
190 token = strtok(substring, ", ");
191 while (token != NULL)
192 {
193 if (strstr(food_name,token) != NULL)
194 {
195 token = strtok(NULL,", ");
196 continue;
197 }
198 for (i=0; i < Abbrev_Count; i++) if (strcmp(token,Abbreviations[i]) == 0) break;
199 if (i == Abbrev_Count) return 0;
200 if (strstr(food_name,Abbreviations[i % 2 == 0 ? i+1 : i-1]) == NULL) return 0;
201 token = strtok(NULL,", ");
202 }
203 return 1;
204 }
205
food_choice(char * screentitle,int usual)206 struct food *food_choice(char *screentitle, int usual)
207 {
208 struct food *food_ptr;
209 struct food *ptrlist[MAX_FOOD];
210 int count = 0, charcount, keysize, lines, junk;
211 char substring[61], key[61];
212 for ( ; ; )
213 {
214 key_decode(substring,key);
215 if (strcmp(substring,"") == 0)
216 {
217 header(screentitle);
218 spacer(0);
219 if (strcmp(screentitle,"NUT: Add Recipes") == 0) printf("\nType food name to add to recipe (or <enter> to quit): ");
220 else printf("\nType food name to select (or <enter> to quit): ");
221 get_string(substring,60);
222 key[0] = '\0';
223 key_clean();
224 }
225 if (substring[0] == '\0') return (struct food *) -1;
226 for (charcount = 0 ; charcount < 60 ; charcount++) substring[charcount] = toupper(substring[charcount]);
227 key_encode(substring,key);
228 if (strncmp(substring,"THEUSUAL",8) == 0 && usual) return (struct food *) -2;
229 if (strncmp(substring,"PCF ",4) == 0 && usual) return (struct food *) -3;
230 header(screentitle);
231 food_ptr = &food_root;
232 keysize = strlen(key); lines = 0; count = 0;
233 while ((food_ptr = food_ptr->next)) if (substring_finder(food_ptr->name,substring) && strncmp(key,food_ptr->name,keysize) == 0) ptrlist[++count] = food_ptr;
234 while (count == 0)
235 {
236 key_clean();
237 spacer(-1);
238 printf("No food named \"%s\". Try another (or <enter> to quit): ",substring);
239 get_string(substring,60);
240 if (substring[0] == '\0') return (struct food *) 0;
241 for (charcount = 0 ; charcount < 60 ; charcount++) substring[charcount] = toupper(substring[charcount]);
242 key_encode(substring,key);
243 if (strncmp(substring,"THEUSUAL",8) == 0 && usual) return (struct food *) -2;
244 if (strncmp(substring,"PCF ",4) == 0 && usual) return (struct food *) -3;
245 header(screentitle);
246 food_ptr = &food_root;
247 keysize = strlen(key); lines = 0; count = 0;
248 while ((food_ptr = food_ptr->next)) if (substring_finder(food_ptr->name,substring) && strncmp(key,food_ptr->name,keysize) == 0) ptrlist[++count] = food_ptr;
249 }
250 if (count == 1) return ptrlist[1];
251 if (count < 21)
252 {
253 for (lines = 1 ; lines <= count ; lines++) printf("%2d. %s\n",lines,ptrlist[lines]->name);
254 spacer(lines - 2);
255 printf("Type number of food category (\"b\" to go back, <enter> to quit): ");
256 get_string(key,60);
257 junk = 0;
258 if (strcmp(key,"b") == 0 || strcmp(key,"B") == 0) junk = -38;
259 if (junk == -38)
260 {
261 key_decode(substring,key);
262 continue;
263 }
264 junk = atoi(key);
265 if (junk > 0 && junk <= count)
266 {
267 key_encode(substring,ptrlist[junk]->name);
268 return ptrlist[junk];
269 }
270 else return (struct food *) 0;
271 }
272 if (count > 20) food_subcat(substring, key, ptrlist, count);
273 }
274 }
275
food_subcat(char * substring,char * key,struct food ** ptrlist,int count)276 void food_subcat(char *substring, char *key, struct food **ptrlist, int count)
277 {
278 char food_screen[2000];
279 char *fsptr[500], *thisfsptr, *bufptr, buffer[61], format[11], format100[11], tokenhead[61], junkstring[120];
280 char *col[10], colformat1[110], colformat2[110];
281 int i, l, s, subcount = 0, charcount, tokencount, nlength, tokenlength, tokenunique, headlength = 0, linecount, savelinecount = 0, tokenmax = 0, colcount;
282 for (linecount = 1 ; linecount <= 20 ; linecount++) fsptr[linecount] = food_screen + (61 * linecount);
283 for (linecount = 1 ; linecount <= count ; linecount++)
284 {
285 tokencount = 0;
286 nlength = strlen(ptrlist[linecount]->name);
287 for (charcount = 0 ; charcount <= nlength ; charcount++) if (ptrlist[linecount]->name[charcount] == ',') tokencount++;
288 if (tokencount > tokenmax) tokenmax = tokencount;
289 }
290 while (subcount < count && tokenmax > -1)
291 {
292 tokenmax--;
293 subcount = 0;
294 for (linecount = 1; subcount < count && linecount <= 20 ; linecount++)
295 {
296 subcount++;
297 nlength = strlen(ptrlist[subcount]->name);
298 thisfsptr = fsptr[linecount];
299 tokencount = 0;
300 for (charcount = 0 ; charcount <= nlength ; charcount++)
301 {
302 if (ptrlist[subcount]->name[charcount] == ',') tokencount++;
303 if (tokencount == tokenmax)
304 {
305 thisfsptr[charcount] = '\0';
306 break;
307 }
308 thisfsptr[charcount] = ptrlist[subcount]->name[charcount];
309 if (ptrlist[subcount]->name[charcount] == '\0') break;
310 }
311 if (linecount > 1 && 0 == strcmp(fsptr[linecount],fsptr[linecount-1])) linecount--;
312 }
313 savelinecount = --linecount;
314 }
315 if (savelinecount > 1)
316 {
317 for (linecount = 1; linecount <= savelinecount ; linecount++) printf("%2d. %s\n",linecount,fsptr[linecount]);
318 spacer(savelinecount-1);
319 printf("Type number of food category (\"b\" to go back, <enter> to quit): ");
320 get_string(junkstring,20);
321 if (strcmp(junkstring,"b") == 0 || strcmp(junkstring,"B") == 0)
322 {
323 key_take();
324 return;
325 }
326 linecount = atoi(junkstring);
327 if (linecount > 0 && linecount <= savelinecount)
328 {
329 if (headlength < 1) strcpy(key,fsptr[linecount]);
330 if (headlength > 0)
331 {
332 strcpy(key,tokenhead);
333 strcat(key,fsptr[linecount]);
334 }
335 for (subcount = 1 ; subcount <= count ; subcount++) if (strcmp(key,ptrlist[subcount]->name) == 0) break;
336 if (--subcount == count) strcat(key,",");
337 }
338 else
339 {
340 key[0] = '\0';
341 substring[0] = '\0';
342 }
343 key_encode(substring,key);
344 }
345 else
346 {
347 tokenhead[0] = '\0';
348 for (tokenmax = 1 ; ; tokenmax++)
349 {
350 buffer[0] = '\0';
351 tokenunique = 0;
352 tokenlength = 0;
353 for (subcount = 1 ; subcount <= count ; subcount++)
354 {
355 bufptr = ptrlist[subcount]->name;
356 nlength = 0;
357 for (tokencount = 1 ; tokencount <= tokenmax ; tokencount++)
358 {
359 bufptr += nlength;
360 bufptr += strspn(bufptr,",");
361 nlength = strcspn(bufptr,",");
362 }
363 if (nlength > tokenlength)
364 {
365 tokenlength = nlength;
366 tokenunique++;
367 strncpy(buffer,bufptr,nlength);
368 buffer[nlength] = '\0';
369 }
370 else if (nlength < tokenlength)
371 {
372 tokenunique++;
373 strncpy(buffer,bufptr,nlength);
374 buffer[nlength] = '\0';
375 }
376 else if (strncmp(buffer,bufptr,nlength) != 0)
377 {
378 tokenunique++;
379 strncpy(buffer,bufptr,nlength);
380 buffer[nlength] = '\0';
381 }
382 }
383 if (tokenunique == 1)
384 {
385 strcat(buffer,",");
386 strcat(tokenhead,buffer);
387 }
388 if (tokenunique != 1) break;
389 }
390 if (tokenhead[0] == '\0') savelinecount = 20;
391 else savelinecount = 19;
392 headlength = strlen(tokenhead);
393 #ifndef DOS
394 while ( savelinecount * (81 / (tokenlength + 5 ) ) < tokenunique )
395 #else
396 while ( savelinecount * (80 / (tokenlength + 5 ) ) < tokenunique )
397 #endif
398 {
399 buffer[0] = '\0';
400 tokenunique = 0 ;
401 tokenlength--;
402 for (subcount = 1 ; subcount <= count ; subcount++)
403 {
404 bufptr = ptrlist[subcount]->name + headlength;
405 nlength = strcspn(bufptr,",");
406 while (*(bufptr + nlength - 1) == ' ') nlength--;
407 if (nlength > tokenlength) nlength = tokenlength;
408 if (strncmp(buffer,bufptr,nlength) != 0)
409 {
410 tokenunique++;
411 strncpy(buffer,bufptr,nlength);
412 buffer[nlength] = '\0';
413 }
414 }
415 }
416 for (linecount = 0 ; linecount <= (tokenunique+2) ; linecount++) fsptr[linecount] = food_screen + ((tokenlength+1) * linecount);
417 food_screen[0] = '\0';
418 linecount = 0;
419 for (subcount = 1 ; subcount <= count ; subcount++)
420 {
421 bufptr = ptrlist[subcount]->name + headlength;
422 nlength = (strcspn(bufptr,","));
423 if (nlength > tokenlength) nlength = tokenlength;
424 while (*(bufptr + nlength - 1) == ' ') nlength--;
425 strncpy(fsptr[linecount + 1],bufptr,nlength);
426 thisfsptr = fsptr[linecount + 1];
427 thisfsptr[nlength] = '\0';
428 if (strncmp(fsptr[linecount],fsptr[linecount + 1],nlength) != 0) linecount++;
429 }
430 sprintf(format,"%%2d. %%-%ds",tokenlength);
431 sprintf(format100,"%%3d. %%-%ds",tokenlength);
432 strcpy(colformat1,format);
433 strcpy(colformat2,format);
434 colcount = (linecount % savelinecount == 0 ? 0 : 1) + (linecount / savelinecount);
435 if (colcount > 7)
436 {
437 spacer(-1);
438 printf("Too many foods meet criterion. Press <enter> to continue...");
439 i = get_int();
440 key_take();
441 return;
442 }
443 if (colcount < 8)
444 {
445 for (i = 2 ; i <= colcount ; i++)
446 {
447 if (i != colcount) strcat(colformat1," ");
448 strcat(colformat2," ");
449 if ((i * savelinecount) < 100 || tokenunique < 100)
450 {
451 if (i != colcount) strcat(colformat1,format);
452 strcat(colformat2,format);
453 }
454 else
455 {
456 if (i != colcount) strcat(colformat1,format100);
457 strcat(colformat2,format100);
458 }
459 }
460 strcat(colformat1,"\n");
461 strcat(colformat2,"\n");
462 col[colcount - 1] = colformat1;
463 col[colcount] = colformat2;
464 if (headlength > 0 ) printf("%-s\n",tokenhead);
465 if ( linecount < savelinecount ) savelinecount = linecount;
466 l = linecount ; s = savelinecount;
467 for (i = 1 ; i <= savelinecount ; i++)
468 {
469 if (i+(1*s)>l) printf(col[1],i,fsptr[i]);
470 else if (i+(2*s)>l) printf(col[2],i,fsptr[i],i+s,fsptr[i+s]);
471 else if (i+(3*s)>l) printf(col[3],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)]);
472 else if (i+(4*s)>l) printf(col[4],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)]);
473 else if (i+(5*s)>l) printf(col[5],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)],i+(4*s),fsptr[i+(4*s)]);
474 else if (i+(6*s)>l) printf(col[6],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)],i+(4*s),fsptr[i+(4*s)],i+(5*s),fsptr[i+(5*s)]);
475 else if (i+(7*s)>l) printf(col[7],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)],i+(4*s),fsptr[i+(4*s)],i+(5*s),fsptr[i+(5*s)],i+(6*s),fsptr[i+(6*s)]);
476 else if (i+(8*s)>l) printf(col[8],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)],i+(4*s),fsptr[i+(4*s)],i+(5*s),fsptr[i+(5*s)],i+(6*s),fsptr[i+(6*s)],i+(7*s),fsptr[i+(7*s)]);
477 else if (i+(9*s)>l) printf(col[9],i,fsptr[i],i+s,fsptr[i+s],i+(2*s),fsptr[i+(2*s)],i+(3*s),fsptr[i+(3*s)],i+(4*s),fsptr[i+(4*s)],i+(5*s),fsptr[i+(5*s)],i+(6*s),fsptr[i+(6*s)],i+(7*s),fsptr[i+(7*s)],i+(8*s),fsptr[i+(8*s)]);
478 }
479 spacer(savelinecount < 19 ? savelinecount : 19);
480 printf("Type number of food category (\"b\" to go back, <enter> to quit): ");
481 get_string(junkstring,20);
482 if (strcmp(junkstring,"b") == 0 || strcmp(junkstring,"B") == 0)
483 {
484 key_take();
485 return;
486 }
487 i = atoi(junkstring);
488 if (i > 0 && i <= linecount)
489 {
490 if (headlength > 0)
491 {
492 strcpy(key,tokenhead);
493 strcat(key,fsptr[i]);
494 }
495 else strcpy(key,fsptr[i]);
496 }
497 else
498 {
499 key[0] = '\0';
500 substring[0] = '\0';
501 }
502 key_encode(substring,key);
503 }
504 }
505 }
506
food_show(struct food * food_ptr,float * ratio)507 void food_show(struct food *food_ptr, float *ratio)
508 {
509 char servingstring[62];
510 int count;
511 printf("%-60s Grams %8.2f\n",food_ptr->name,food_ptr->grams * *ratio);
512 printf("Serving: %-50s Ounces %7.2f\n",format_serving(servingstring,ratio,food_ptr),*ratio * food_ptr->grams / GRAMS_IN_OUNCE);
513 printf(" %-50s Water %6.2f%%\n"," ",food_ptr->nutrient[WATER] > 0 ? food_ptr->nutrient[WATER] : 0.0);
514 if ( ! options.custom && options.screen == 0 ) printf("Percentages of \"Daily Values\" in this serving: Refuse %3d%%\n\n",food_ptr->refuse);
515 if ( options.custom && options.screen == 0 ) printf("Percentages of customized DV in this serving: Refuse %3d%%\n\n",food_ptr->refuse);
516 if ( options.screen > 0 ) printf("Nutrients in this serving: Refuse %3d%%\n\n",food_ptr->refuse);
517 for (count = 0; count < NUTRIENT_COUNT; count++) food_work.nutrient[count] = *ratio * food_ptr->nutrient[count] * food_ptr->grams / 100;
518 food_display(stdout);
519 spacer(20);
520 }
521
food_number(int i)522 struct food *food_number(int i)
523 {
524 return FoodIndex[i];
525 }
526
find_ndbno(int ndbno)527 int find_ndbno(int ndbno)
528 {
529 struct food *food_ptr = &food_root;
530 while (food_ptr->next != NULL)
531 {
532 food_ptr = food_ptr->next;
533 if (food_ptr->ndb_no == ndbno) return food_ptr->food_no;
534 }
535 return -1;
536 }
537
find_ndbno_ptr(int ndbno)538 struct food *find_ndbno_ptr(int ndbno)
539 {
540 struct food *food_ptr = &food_root;
541 while (food_ptr->next != NULL)
542 {
543 food_ptr = food_ptr->next;
544 if (food_ptr->ndb_no == ndbno) return food_ptr;
545 }
546 return NULL;
547 }
548
make_food_index()549 void make_food_index()
550 {
551 struct food *food_ptr = &food_root;
552 FoodCount = 0;
553 while (food_ptr->next != NULL)
554 {
555 food_ptr = food_ptr->next;
556 food_ptr->food_no = FoodCount;
557 FoodIndex[FoodCount++] = food_ptr;
558 }
559 }
560
modify_food_index(int foodnum,struct food * food_ptr)561 int modify_food_index(int foodnum, struct food *food_ptr)
562 {
563 int count;
564 for (count = FoodCount; count > foodnum; count--) FoodIndex[count] = FoodIndex[count-1];
565 FoodIndex[foodnum] = food_ptr;
566 FoodCount++;
567 food_ptr = &food_root;
568 for (count = 0; count < FoodCount; count++)
569 {
570 food_ptr = food_ptr->next;
571 food_ptr->food_no = count;
572 }
573 return foodnum;
574 }
575
clear_work()576 void clear_work()
577 {
578 int count;
579 for (count = 0; count < NUTRIENT_COUNT; count++) food_work.nutrient[count] = NoData;
580 food_work.grams = 0;
581 food_work.refuse = 0;
582 }
583
food_display(FILE * fp)584 void food_display(FILE *fp)
585 {
586 int i, n6;
587 float pctfat = 0, pctcarb = 0, pctprot = 0;
588 float p3, p6, h3, h6, o;
589 char protcarbfat[30];
590 if (food_work.nutrient[ENERC_KCAL] > 0.05)
591 {
592 pctcarb = 100 * food_work.nutrient[CHO_KCAL] / food_work.nutrient[ENERC_KCAL];
593 pctprot = 100 * food_work.nutrient[PROT_KCAL] / food_work.nutrient[ENERC_KCAL];
594 pctfat = 100 * food_work.nutrient[FAT_KCAL] / food_work.nutrient[ENERC_KCAL];
595 if (test_for_negative_zero(&pctcarb)) pctcarb = 0;
596 if (test_for_negative_zero(&pctprot)) pctprot = 0;
597 if (test_for_negative_zero(&pctfat)) pctfat = 0;
598 }
599 else
600 {
601 pctcarb = 0; pctprot = 0; pctfat = 0;
602 }
603 sprintf(protcarbfat,"%1.0f/%1.0f/%1.0f",pctprot,pctcarb,pctfat);
604 switch (options.screen)
605 {
606 case 1 :
607 food_display_line(fp,ScreenMap[options.screen][1],0,0,0,0);
608 food_display_line(fp,ScreenMap[options.screen][14],0,0,0,0);
609 food_display_line(fp,ScreenMap[options.screen][17],0,1,0,0);
610 fprintf(fp,"Prot/Carb/Fat %8s ",protcarbfat);
611 food_display_line(fp,ScreenMap[options.screen][15],0,0,0,0);
612 food_display_line(fp,ScreenMap[options.screen][16],0,1,0,0);
613 fprintf(fp,"\n");
614 food_display_line(fp,ScreenMap[options.screen][2],0,0,0,0);
615 food_display_line(fp,ScreenMap[options.screen][18],0,0,0,0);
616 food_display_line(fp,ScreenMap[options.screen][30],0,1,0,0);
617 for (i = 3; i < 6 ; i++)
618 {
619 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,1);
620 food_display_line(fp,ScreenMap[options.screen][i+16],0,0,0,0);
621 food_display_line(fp,ScreenMap[options.screen][i+28],0,1,0,0);
622 }
623 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,2);
624 food_display_line(fp,ScreenMap[options.screen][i+16],0,0,0,0);
625 food_display_line(fp,ScreenMap[options.screen][i+28],0,1,0,0);
626 for (i = 7; i < 9 ; i++)
627 {
628 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,4);
629 food_display_line(fp,ScreenMap[options.screen][i+16],0,0,0,0);
630 food_display_line(fp,ScreenMap[options.screen][i+28],0,1,0,0);
631 }
632 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,2);
633 food_display_line(fp,ScreenMap[options.screen][i+16],0,0,0,0);
634 food_display_line(fp,ScreenMap[options.screen][i+28],0,1,0,0);
635 for (i = 10; i < 12 ; i++)
636 {
637 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,4);
638 food_display_line(fp,ScreenMap[options.screen][i+16],0,0,0,0);
639 food_display_line(fp,ScreenMap[options.screen][i+28],0,1,0,0);
640 }
641 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,4);
642 food_display_line(fp,ScreenMap[options.screen][i+16],0,1,0,0);
643 food_display_line(fp,ScreenMap[options.screen][13],0,0,0,0);
644 food_display_line(fp,ScreenMap[options.screen][13+16],0,0,0,0);
645 p3 = 900 * food_work.nutrient[SHORT3] / food_work.nutrient[ENERC_KCAL];
646 p6 = 900 * food_work.nutrient[SHORT6] / food_work.nutrient[ENERC_KCAL];
647 h3 = 900 * food_work.nutrient[LONG3] / food_work.nutrient[ENERC_KCAL];
648 h6 = 900 * food_work.nutrient[LONG6] / food_work.nutrient[ENERC_KCAL];
649 o = 900 * (food_work.nutrient[FASAT] + food_work.nutrient[FAMS] + food_work.nutrient[FAPU] - food_work.nutrient[SHORT6] - food_work.nutrient[LONG6] - food_work.nutrient[SHORT3] - food_work.nutrient[LONG3]) / food_work.nutrient[ENERC_KCAL];
650 n6 = (int) n6hufa(p3,p6,h3,h6,o,food_work.nutrient[ENERC_KCAL]);
651 fprintf(fp,"Omega-6/3 Balance %2d/%1d\n",n6 == 0 ? 0 : n6,n6 == 0 ? 0 : 100-n6);
652 break;
653 case 2 :
654 fprintf(fp,"%-27s","Carbohydrates");
655 fprintf(fp,"%-27s\n\n","Amino Acids");
656 for (i = 1; i < 5 ; i++)
657 {
658 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,0);
659 food_display_line(fp,ScreenMap[options.screen][i+10],0,0,0,0);
660 food_display_line(fp,ScreenMap[options.screen][i+21],0,1,0,0);
661 }
662 for (i = 5; i < 11 ; i++)
663 {
664 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,1);
665 food_display_line(fp,ScreenMap[options.screen][i+10],0,0,0,0);
666 food_display_line(fp,ScreenMap[options.screen][i+21],0,1,0,0);
667 }
668 fprintf(fp,"%-27s"," ");
669 food_display_line(fp,ScreenMap[options.screen][i+10],0,1,0,0);
670 fprintf(fp,"\n\n");
671 break;
672 case 3 :
673 fprintf(fp,"Miscellaneous Nutrients\n\n");
674 for (i = 1; i < 14 ; i++)
675 {
676 food_display_line(fp,ScreenMap[options.screen][i],0,0,0,0);
677 food_display_line(fp,ScreenMap[options.screen][i+13],0,0,0,0);
678 food_display_line(fp,ScreenMap[options.screen][i+26],0,1,0,0);
679 }
680 break;
681 case 4 :
682 food_display_line(fp,ScreenMap[options.screen][1],0,0,1,0);
683 fprintf(fp,"Saturated and Monounsaturated Fatty Acids\n");
684 food_display_line(fp,ScreenMap[options.screen][2],0,1,1,0);
685 for (i = 3; i < 15 ; i++)
686 {
687 food_display_line(fp,ScreenMap[options.screen][i],0,0,1,0);
688 food_display_line(fp,ScreenMap[options.screen][i+13],0,1,1,0);
689 }
690 food_display_line(fp,ScreenMap[options.screen][i],0,1,1,0);
691 break;
692 case 5 :
693 fprintf(fp,"%-27s","Polyunsaturated and Trans Fatty Acids\n\n");
694 for (i = 1; i < 10 ; i++)
695 {
696 food_display_line(fp,ScreenMap[options.screen][i],0,0,1,0);
697 food_display_line(fp,ScreenMap[options.screen][i+9],0,0,1,0);
698 food_display_line(fp,ScreenMap[options.screen][i+18],0,1,1,0);
699 }
700 for (i = 10; i < 13 ; i++)
701 {
702 fprintf(fp,"%-54s"," ");
703 food_display_line(fp,ScreenMap[options.screen][i+18],0,1,1,0);
704 }
705 fprintf(fp,"\n");
706 break;
707 default :
708 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][1]])) fprintf(fp,"Calories(%4.0f) %5.0f%% ",DV[ScreenMap[options.screen][1]],food_work.nutrient[ScreenMap[options.screen][1]]/DV[ScreenMap[options.screen][1]]*100);
709 else fprintf(fp,"Calories(%4.0f) %5s ",DV[ScreenMap[options.screen][1]],"(nd)");
710 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][14]])) fprintf(fp,"%-14s %5.0f%% ",Nutrient[ScreenMap[options.screen][14]],food_work.nutrient[ScreenMap[options.screen][14]]/DV[ScreenMap[options.screen][14]] *100);
711 else fprintf(fp,"%-14s %5s ",Nutrient[ScreenMap[options.screen][14]],"(nd)");
712 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][17]])) fprintf(fp,"%-14s %5.0f%%\n",Nutrient[ScreenMap[options.screen][17]],food_work.nutrient[ScreenMap[options.screen][17]]/DV[ScreenMap[options.screen][17]] *100);
713 else fprintf(fp,"%-14s %5s\n",Nutrient[ScreenMap[options.screen][17]],"(nd)");
714 fprintf(fp,"Prot/Carb/Fat %8s ",protcarbfat);
715 food_display_line(fp,ScreenMap[options.screen][15],1,0,0,0);
716 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][16]])) fprintf(fp,"%-15s %5.0f%-1s\n",Nutrient[ScreenMap[options.screen][16]],food_work.nutrient[ScreenMap[options.screen][16]],Unit[ScreenMap[options.screen][16]]);
717 else fprintf(fp,"%-15s %5s\n",Nutrient[ScreenMap[options.screen][16]],"(nd)");
718 fprintf(fp,"\n");
719 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][2]])) fprintf(fp,"%-14s %5.0f%% ",Nutrient[ScreenMap[options.screen][2]],food_work.nutrient[ScreenMap[options.screen][2]]/DV[ScreenMap[options.screen][2]] *100);
720 else fprintf(fp,"%-14s %5s ",Nutrient[ScreenMap[options.screen][2]],"(nd)");
721 food_display_line(fp,ScreenMap[options.screen][18],1,0,0,0);
722 food_display_line(fp,ScreenMap[options.screen][30],1,1,0,0);
723 food_display_line(fp,ScreenMap[options.screen][3],1,0,0,1);
724 food_display_line(fp,ScreenMap[options.screen][19],1,0,0,0);
725 food_display_line(fp,ScreenMap[options.screen][31],1,1,0,0);
726 if (! test_for_negative_zero(&food_work.nutrient[ScreenMap[options.screen][4]])) fprintf(fp," %-13s %5.0f%% ",Nutrient[ScreenMap[options.screen][4]],food_work.nutrient[ScreenMap[options.screen][4]]/DV[FAMS]*100);
727 else fprintf(fp," %-13s %5s ",Nutrient[ScreenMap[options.screen][4]],"(nd)");
728 food_display_line(fp,ScreenMap[options.screen][20],1,0,0,0);
729 food_display_line(fp,ScreenMap[options.screen][32],1,1,0,0);
730 food_display_line(fp,ScreenMap[options.screen][5],1,0,0,1);
731 food_display_line(fp,ScreenMap[options.screen][21],1,0,0,0);
732 food_display_line(fp,ScreenMap[options.screen][33],1,1,0,0);
733 food_display_line(fp,ScreenMap[options.screen][6],1,0,0,2);
734 food_display_line(fp,ScreenMap[options.screen][22],1,0,0,0);
735 food_display_line(fp,ScreenMap[options.screen][34],1,1,0,0);
736 for (i = 7; i < 9 ; i++)
737 {
738 food_display_line(fp,ScreenMap[options.screen][i],1,0,0,4);
739 food_display_line(fp,ScreenMap[options.screen][i+16],1,0,0,0);
740 food_display_line(fp,ScreenMap[options.screen][i+28],1,1,0,0);
741 }
742 food_display_line(fp,ScreenMap[options.screen][i],1,0,0,2);
743 food_display_line(fp,ScreenMap[options.screen][i+16],1,0,0,0);
744 food_display_line(fp,ScreenMap[options.screen][i+28],1,1,0,0);
745 for (i = 10; i < 12 ; i++)
746 {
747 food_display_line(fp,ScreenMap[options.screen][i],1,0,0,4);
748 food_display_line(fp,ScreenMap[options.screen][i+16],1,0,0,0);
749 food_display_line(fp,ScreenMap[options.screen][i+28],1,1,0,0);
750 }
751 food_display_line(fp,ScreenMap[options.screen][i],1,0,0,4);
752 food_display_line(fp,ScreenMap[options.screen][i+16],1,1,0,0);
753 food_display_line(fp,ScreenMap[options.screen][13],1,0,0,0);
754 food_display_line(fp,ScreenMap[options.screen][13+16],1,0,0,0);
755 p3 = 900 * food_work.nutrient[SHORT3] / food_work.nutrient[ENERC_KCAL];
756 p6 = 900 * food_work.nutrient[SHORT6] / food_work.nutrient[ENERC_KCAL];
757 h3 = 900 * food_work.nutrient[LONG3] / food_work.nutrient[ENERC_KCAL];
758 h6 = 900 * food_work.nutrient[LONG6] / food_work.nutrient[ENERC_KCAL];
759 o = 900 * (food_work.nutrient[FASAT] + food_work.nutrient[FAMS] + food_work.nutrient[FAPU] - food_work.nutrient[SHORT6] - food_work.nutrient[LONG6] - food_work.nutrient[SHORT3] - food_work.nutrient[LONG3]) / food_work.nutrient[ENERC_KCAL];
760 n6 = (int) n6hufa(p3,p6,h3,h6,o,food_work.nutrient[ENERC_KCAL]);
761 fprintf(fp,"Omega-6/3 Balance %2d/%1d\n",n6 == 0 ? 0 : n6,n6 == 0 ? 0 : 100-n6);
762 break;
763 }
764 }
765
food_display_line(FILE * fp,int nut,int dv,int eol,int precision,int indent)766 void food_display_line(FILE *fp, int nut, int dv, int eol, int precision, int indent)
767 {
768 int flags;
769 flags = 100 * dv + 10 * eol + precision;
770 switch (indent)
771 {
772 case 1 : fprintf(fp," %-13s",Nutrient[nut]);
773 break;
774 case 2 : fprintf(fp," %-12s",Nutrient[nut]);
775 break;
776 case 4 : fprintf(fp," %-10s",Nutrient[nut]);
777 break;
778 default : fprintf(fp,"%-14s",Nutrient[nut]);
779 break;
780 }
781
782 switch (flags)
783 {
784 case 0 :
785 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.1f %-3s ",food_work.nutrient[nut],Unit[nut]);
786 else fprintf(fp,"%9s%-3s ","(nd)"," ");
787 break;
788 case 1 :
789 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.2f %-3s ",food_work.nutrient[nut],Unit[nut]);
790 else fprintf(fp,"%9s%-3s ","(nd)"," ");
791 break;
792 case 10 :
793 #ifndef DOS
794 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.1f %-3s\n",food_work.nutrient[nut],Unit[nut]);
795 else fprintf(fp,"%9s%-3s\n","(nd)"," ");
796 #else
797 if (nut != VITE && nut != VITK1 && nut != ILE_G && nut != TOCPHG)
798 {
799 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%7.1f %-3s\n",food_work.nutrient[nut],Unit[nut]);
800 else fprintf(fp,"%8s%-3s\n","(nd)"," ");
801 }
802 else
803 {
804 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.1f %-3s\n",food_work.nutrient[nut],Unit[nut]);
805 else fprintf(fp,"%9s%-3s\n","(nd)"," ");
806 }
807 #endif
808 break;
809 case 11 :
810 #ifndef DOS
811 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.2f %-3s\n",food_work.nutrient[nut],Unit[nut]);
812 else fprintf(fp,"%9s%-3s\n","(nd)"," ");
813 #else
814 if (nut != F4D0 && nut != F18D2CN6 && nut != F20D2CN6 && nut != F20D3 && nut != F20D4 && nut != F20D5 && nut != F22D4 && nut != F24D0)
815 {
816 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%7.2f %-3s\n",food_work.nutrient[nut],Unit[nut]);
817 else fprintf(fp,"%8s%-3s\n","(nd)"," ");
818 }
819 else
820 {
821 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp,"%8.2f %-3s\n",food_work.nutrient[nut],Unit[nut]);
822 else fprintf(fp,"%9s%-3s\n","(nd)"," ");
823 }
824 #endif
825 break;
826 case 110 :
827 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp," %5.0f%%\n",food_work.nutrient[nut]/DV[nut]*100);
828 else fprintf(fp," %4s\n","(nd)");
829 break;
830 default :
831 if (! test_for_negative_zero(&food_work.nutrient[nut])) fprintf(fp," %5.0f%% ",food_work.nutrient[nut]/DV[nut]*100);
832 else fprintf(fp," %5s ","(nd)");
833 break;
834 }
835 }
836
order_new_recipe()837 void order_new_recipe()
838 {
839 struct food *food_ptr = &recipe_root;
840 while (food_ptr->next != NULL) food_ptr = food_ptr->next;
841 new_recipe->next = NULL;
842 food_ptr->next = new_recipe;
843 }
844
modify_recipe_food(int num,char * qty)845 void modify_recipe_food(int num, char *qty)
846 {
847 struct food *m, *recipe_ptr = &recipe_root;
848 int count = 0;
849 float newqty;
850 while (recipe_ptr->next != NULL)
851 {
852 count++;
853 if (count == num)
854 {
855 newqty = evaluate_qty(food_number(recipe_ptr->next->food_no),qty);
856 if (newqty == 0)
857 {
858 m = recipe_ptr->next;
859 recipe_ptr->next = recipe_ptr->next->next;
860 free(m);
861 }
862 else recipe_ptr->next->grams = newqty;
863 return;
864 }
865 recipe_ptr = recipe_ptr->next;
866 }
867 }
868
modify_label_food(int num,char * command)869 void modify_label_food(int num, char *command)
870 {
871 struct food *m = NULL, *pm = NULL, *am = NULL, *po = NULL, *ao = NULL, *recipe_ptr = &recipe_root;
872 int count = 0;
873 int action;
874 action = evaluate_action(command);
875 if (num == action) return;
876 while (recipe_ptr->next != NULL)
877 {
878 count++;
879 if (count == action && action > 0 && num > action)
880 {
881 ao = recipe_ptr;
882 po = recipe_ptr->next;
883 }
884 if (count == action && action > 0 && num < action)
885 {
886 ao = recipe_ptr->next;
887 if (recipe_ptr->next != NULL) po = recipe_ptr->next->next;
888 else po = NULL;
889 }
890 if (count == num)
891 {
892 m = recipe_ptr->next;
893 pm = recipe_ptr->next->next;
894 am = recipe_ptr;
895 if (action == 0)
896 {
897 recipe_ptr->next = recipe_ptr->next->next;
898 free(m);
899 return;
900 }
901 if (action < 0)
902 {
903 if (action == -1 && m->refuse >= 0) m->refuse++;
904 if (action == -1 && m->refuse < 0) m->refuse = 1;
905 if (action == -2 && m->refuse <= 0) m->refuse--;
906 if (action == -2 && m->refuse > 0) m->refuse = -1;
907 if (action == -3 && m->refuse < 0) m->refuse++;
908 if (action == -3 && m->refuse > 0) m->refuse--;
909 return;
910 }
911 }
912 recipe_ptr = recipe_ptr->next;
913 }
914 if (num > count || action > count) return;
915 am->next = pm;
916 ao->next = m;
917 m->next = po;
918 }
919
compute_derived_fields(struct food * food_ptr)920 void compute_derived_fields(struct food *food_ptr)
921 {
922 float ratio, realcal, alcCalFactor = 6.93;
923 if (!test_for_negative_zero(&food_ptr->nutrient[VITE_ADDED]) || !test_for_negative_zero(&food_ptr->nutrient[TOCPHA])) food_ptr->nutrient[VITE] = (food_ptr->nutrient[VITE_ADDED] / 0.45) + ((food_ptr->nutrient[TOCPHA] - food_ptr->nutrient[VITE_ADDED]) / 0.67);
924 if (test_for_negative_zero(&food_ptr->nutrient[VITE_ADDED]) && test_for_negative_zero(&food_ptr->nutrient[TOCPHA])) food_ptr->nutrient[VITE] = NoData;
925 food_ptr->nutrient[LA] = food_ptr->nutrient[F18D2CN6] > 0 ? food_ptr->nutrient[F18D2CN6] : food_ptr->nutrient[F18D2] - food_ptr->nutrient[F18D2T] - food_ptr->nutrient[F18D2TT] - food_ptr->nutrient[F18D2I] - food_ptr->nutrient[F18D2CLA];
926 if (food_ptr->nutrient[LA] == 0 && test_for_negative_zero(&food_ptr->nutrient[F18D2])) food_ptr->nutrient[LA] = NoData;
927 if (food_ptr->nutrient[LA] < 0) food_ptr->nutrient[LA] = 0;
928 food_ptr->nutrient[SHORT6] = food_ptr->nutrient[LA];
929 food_ptr->nutrient[SHORT6] += food_ptr->nutrient[F18D3CN6];
930 food_ptr->nutrient[ALA] = food_ptr->nutrient[F18D3CN3] > 0 ? food_ptr->nutrient[F18D3CN3] : food_ptr->nutrient[F18D3] - food_ptr->nutrient[F18D3CN6] - food_ptr->nutrient[F18D3I];
931 if (food_ptr->nutrient[ALA] == 0 && test_for_negative_zero(&food_ptr->nutrient[F18D3])) food_ptr->nutrient[ALA] = NoData;
932 if (food_ptr->nutrient[ALA] < 0) food_ptr->nutrient[ALA] = 0;
933 food_ptr->nutrient[SHORT3] = food_ptr->nutrient[ALA];
934 food_ptr->nutrient[SHORT3] += food_ptr->nutrient[F18D4];
935 food_ptr->nutrient[LONG6] = food_ptr->nutrient[F20D2CN6];
936 food_ptr->nutrient[LONG3] = food_ptr->nutrient[F20D5];
937 if (food_ptr->nutrient[F20D3N3] > 0) food_ptr->nutrient[LONG3] += food_ptr->nutrient[F20D3N3];
938 if (food_ptr->nutrient[F20D3N6] > 0) food_ptr->nutrient[LONG6] += food_ptr->nutrient[F20D3N6];
939 if (food_ptr->nutrient[F20D3N3] == 0 && food_ptr->nutrient[F20D3N6] == 0) food_ptr->nutrient[LONG6] += food_ptr->nutrient[F20D3];
940 food_ptr->nutrient[AA] = food_ptr->nutrient[F20D4];
941 if (food_ptr->nutrient[F20D4N6] > 0) food_ptr->nutrient[AA] = food_ptr->nutrient[F20D4N6];
942 food_ptr->nutrient[LONG6] += food_ptr->nutrient[AA];
943 food_ptr->nutrient[LONG3] += food_ptr->nutrient[F22D5];
944 food_ptr->nutrient[LONG6] += food_ptr->nutrient[F22D4];
945 food_ptr->nutrient[LONG3] += food_ptr->nutrient[F21D5];
946 food_ptr->nutrient[EPA] = food_ptr->nutrient[F20D5];
947 food_ptr->nutrient[DHA] = food_ptr->nutrient[F22D6];
948 food_ptr->nutrient[LONG3] += food_ptr->nutrient[F22D6];
949 if (food_ptr->nutrient[SHORT3] == 0 && test_for_negative_zero(&food_ptr->nutrient[ALA]) && test_for_negative_zero(&food_ptr->nutrient[F18D4])) food_ptr->nutrient[SHORT3] = NoData;
950 if (food_ptr->nutrient[LONG3] == 0 && test_for_negative_zero(&food_ptr->nutrient[EPA]) && test_for_negative_zero(&food_ptr->nutrient[F22D5]) && test_for_negative_zero(&food_ptr->nutrient[DHA])) food_ptr->nutrient[LONG3] = NoData;
951 if (food_ptr->nutrient[SHORT6] == 0 && test_for_negative_zero(&food_ptr->nutrient[LA]) && test_for_negative_zero(&food_ptr->nutrient[F18D3CN6])) food_ptr->nutrient[SHORT6] = NoData;
952 if (food_ptr->nutrient[LONG6] == 0 && test_for_negative_zero(&food_ptr->nutrient[F20D2CN6]) && test_for_negative_zero(&food_ptr->nutrient[F20D3]) && test_for_negative_zero(&food_ptr->nutrient[F20D3N6]) && test_for_negative_zero(&food_ptr->nutrient[AA])) food_ptr->nutrient[LONG6] = NoData;
953 food_ptr->nutrient[OMEGA6] = food_ptr->nutrient[SHORT6] + food_ptr->nutrient[LONG6];
954 if (food_ptr->nutrient[OMEGA6] == 0 && test_for_negative_zero(&food_ptr->nutrient[SHORT6]) && test_for_negative_zero(&food_ptr->nutrient[LONG6])) food_ptr->nutrient[OMEGA6] = NoData;
955 food_ptr->nutrient[OMEGA3] = food_ptr->nutrient[SHORT3] + food_ptr->nutrient[LONG3];
956 if (food_ptr->nutrient[OMEGA3] == 0 && test_for_negative_zero(&food_ptr->nutrient[SHORT3]) && test_for_negative_zero(&food_ptr->nutrient[LONG3])) food_ptr->nutrient[OMEGA3] = NoData;
957
958 if ( food_ptr->prot_cal_factor == 0 && food_ptr->fat_cal_factor == 0 && food_ptr->cho_cal_factor == 0 && food_ptr->nutrient[ENERC_KCAL] > 0)
959 {
960 food_ptr->prot_cal_factor = 4;
961 food_ptr->fat_cal_factor = 9;
962 food_ptr->cho_cal_factor = 4;
963 food_ptr->nutrient[PROT_KCAL] = food_ptr->prot_cal_factor * food_ptr->nutrient[PROCNT];
964 food_ptr->nutrient[FAT_KCAL] = food_ptr->fat_cal_factor * food_ptr->nutrient[FAT];
965 food_ptr->nutrient[CHO_KCAL] = food_ptr->cho_cal_factor * food_ptr->nutrient[CHOCDF];
966 realcal = food_ptr->nutrient[ENERC_KCAL] - (food_ptr->nutrient[ALC] * alcCalFactor);
967 ratio = realcal / (food_ptr->nutrient[PROT_KCAL] + food_ptr->nutrient[FAT_KCAL] + food_ptr->nutrient[CHO_KCAL]);
968 food_ptr->prot_cal_factor *= ratio;
969 food_ptr->fat_cal_factor *= ratio;
970 food_ptr->cho_cal_factor *= ratio;
971 }
972 food_ptr->nutrient[PROT_KCAL] = food_ptr->prot_cal_factor * food_ptr->nutrient[PROCNT];
973 food_ptr->nutrient[FAT_KCAL] = food_ptr->fat_cal_factor * food_ptr->nutrient[FAT];
974 food_ptr->nutrient[CHO_KCAL] = food_ptr->cho_cal_factor * food_ptr->nutrient[CHOCDF];
975 if (!test_for_negative_zero(&food_ptr->nutrient[CHOCDF]))
976 {
977 food_ptr->nutrient[CHO_NONFIB] = food_ptr->nutrient[CHOCDF] - food_ptr->nutrient[FIBTG];
978 if (food_ptr->nutrient[CHO_NONFIB] < 0) food_ptr->nutrient[CHO_NONFIB] = 0;
979 }
980 }
981
format_serving(char * buffer,float * ratio,struct food * food_ptr)982 char *format_serving(char *buffer, float *ratio, struct food *food_ptr)
983 {
984 sprintf(buffer,"%1.3g",food_ptr->qty * *ratio);
985 strncat(buffer," ",50);
986 strncat(buffer,food_ptr->unit,50);
987 buffer[49] = '\0';
988 return buffer;
989 }
990
load_foodwork(int max,struct meal * meal_ptr_origin)991 struct meal *load_foodwork(int max, struct meal *meal_ptr_origin)
992 {
993 int meals = 0, meal = 0, count = 0;
994 char meal_date[9];
995 struct meal *meal_ptr = meal_ptr_origin;
996 clear_work();
997 if (max == 0) max = meal_count(meal_ptr);
998 clear_work();
999 while (meal_ptr->next != NULL && meals <= max)
1000 {
1001 meal_ptr = meal_ptr->next;
1002 if (strcmp(meal_date,meal_ptr->meal_date) != 0 || meal != meal_ptr->meal)
1003 {
1004 strcpy(meal_date,meal_ptr->meal_date);
1005 meal = meal_ptr->meal;
1006 meals++;
1007 }
1008 if (meals > max) break;
1009 for (count = 1; count <= *ScreenMap[options.screen] ; count++) if (! test_for_negative_zero(&FoodIndex[meal_ptr->food_no]->nutrient[ScreenMap[options.screen][count]])) food_work.nutrient[ScreenMap[options.screen][count]] = food_work.nutrient[ScreenMap[options.screen][count]] + ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[ScreenMap[options.screen][count]]) / (float) max);
1010 if (options.screen < 2)
1011 {
1012 food_work.nutrient[FAT_KCAL] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[FAT_KCAL]) / (float) max);
1013 food_work.nutrient[PROT_KCAL] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[PROT_KCAL]) / (float) max);
1014 food_work.nutrient[CHO_KCAL] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[CHO_KCAL]) / (float) max);
1015 food_work.nutrient[SHORT3] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[SHORT3]) / (float) max);
1016 food_work.nutrient[LONG3] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[LONG3]) / (float) max);
1017 food_work.nutrient[SHORT6] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[SHORT6]) / (float) max);
1018 food_work.nutrient[LONG6] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[LONG6]) / (float) max);
1019 food_work.nutrient[ALC] += ((options.mealsperday * meal_ptr->grams / 100 * FoodIndex[meal_ptr->food_no]->nutrient[ALC]) / (float) max);
1020 }
1021 }
1022 return meal_ptr;
1023 }
1024
n6hufa(float p3,float p6,float h3,float h6,float o,float c)1025 float n6hufa(float p3, float p6, float h3, float h6, float o, float c)
1026 {
1027 float pc6 = .0441, pc3 = .0555, co = 5, ks = .175, hc6 = .7, hc3 = 3;
1028 float hi3 = .005;
1029 /* float hi6 = .04; */
1030 float answer;
1031 /*
1032 printf("%f %f %f %f %f\n",p3,p6,h3,h6,o);
1033 exit(0);
1034 */
1035 /* if (p3 == 0 && p6 == 0 && h3 == 0 && h6 == 0) return 0; */
1036 if (p3 < 0.00000001 && p6 < 0.00000001 && h3 < 0.00000001 && h6 < 0.00000001) return 0;
1037 /* if (c == 0) return 0; */
1038 if (c < 0.00000001) return 0;
1039 answer = 100 / (1 + pc6/p6 * (1 + p3/pc3 + h3/hi3 + o/co + p6/ks)) + 100 / (1 + hc6/h6 * (1 + h3/hc3));
1040 if (answer <= 90 && answer >= 15) return answer;
1041 if (answer > 90) return 90;
1042 else return 15;
1043 }
1044