/*
 * MODULE: GROCLIST.C
 *
 *    Subroutines for GROCLIST.
 *
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define MODULE_GROCLIST
#include "common.h"


/*
 *       -------======= LIST HOOK FUNCTIONS =======-------
 *
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
SAVEDS ASM LONG fnGrocListCompareFunc( REG(a0) struct Hook *hook, REG(a1) char *pszGL1, REG(a2) char *pszGL2 )
{
   char *psz1, *psz2;


   psz1 = fnSkipQuantity( pszGL1 );
   psz2 = fnSkipQuantity( pszGL2 );

   return( stricmp( psz1, psz2 ) );
}
static struct Hook hGrocListCompareHook = {
   {NULL, NULL},
   (void *)fnGrocListCompareFunc,
   NULL, NULL
};


/*
 *             -------======= ROUTINES =======-------
 *
 *
 * void  fnFillIngredientsList( APTR, ULONG, APTR )
 *
 * BOOL  fnConstructGrocListWindow( void )
 * BOOL  fnInitGrocListWindow( void )
 * BOOL  fnDestructGrocListWindow( BOOL fOKorCANCEL )
 *
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void fnFillIngredientsList( APTR pListObject, ULONG ulDiskAddr, struct MakeNode *pMNode )
{
   APTR                  pMemRecord = NULL;
   UBYTE                *psz, *psz2, *pszStart, *pszEnd;
   char                  szLineBuf[90], szFractionBuf[20];
   float                 fl;


   pMemRecord = fnFetchRecord( ulDiskAddr );
   if ( pMemRecord )
   {
      // find start of ingredients list...
      if ( pszStart = (char *)fnFindRecordItem( pMemRecord, RECITEM_INGREDIENTS, NULL ) )
      {
         pszEnd = strchr( pszStart, LEVEL1BREAK );

         //
         // read ingredients and stuff into groclist (for now)
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         for ( psz = pszStart; psz < ( pszEnd-1 ); )
         {
            psz2 = strchr( psz+1, LEVEL2BREAK );
            if ( psz2 )
            {
               *psz2 = 0;

               //
               // multiplier
               // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               fl = fnExtractValue( pMNode->szNewServings );
               fl *= fnExtractValue( psz );
               fl /= fnExtractValue( pMNode->szStdServings );
               fnFloat2Frac( fl, szFractionBuf );
               sprintf( szLineBuf, "%s %s", szFractionBuf, fnSkipQuantity( psz ) );

               DoMethod( pListObject, MUIM_List_InsertSingle,
                         szLineBuf, MUIV_List_Insert_Sorted );

               *psz2 = LEVEL2BREAK;
               psz = psz2+1;
            }
         }
      }
      FreeVec( pMemRecord );
   }
}

// ***********************************************************************
//
//    GROCERY LIST WINDOW
// struct GroceryListWindow {
//    APTR  LIS_GroceryList,
//          BUT_Print,
//          BUT_Cancel;
// } GROCLIST;
//
// ***********************************************************************
//
BOOL  fnConstructGrocListWindow( void )
{
   MG.WIN_GrocList = WindowObject,
      MUIA_Window_ID, MAKE_ID('G','R','O','C'),
      MUIA_Window_Title, "Grocery List",
      MUIA_Window_Menu, MUIV_Window_Menu_NoMenu,
      WindowContents, VGroup,
         Child, GROCLIST.LIS_GroceryList = ListviewObject,
            MUIA_Listview_Input, FALSE,
            MUIA_Listview_List, ListObject,
               ReadListFrame,
               MUIA_List_CompareHook,   &hGrocListCompareHook,
               MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
               MUIA_List_DestructHook,  MUIV_List_DestructHook_String,
               End,
            End,
         Child, HGroup,
            Child, GROCLIST.BUT_Print  = KeyButton("Print",'p'),
            Child, HSpace(0),
            Child, GROCLIST.BUT_Cancel = SimpleButton("Cancel"),
            End,
         End,
      End;

   // window failed?
   if ( !MG.WIN_GrocList )
   {
      return( FAILURE );
   }
   else
   {
      // make gadget connections
      DoMethod( MG.WIN_GrocList, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
                MG.App, 2, MUIM_Application_ReturnID, ID_WIN_CLOSE_GROCLIST );

      DoMethod( GROCLIST.BUT_Print, MUIM_Notify, MUIA_Pressed, FALSE,
                MG.App, 2, MUIM_Application_ReturnID, ID_BUT_GROCLISTPRINT );
      DoMethod( GROCLIST.BUT_Cancel, MUIM_Notify, MUIA_Pressed, FALSE,
                MG.App, 2, MUIM_Application_ReturnID, ID_BUT_GROCLISTCANCEL );

      // set tab cycle chain
      DoMethod( MG.WIN_GrocList, MUIM_Window_SetCycleChain,
                GROCLIST.LIS_GroceryList,
                GROCLIST.BUT_Print,
                GROCLIST.BUT_Cancel,
                NULL );

      // add window to Application object
      DoMethod( MG.App, OM_ADDMEMBER, MG.WIN_GrocList );

      return( SUCCESS );
   }
}

BOOL  fnInitGrocListWindow( void )
{
   ULONG  ulStat;
   LONG   lStat;

   struct MakeNode      *pMNode = NULL;
   struct RecipeMemNode *pRMNode = NULL;
   UBYTE                *psz;
   char                  szLineBuf[90], szFractionBuf[20];
   char                  szCurrentLine[90], szLikeLine[90];
   char                 *pszCurrentLine, *pszLikeLine;
   LONG                  lLikeLine = -1;
   float                 flLikeTotal = 0.0;


   set( MG.WIN_Main, MUIA_Window_Sleep, TRUE );

   DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_Clear, TRUE );

   // get number of items selected...
   get( MAKE.LIS_Recipes, MUIA_List_Entries, &ulStat );
   for ( lStat = 0; lStat < ulStat; lStat++ )
   {
      DoMethod( MAKE.LIS_Recipes, MUIM_List_GetEntry, lStat, &pMNode );
      if ( pMNode )
      {
         // get ingredients list
         DoMethod( MAIN.LIS_RecipeList, MUIM_List_GetEntry, pMNode->ulMainListIndex, &pRMNode );
         fnFillIngredientsList( GROCLIST.LIS_GroceryList, pRMNode->ulDiskAddr, pMNode );
      }
   }

   //
   // scan list for like terms and combine
   // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   get( GROCLIST.LIS_GroceryList, MUIA_List_Entries, &ulStat );
   if ( ulStat > 0 )
   {
      strcpy( szLikeLine, "" );
      pszLikeLine = NULL;
      for ( lStat = 0; lStat < ulStat; lStat++ )
      {
         DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_GetEntry, lStat, &psz );
         strcpy( szCurrentLine, psz );
         pszCurrentLine = fnSkipQuantity( szCurrentLine );
         if ( pszLikeLine )
         {
            if ( strcmpi( pszCurrentLine, pszLikeLine ) == 0 )
            {
               // add like terms
               flLikeTotal += fnExtractValue( szCurrentLine );

               // delete duplicate lines
               DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_Remove, lStat );
               lStat--;
               ulStat--;

               // if last line is a dup, put total back into list
               if ( lStat == ulStat-1 )
               {
                  // insert total back into list
                  DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_Remove, lLikeLine );
                  fnFloat2Frac( flLikeTotal, szFractionBuf );
                  sprintf( szLineBuf, "%s %s", szFractionBuf, pszLikeLine );
                  DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_InsertSingle, szLineBuf, lLikeLine );
               }
            }
            else
            {
               // insert total back into list
               DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_Remove, lLikeLine );
               fnFloat2Frac( flLikeTotal, szFractionBuf );
               sprintf( szLineBuf, "%s %s", szFractionBuf, pszLikeLine );
               DoMethod( GROCLIST.LIS_GroceryList, MUIM_List_InsertSingle, szLineBuf, lLikeLine );

               strcpy( szLikeLine, szCurrentLine );
               pszLikeLine = fnSkipQuantity( szLikeLine );
               lLikeLine = lStat;
               flLikeTotal = fnExtractValue( szLikeLine );
            }
         }
         else
         {
            strcpy( szLikeLine, szCurrentLine );
            pszLikeLine = fnSkipQuantity( szLikeLine );
            lLikeLine = lStat;
            flLikeTotal = fnExtractValue( szLikeLine );
         }
      }
   }

   set( MG.WIN_GrocList, MUIA_Window_Open, TRUE );
   set( MG.WIN_GrocList, MUIA_Window_DefaultObject, GROCLIST.BUT_Print );
   set( MG.WIN_GrocList, MUIA_Window_ActiveObject,  GROCLIST.BUT_Print );

   return( SUCCESS );
}

BOOL  fnDestructGrocListWindow( BOOL fOKorCANCEL )
{
   BOOL  rc = SUCCESS;


   switch( fOKorCANCEL )
   {
      case ENDWINDOW_OK:
         break;
      case ENDWINDOW_CANCEL:
         break;
   }

   set( MG.WIN_GrocList, MUIA_Window_Open, FALSE );
   set( MG.WIN_Main, MUIA_Window_Sleep, FALSE );

   return( rc );
}
