
------------------------------------------------------------------------------
-- Program Name: Recipe

------------------------------------------------------------------------------

program Recipe; 
 
#include Recipe.iri 

  -- Constants and aliases definitions 
  g_csProgName          : constant string  := "Recipe"; --Program Name 
  g_csVersion           : constant string  := "1.00"; --Program Version   
  g_ciPrinter           : constant integer := 0;
  g_ciDigInOn           : constant integer := 0; --Digital Input is On 
  g_ciDigInOff          : constant integer := 1; --Digital Input is Off
  g_ciDigOutOn          : constant integer := 1; --Digital Output is On
  g_ciDigOutOff         : constant integer := 0; --Digital Output is Off  
  g_ciBackDoorPassword  : constant string  := "1234";  --Backdoor Password 
  g_ciInt32_Max         : constant integer := 2147483647;   
  g_ciMaxIngredients    : constant integer := 4;
  
  -- Inputs/Outputs  
  g_ciStartAbort    : constant integer := 1;
  g_ciEStop         : constant integer := 2;  
  g_coDischarge    : constant integer := 7;

  -- Screens
  g_ciMain    : constant integer := 1;
  g_ciSetup   : constant integer := 9; 
  g_ciIOTest  : constant integer := 4;    
  
  -- Operation Modes
  LockMode                : constant integer := 0;
  NoMode                  : constant integer := 100;    
  EnterRecipeID           : constant integer := 101; 
  
  -- Setup Modes
  SetupEnterPasswordMode   : constant integer := 999;
  Setup1Mode               : constant integer := 1000; 
    SetupChangePasswordMode  : constant integer := 1100;
      SetupVerifyPasswordMode  : constant integer := 1101;
    SetupDatabaseMode1        : constant integer :=  1200;  
      SetupRecipeId             : constant integer := 1210;
        SetupRecipeName           : constant integer := 1211;
        SetupRecipeIngred1        : constant integer := 1212;
        SetupRecipeTarget1        : constant integer := 1213;
        SetupRecipeIngred2        : constant integer := 1214;
        SetupRecipeTarget2        : constant integer := 1215;
        SetupRecipeIngred3        : constant integer := 1216;
        SetupRecipeTarget3        : constant integer := 1217;
        SetupRecipeIngred4        : constant integer := 1218;
        SetupRecipeTarget4        : constant integer := 1219;                
      SetupDeleteRecipe         : constant integer := 1220;
      SetupIngredId             : constant integer := 1230;
        SetupIngredName           : constant integer := 1231;
        SetupIngredPreact         : constant integer := 1232;
      SetupDeleteIngred         : constant integer := 1240; 
    SetupScaleEmptyWeightMode  : constant integer := 1300;
    SetupScaleDischargeTimeMode : constant integer := 1301; 
  Setup2Mode                     : constant integer :=  2000;
    SetupIOTest              : constant integer := 2200; 
      SetupTurnOnOutput        : constant integer := 2210; 
      SetupTurnOffOutput       : constant integer := 2220; 	

  EntryMode : integer; 

  -- Batch Modes     
  Complete               : constant integer := 50000;
  WaitSSTare             : constant integer := 50001;
  Filling                : constant integer := 50002;  
  WaitSSFull             : constant integer := 50003;
  Discharging            : constant integer := 50004;
  DischargeDelay         : constant integer := 50005; 
  
  BatchMode : integer; 
  type Pausedmode is (Yes, No);
  Paused : PausedMode;

  Blank : constant string := "";      
  type boolean is (False,True); 

  -- Global/Types variables definitions 
  g_sSetupPassword : stored string;
  g_iDownload : stored integer;
  g_sTmpPassword : string;  
  g_rCountby : real;    
  g_bUpdate : boolean;
  g_iDecimal1 : integer;  
  g_uUnits : Units; 
  g_sysResult : SysCode;   
  g_iDebug : integer;
  g_rScaleEmptyWeight : stored real;
  g_rScaleDischargeTime : stored real;
  g_iRecipeId : stored integer;  
  g_iTotalNbrIngredients : integer;    
  g_iCurrentIngredient : integer;    
  g_iDelayCnt : integer;     

  type RecipeRecord is
    record 
      iRecipeId : integer;
      sRecipeName : string; 
      iIngredientId : integer;
      sIngredientName : string;  
      rTargetWgt : real;    
      rPreactWgt : real;
      rActualWgt : real;      
    end record;   

  type RecipeArrays is array [4] of RecipeRecord;
  -- Database display array
  g_arRecipe : stored RecipeArrays;   
       
  IngredDB : IngredDatabase;
  RecipeDB : RecipeDatabase;   
  
  -- Functions and procedures definitions   

  -- Sets all 5 sofktey text  
  procedure WriteKeys(sKey1 : string; sKey2 : string; sKey3 : string; sKey4 : string; sKey5 : string);
  begin  
  
    SetSoftkeyText(1, sKey1);
    SetSoftkeyText(2, sKey2);
    SetSoftkeyText(3, sKey3);
    SetSoftkeyText(4, sKey4);
    SetSoftkeyText(5, sKey5);  
       
  end;  

  procedure SetKeys;
  begin
    if EntryMode = NoMode then
      if BatchMode = Complete then
        WriteKeys("Recipe", Blank, Blank, Blank,"Setup Menu"); 
      else
        WriteKeys(Blank, Blank, Blank, Blank,Blank);
      end if;
    elsif EntryMode = Setup1Mode then
      WriteKeys("Setup Password", "Database Setup", "Empty Weight", "Discharge Time", "More=>");
		elsif EntryMode = Setup2Mode then
			WriteKeys("<=Back", "IO Test Screen", Blank, Blank, "Exit");
    elsif EntryMode = SetupDatabaseMode1 then
      WriteKeys("Add/Edit Recipes" ,"Delete Recipes", "Add/Edit Ingredients", "Delete Ingredients", "Exit");         
    elsif EntryMode = SetupIOTest then
      WriteKeys("Turn ON Output" ,"Turn OFF Output", "Turn OFF ALL Outputs", Blank, "Exit");  		
		end if;
  end;      

  procedure SetupStartTimer(iTimer : integer; iDuration : integer; itmMode : TimerMode);  -- Setup a Timer and Start                                
  begin
  
    SetTimer(iTimer, iDuration);
    SetTimerMode(iTimer, itmMode);
    StartTimer(iTimer);
    
  end;  
  
  procedure DisableSetPoints;
  begin
    
    DisableSP(1);
    DisableSP(2);
    DisableSP(3);
    DisableSP(4);
    
  end;

  function GetCurrentUnitsString(s : integer) : string;  -- Gets current units string (lb/kg/etc). 
    sUnit : Units;
    sUnitString : string;  
  begin          
    
    if GetUnits(s, sUnit) = SysOk then
      GetUnitsString(s, sUnit, sUnitString);    
    else
      sUnitString := Blank;
    end if; 
    
    return sUnitString; 
    
  end;    
  
  function Pad15Spaces(s : string) : string;
  begin

    while Len(s) < 15
    loop   
      s := s + " "; 
    end loop; 
     
    return s;   

  end; 

  procedure PrintTicket; 
    sUnitsString : string;   
    rTargetWgt : real := 0.0;
    rActualWgt : real := 0.0;   
    i : integer;
  begin  

    sUnitsString := GetCurrentUnitsString(1);    
        
    SetPrintText(1, IntegerToString(g_arRecipe[1].iRecipeId,0));
    SetPrintText(2, g_arRecipe[1].sRecipeName);
    Print(AuxFmt1);    
    ProgramDelay(25);
				
    for i := 1 to g_ciMaxIngredients
    loop
      if g_arRecipe[i].rTargetWgt <> 0.0 then
        SetPrintText(3, Pad15Spaces(g_arRecipe[i].sIngredientName));
        SetPrintText(4, RealToString(g_arRecipe[i].rTargetWgt,6,g_iDecimal1) + " " + sUnitsString);    
        SetPrintText(5, RealToString(g_arRecipe[i].rActualWgt,6,g_iDecimal1) + " " + sUnitsString);    
        rTargetWgt := rTargetWgt + g_arRecipe[i].rTargetWgt;
        rActualWgt := rActualWgt + g_arRecipe[i].rActualWgt; 
        Print(AuxFmt2);                                                                   
        ProgramDelay(25);          
      end if; 
    end loop;
     
    SetPrintText(6, RealToString(rTargetWgt,6,g_iDecimal1) + " " + sUnitsString);                                                                                                 
    SetPrintText(7, RealToString(rActualWgt,6,g_iDecimal1) + " " + sUnitsString); 
    Print(AuxFmt3); 
    ProgramDelay(25);
    
    SetLabelText(lbSts1, Blank); 

  end;   
  
  procedure DisableDisplayListHandlers;  -- Disables NumericKey, NavUp, NavDown and Enter Key Handlers
  begin

    DisableHandler(NumericKeyPressed);
    DisableHandler(NavUpKeyPressed);   
    DisableHandler(NavDownKeyPressed); 
    DisableHandler(EnterKeyPressed);  
  
  end;    

  procedure EnableDisplayListHandlers;  -- Enables NumericKey, NavUp, NavDown and Enter Key Handlers
  begin

    EnableHandler(NumericKeyPressed);
    EnableHandler(NavUpKeyPressed);   
    EnableHandler(NavDownKeyPressed); 
    EnableHandler(EnterKeyPressed);  
  
  end;  

  procedure LockMajorKeys;  -- Locks ZERO, GROSS/NET, TARE, UNITS and PRINT key
  begin
  
    LockKey(GrossNetKey);
    LockKey(TareKey);
    LockKey(UnitsKey);
    LockKey(PrintKey);
    
  end; 

  procedure UnLockMajorKeys;  -- UnLocks ZERO, GROSS/NET, TARE, UNITS and PRINT key
  begin
  
    UnlockKey(GrossNetKey);
    UnlockKey(TareKey);
    UnlockKey(UnitsKey);
    UnlockKey(PrintKey);
    
  end;   

  procedure LockAllKeys; -- Lock All Keys
  begin
  
    LockMajorKeys;
    DisableDisplayListHandlers;
  
  end;

  procedure PromptForEntry(sPrompt : string;  iMode : integer; sDefault : string);  -- Prompts operator for data
  begin
    
    DisableHandler(NumericKeyPressed);
    DisableHandler(EnterKeyPressed);
    DisableHandler(NavUpKeyPressed);
    DisableHandler(NavDownKeyPressed);   
    
    LockMajorKeys;
 
		SetEntry(sDefault);
    PromptUser(sPrompt);
    EntryMode := iMode;
    
  end;  

  function IsDigits(sNumeric : string) : boolean;  -- Makes ure user entry is numeric       
    i : integer;
    sTemp : string;
    bResult : boolean := True;
    bDecimal : boolean := False;
  begin
  
    if sNumeric = "." or StringToInteger(sNumeric) >= g_ciInt32_Max then   
      bResult := False;
      return bResult;
    end if;  

    for i := 1 to Len(sNumeric)
    loop                              
    
      sTemp := Mid$(sNumeric, i, 1); 
      
      -- ignore first decimal point
      if sTemp = "." then  
        if bDecimal = True then   
          bResult := False;
          exit;   
        end if;     
        bDecimal := True;  
      end if; 
      
      -- ignore negative if first character
      if i <> 1 and sTemp = "-" then
        bResult := False;
        exit;
      end if;
      
      if (sTemp < "0" or sTemp > "9") and sTemp <> "." and sTemp <> "-" then        
        bResult := False;
        exit;
      end if; 
      
    end loop;
        
    return bResult; 
    
  end;   

  function IsValid(sTemp : string; sValidFor : string; iLength : integer) : boolean;  -- Validates a String, Integer and Real
    bResult : boolean := True; 
    sMessage : string;
  begin 
    
    sValidFor := UCase$(sValidFor);
    
    if sValidFor = "S" then
    
      if Len(sTemp) = 0 or (Len(sTemp) > iLength and iLength <> 0) then  
        bResult := False;
        sMessage := "Required Entry - Try Again";  
      end if;      
        
    elsif sValidFor = "I" then
      
      if isDigits(sTemp) = False then
        bResult := False;  
        sMessage := "Invalid Number - Try Again";        
      elsif (Len(sTemp) = 0 or StringToInteger(sTemp) < 1) and iLength = 0 then   -- iLength to 1 will allow zero for an entry
        bResult := False;  
        sMessage := "Invalid Number (0) - Try Again";
      end if;      
    
    elsif sValidFor = "R" then
    
      if isDigits(sTemp) = False or StringToReal(sTemp) < 0 then     
        bResult := False;    
        sMessage := "Invalid Number - Try Again";
      elsif (Len(sTemp) = 0 or StringToReal(sTemp) = 0) and iLength = 0 then  -- iLength to 1 will allow zero for an entry
        bResult := False;    
        sMessage := "Invalid Number (0) - Try Again";              
      end if;  

    elsif sValidFor = "P" then
    
      if isDigits(sTemp) = False or StringToReal(sTemp) < 0 or StringToReal(sTemp) > 100 then 
        bResult := False; 
        sMessage := "Invalid Number (0-100) - Try Again";
      end if; 
                
    else
      
      DisplayStatus("Validation Error");
      bResult := False;
      
    end if;

    if bResult = False then
      PromptForEntry(sMessage, EntryMode, Blank);
    end if;
    
    return bResult;

  end;   
  
  function CalcDecimal(rCountBy : real) : integer;  -- Calculates the amount of decimal positions  
    iDecimal : integer := 0;    
  begin   
         
    while rCountBy < 1.0
    loop    
      iDecimal := iDecimal + 1;
      rCountBy := rCountBy * 10.0;  
     end loop;

     return iDecimal; 
     
  end; 

  procedure DisplayVersion;    -- Displays Version Number and program name on startup or exiting config   
  begin   
  
    DisplayStatus(g_csProgName + " " + g_csVersion); 
    SetLabelText(lbProg, "Program: " + g_csProgName + " " + g_csVersion);  
    
  end; 

  procedure TurnOffAllOutputs;  -- Turn off All Outputs
    i : integer;
  begin
    
    for i := 3 to 7
    loop
      SetDigout(0, i, g_ciDigOutOff);
    end loop;  
  
  end;     
  
  procedure RefreshSetupDisplay;  -- Update display screen in setup menu 
    sUnits : string;    
  begin             
    
    -- Remember to put the units string after all weight variables
    sUnits := GetCurrentUnitsString(1);               

    SetLabelText(lbSet1, "Empty Weight: " + RealToString(g_rScaleEmptyWeight,0,g_iDecimal1) + " " + sUnits);
    SetLabelText(lbSet2, "Discharge Time (sec): " + RealToString(g_rScaleDischargeTime,0,1));
  	SetLabelText(lbset3, Blank);
		
  end; 
  
  procedure RefreshMainDisplay;       
    i : integer;      
    iStart : integer;
		sUnits : string;
  begin
		
		sUnits := GetCurrentUnitsString(1); 
    
    if g_arRecipe[1].iRecipeId <> 0 then 
      SetLabelText(lbRec, "Recipe " + IntegerToString(g_arRecipe[1].iRecipeId,0) + " - " + g_arRecipe[1].sRecipeName);
    else
      SetLabelText(lbRec, Blank);
    end if; 
    
    iStart := lbSt - 3;
    
    for i := 1 to 4
    loop  
      
      if g_arRecipe[i].sIngredientName <> Blank then
        SetLabelText(iStart + (i * 3),  IntegerToString(g_arRecipe[i].iIngredientId,0) + " - " + g_arRecipe[i].sIngredientName);
        SetLabelText(iStart + 1 + (i * 3),  RealToString(g_arRecipe[i].rTargetWgt,0,g_iDecimal1) + " " + sUnits);
        SetLabelText(iStart + 2 + (i * 3),  RealToString(g_arRecipe[i].rActualWgt,0,g_iDecimal1) + " " + sUnits);
      else
        SetLabelText(iStart + (i * 3),  Blank);
        SetLabelText(iStart + 1 + (i * 3),  Blank);
        SetLabelText(iStart + 2 + (i * 3),  Blank);        
      end if;
      
    end loop;
  
  end;
  
  procedure GoIntoSetupMenu;  -- Enters Setup Menu
  begin

    DisplayStatus("Setup Menu");
    EntryMode := Setup1Mode;  
    SetKeys;      
    SelectScreen(g_ciSetup);     
    RefreshSetupDisplay;     
  
  end; 

  procedure ClearStatus(iTime : integer);  -- Removes Display Status Message
  begin 
  
    SetupStartTimer(29, iTime, TimerOneShot);
    
  end;    
  
  procedure ClearRecipeArray;  
    i : integer;
  begin 
  
    for i := 1 to g_ciMaxIngredients 
    loop
      g_arRecipe[i].iRecipeId := 0; 
      g_arRecipe[i].sRecipeName := Blank; 
      g_arRecipe[i].iIngredientId := 0; 
      g_arRecipe[i].sIngredientName := Blank;
      g_arRecipe[i].rTargetWgt := 0.0;    
      g_arRecipe[i].rPreactWgt := 0.0;
      g_arRecipe[i].rActualWgt := 0.0;            
    end loop;
         
  end;     

  procedure PopulateRecipeArray; 
    i : integer := 0;
  begin 
    
    ClearRecipeArray;   
      
    IngredDB.Id := RecipeDB.Ingred1;
    if IngredDB.FindFirst(Ingred_Id) = SysOk then 
      if RecipeDB.Target1 <> 00.00 then  -- Don't include ingredients with a target of zero 
        i := i + 1;  
        g_arRecipe[i].iRecipeId := RecipeDB.Id; 
        g_arRecipe[i].sRecipeName := RecipeDB.Name; 
        g_arRecipe[i].iIngredientId := IngredDB.Id; 
        g_arRecipe[i].sIngredientName := IngredDB.Name;
        g_arRecipe[i].rTargetWgt := RecipeDB.Target1;    
        g_arRecipe[i].rPreactWgt := IngredDB.Preact; 
        SetSPValue(RecipeDB.Ingred1, g_arRecipe[i].rTargetWgt - g_arRecipe[i].rPreactWgt);              
      end if; 
    end if; 

    IngredDB.Id := RecipeDB.Ingred2;
    if IngredDB.FindFirst(Ingred_Id) = SysOk then 
      if RecipeDB.Target2 <> 00.00 then  -- Don't include ingredients with a target of zero 
        i := i + 1;  
        g_arRecipe[i].iRecipeId := RecipeDB.Id; 
        g_arRecipe[i].sRecipeName := RecipeDB.Name; 
        g_arRecipe[i].iIngredientId := IngredDB.Id; 
        g_arRecipe[i].sIngredientName := IngredDB.Name;
        g_arRecipe[i].rTargetWgt := RecipeDB.Target2;    
        g_arRecipe[i].rPreactWgt := IngredDB.Preact;  
        SetSPValue(RecipeDB.Ingred2, g_arRecipe[i].rTargetWgt - g_arRecipe[i].rPreactWgt);             
      end if; 
    end if;

    IngredDB.Id := RecipeDB.Ingred3;
    if IngredDB.FindFirst(Ingred_Id) = SysOk then 
      if RecipeDB.Target3 <> 00.00 then  -- Don't include ingredients with a target of zero 
        i := i + 1;  
        g_arRecipe[i].iRecipeId := RecipeDB.Id; 
        g_arRecipe[i].sRecipeName := RecipeDB.Name; 
        g_arRecipe[i].iIngredientId := IngredDB.Id; 
        g_arRecipe[i].sIngredientName := IngredDB.Name;
        g_arRecipe[i].rTargetWgt := RecipeDB.Target3;    
        g_arRecipe[i].rPreactWgt := IngredDB.Preact;   
        SetSPValue(RecipeDB.Ingred3, g_arRecipe[i].rTargetWgt - g_arRecipe[i].rPreactWgt);            
      end if; 
    end if; 

    IngredDB.Id := RecipeDB.Ingred4;
    if IngredDB.FindFirst(Ingred_Id) = SysOk then 
      if RecipeDB.Target4 <> 00.00 then  -- Don't include ingredients with a target of zero 
        i := i + 1;  
        g_arRecipe[i].iRecipeId := RecipeDB.Id; 
        g_arRecipe[i].sRecipeName := RecipeDB.Name; 
        g_arRecipe[i].iIngredientId := IngredDB.Id; 
        g_arRecipe[i].sIngredientName := IngredDB.Name;
        g_arRecipe[i].rTargetWgt := RecipeDB.Target4;    
        g_arRecipe[i].rPreactWgt := IngredDB.Preact;
        g_arRecipe[i].rActualWgt := 0.0;    
        SetSPValue(RecipeDB.Ingred4, g_arRecipe[i].rTargetWgt - g_arRecipe[i].rPreactWgt);             
      end if; 
    end if;		

    g_iTotalNbrIngredients := i;

  end;   

  procedure ProcessPromptCancel;   -- Performs Cancel operation when cancelling a prompt
  begin 
  
    ClosePrompt;  
    UnLockMajorKeys;
    
    
    if EntryMode >= Setup1Mode and EntryMode < Setup2Mode then 

      if EntryMode = SetupScaleEmptyWeightMode or EntryMode = SetupScaleDischargeTimeMode then  
        EntryMode := Setup1Mode;  
      else
        EntryMode := SetupDatabaseMode1; 
        SetKeys;
      end if;
			
		elsif EntryMode = SetupTurnOnOutput or EntryMode = SetupTurnOffOutput then
			
			EntryMode := SetupIOTest;
			
    else    
      SetLabelText(lbSts1, Blank);  
      EntryMode := NoMode; 
      SetKeys;     
    end if;
    
  end;    
  
  procedure ProcessDataEntry(sTemp : string);  -- Processing the entered data  
  begin 
    
    ClosePrompt;   
    UnLockMajorKeys;
    
    if EntryMode = SetupChangePasswordMode then
     
      if IsDigits(sTemp) then 
        g_sTmpPassword := sTemp;
        PromptForEntry("Re-enter Password to Verify", SetupVerifyPasswordMode, Blank);    
      else      
        PromptForEntry("Error: Numeric Only", SetupChangePasswordMode, Blank);  
      end if;      
     
    elsif EntryMode = SetupVerifyPasswordMode then 
    
      if sTemp = g_sTmpPassword then    
        g_sSetupPassword := sTemp;
        EntryMode := Setup1Mode;
        DisplayStatus("Password Changed");      
      else 
        DisplayStatus("Error: Passwords don't Match");
        EntryMode := Setup1Mode;  
      end if;

    elsif EntryMode = SetupScaleEmptyWeightMode then

      if isValid(sTemp, "r", 1) then
        g_rScaleEmptyWeight  :=  StringToReal(sTemp);   
        EntryMode := Setup1Mode;
        SetKeys;        
      end if;

    elsif EntryMode = SetupScaleDischargeTimeMode then

      if isValid(sTemp, "r", 1) then
        g_rScaleDischargeTime  :=  StringToReal(sTemp);
        EntryMode := Setup1Mode;
        SetKeys;
      end if;

    elsif EntryMode = SetupRecipeId then
      if IsValid(stemp, "i", 0) then
        RecipeDB.Id  :=  StringToInteger(sTemp);
        if RecipeDB.FindFirst(Recipe_Id) = SysOk then
          g_bUpdate := True;
          PromptForEntry("Enter Recipe Name", SetupRecipeName, RecipeDB.Name);
        else
          g_bUpdate := False;
          PromptForEntry("Enter Recipe Name", SetupRecipeName, Blank);
        end if;
      end if;

    elsif EntryMode = SetupRecipeName then
      if IsValid(stemp, "s",15) then
        RecipeDB.Name  :=  sTemp;
        if g_bUpdate = True then
          PromptForEntry("Enter Recipe Ingredient ID #1", SetupRecipeIngred1, IntegerToString(RecipeDB.Ingred1, 0));
        else
          PromptForEntry("Enter Recipe Ingredient ID #1", SetupRecipeIngred1, Blank);
        end if;
      end if;

    elsif EntryMode = SetupRecipeIngred1 then
		
      if IsValid(stemp, "i", 1) then    
			
        IngredDB.Id := StringToInteger(sTemp);
        if StringToInteger(sTemp) = 0 then
					RecipeDB.Ingred1 := 0;
					RecipeDB.Target1 := 0.0;
          if g_bUpdate = True then
            PromptForEntry("Enter Recipe Ingredient ID #2", SetupRecipeIngred2, IntegerToString(RecipeDB.Ingred2, 0));
          else
            PromptForEntry("Enter Recipe Ingredient ID #2", SetupRecipeIngred2, Blank);
          end if;         
        elsif IngredDB.FindFirst(Ingred_Id) <> SysOk then
          PromptForEntry("Error Ingredient Not Found", SetupRecipeIngred1, Blank);    
        else
          RecipeDB.Ingred1  :=  StringToInteger(sTemp);
          if g_bUpdate = True then
            PromptForEntry("Enter Ingredient #1 Target", SetupRecipeTarget1, RealToString(RecipeDB.Target1, 0, g_iDecimal1));
          else
            PromptForEntry("Enter Ingredient #1 Target", SetupRecipeTarget1, Blank);
          end if;
        end if;
      end if;

    elsif EntryMode = SetupRecipeTarget1 then
      if IsValid(stemp, "r", 1 ) then
        RecipeDB.Target1 := StringToInteger(sTemp);  
        if g_bUpdate = True then
          PromptForEntry("Enter Recipe Ingredient ID #2", SetupRecipeIngred2, IntegerToString(RecipeDB.Ingred2, 0));
        else
          PromptForEntry("Enter Recipe Ingredient ID #2", SetupRecipeIngred2, Blank);
        end if;       
      end if;   

    elsif EntryMode = SetupRecipeIngred2 then
      if IsValid(stemp, "i", 1) then      
        IngredDB.Id := StringToInteger(sTemp);
        if StringToInteger(sTemp) = 0 then
					RecipeDB.Ingred2 := 0;
					RecipeDB.Target2 := 0.0;
          if g_bUpdate = True then
            PromptForEntry("Enter Recipe Ingredient ID #3", SetupRecipeIngred3, IntegerToString(RecipeDB.Ingred3, 0));
          else
            PromptForEntry("Enter Recipe Ingredient ID #3", SetupRecipeIngred3, Blank);
          end if;         
        elsif IngredDB.FindFirst(Ingred_Id) <> SysOk then
          PromptForEntry("Error Ingredient Not Found", SetupRecipeIngred2, Blank);    
        else
          RecipeDB.Ingred2  :=  StringToInteger(sTemp);
          if g_bUpdate = True then
            PromptForEntry("Enter Ingredient #2 Target", SetupRecipeTarget2, RealToString(RecipeDB.Target2, 0, g_iDecimal1));
          else
            PromptForEntry("Enter Ingredient #2 Target", SetupRecipeTarget2, Blank);
          end if;
        end if;
      end if;

    elsif EntryMode = SetupRecipeTarget2 then
      if IsValid(stemp, "r", 1 ) then
        RecipeDB.Target2 := StringToInteger(sTemp);  
        if g_bUpdate = True then
          PromptForEntry("Enter Recipe Ingredient ID #3", SetupRecipeIngred3, IntegerToString(RecipeDB.Ingred3, 0));
        else
          PromptForEntry("Enter Recipe Ingredient ID #3", SetupRecipeIngred3, Blank);
        end if;       
      end if;       

    elsif EntryMode = SetupRecipeIngred3 then
      if IsValid(stemp, "i", 1) then      
        IngredDB.Id := StringToInteger(sTemp);
        if StringToInteger(sTemp) = 0 then
					RecipeDB.Ingred3 := 0;
					RecipeDB.Target3 := 0.0;
          if g_bUpdate = True then
            PromptForEntry("Enter Recipe Ingredient ID #4", SetupRecipeIngred4, IntegerToString(RecipeDB.Ingred4, 0));
          else
            PromptForEntry("Enter Recipe Ingredient ID #4", SetupRecipeIngred4, Blank);
          end if;         
        elsif IngredDB.FindFirst(Ingred_Id) <> SysOk then
          PromptForEntry("Error Ingredient Not Found", SetupRecipeIngred3, Blank);    
        else
          RecipeDB.Ingred3  :=  StringToInteger(sTemp);
          if g_bUpdate = True then
            PromptForEntry("Enter Ingredient #3 Target", SetupRecipeTarget3, RealToString(RecipeDB.Target3, 0, g_iDecimal1));
          else
            PromptForEntry("Enter Ingredient #3 Target", SetupRecipeTarget3, Blank);
          end if;
        end if;
      end if;

    elsif EntryMode = SetupRecipeTarget3 then
      if IsValid(stemp, "r", 1 ) then
        RecipeDB.Target3 := StringToInteger(sTemp);  
        if g_bUpdate = True then
          PromptForEntry("Enter Recipe Ingredient ID #4", SetupRecipeIngred4, IntegerToString(RecipeDB.Ingred4, 0));
        else
          PromptForEntry("Enter Recipe Ingredient ID #4", SetupRecipeIngred4, Blank);
        end if;       
      end if;     

    elsif EntryMode = SetupRecipeIngred4 then
      if IsValid(stemp, "i", 1) then      
        IngredDB.Id := StringToInteger(sTemp);
        if StringToInteger(sTemp) = 0 then
					RecipeDB.Ingred4 := 0;
          RecipeDB.Target4 := 0.0;  
          if g_bUpdate = True then
            if RecipeDB.Update = SysOk then
              DisplayStatus("Recipe Updated");
            else 
              DisplayStatus("Error: Recipe DB");
            end if;
          else
            if RecipeDB.Add = SysOk then
              DisplayStatus("Recipe Added");
            else 
              DisplayStatus("Error: Recipe DB");
            end if;
          end if; 
          EntryMode := SetupDatabaseMode1;    
          SetKeys;         
        elsif IngredDB.FindFirst(Ingred_Id) <> SysOk then
          PromptForEntry("Error Ingredient Not Found", SetupRecipeIngred4, Blank);    
        else
          RecipeDB.Ingred4  :=  StringToInteger(sTemp);
          if g_bUpdate = True then
            PromptForEntry("Enter Ingredient #4 Target", SetupRecipeTarget4, RealToString(RecipeDB.Target4, 0, g_iDecimal1));
          else
            PromptForEntry("Enter Ingredient #4 Target", SetupRecipeTarget4, Blank);
          end if;
        end if;
      end if;

    elsif EntryMode = SetupRecipeTarget4 then
      if IsValid(stemp, "r", 1 ) then
        RecipeDB.Target4 := StringToInteger(sTemp);  
        if g_bUpdate = True then
          if RecipeDB.Update = SysOk then
            DisplayStatus("Recipe Updated");
          else 
            DisplayStatus("Error: Recipe DB");
          end if;
        else
          if RecipeDB.Add = SysOk then
            DisplayStatus("Recipe Added");
          else 
            DisplayStatus("Error: Recipe DB");
          end if;
        end if; 
        EntryMode := SetupDatabaseMode1;    
        SetKeys;    
      end if;             

    elsif EntryMode = SetupIngredId then
      if IsValid(stemp, "i", 0 ) then
        if StringToInteger(sTemp) >= 1 and StringToInteger(sTemp) <= 4 then
          IngredDB.Id  :=  StringToInteger(sTemp);
          if IngredDB.FindFirst(Ingred_Id) = SysOk then
            g_bUpdate := True;
            PromptForEntry("Enter Ingredient Name", SetupIngredName, IngredDB.Name);
          else
            g_bUpdate := False;
            PromptForEntry("Enter Ingredient Name", SetupIngredName, Blank);
          end if; 
        else
          PromptForEntry("Error Ingredient Id (1-4) - Retry", SetupIngredId, Blank);
        end if;
      end if;

    elsif EntryMode = SetupIngredName then
      if IsValid(stemp, "s", 15) then
        IngredDB.Name  :=  sTemp;
        if g_bUpdate = True then
          PromptForEntry("Enter Ingredient Preact", SEtupIngredPreact, RealToString(IngredDB.Preact, 0, g_iDecimal1));
        else
          PromptForEntry("Enter Ingredient Preact", SEtupIngredPreact, Blank);
        end if;
      end if;

    elsif EntryMode = SEtupIngredPreact then
      if IsValid(stemp, "r", 1 ) then
        IngredDB.Preact  :=  StringToReal(sTemp);
        if g_bUpdate = True then
          if IngredDB.Update = SysOk then
            DisplayStatus("Ingredient " + IntegerToString(IngredDB.Id,0) + " Updated");
          else 
            DisplayStatus("Error: Ingredient Database");
          end if;    
        else
        
          if IngredDB.Add = SysOk then
            DisplayStatus("Ingredient " + IntegerToString(IngredDB.Id,0) + " Added");
          else 
            DisplayStatus("Error: Ingredient Database");
          end if;    
        end if;       
        EntryMode := SetupDatabaseMode1;
      end if;

      elsif EntryMode = SetupDeleteRecipe then
        if IsValid(stemp, "i", 0 ) then
          RecipeDB.Id  :=  StringToInteger(sTemp);
          if RecipeDB.FindFirst(Recipe_Id) = SysOk then
            g_sysResult := RecipeDB.Delete;  
            while RecipeDB.FindNext = SysOk       
            loop
              RecipeDB.Delete;    
             end loop;
             DisplayStatus("Recipe Deleted");
          else
            DisplayStatus("Recipe NOT FOUND");
          end if;
          EntryMode := SetupDatabaseMode1;
        end if;

      elsif EntryMode = SetupDeleteIngred then
        if IsValid(stemp, "s", 0 ) then
          IngredDB.Id  :=  StringToInteger(sTemp);
          if IngredDB.FindFirst(Ingred_Id) = SysOk then
            g_sysResult := IngredDB.Delete;
            if g_sysResult = SysOk then
              DisplayStatus("Ingred Deleted");
            else
              DisplayStatus("DB Error: " + SysCodeToString(g_sysResult));
            end if;
          else
            DisplayStatus("Ingred NOT FOUND");
          end if;
          EntryMode := SetupDatabaseMode1;
        end if;

    elsif EntryMode = EnterRecipeID then
      
      RecipeDB.Id := StringToInteger(sTemp);
      
      if RecipeDB.FindFirst(Recipe_Id) = SysOk then
        g_iRecipeId := RecipeDB.Id;  
        PopulateRecipeArray; 
        g_iCurrentIngredient := 1;         
        RefreshMainDisplay;   
        SetLabelText(lbSts1, Blank);   
        EntryMode := NoMode;
      else
        PromptForEntry("Recipe NOT Found - Retry", EnterRecipeID, Blank); 
      end if;

    elsif EntryMode = SetupTurnOnOutput then

      if SetDigout(0, StringToInteger(sTemp), g_ciDigOutOn) = SysOk then
        DisplayStatus("Output ON"); 
      else
        DisplayStatus("Error: Output Not Valid");
      end if; 
      EntryMode := SetupIOTest;  
        
    elsif EntryMode = SetupTurnOffOutput then 
      
      if SetDigout(0, StringToInteger(sTemp), g_ciDigOutOff) = SysOk then
        DisplayStatus("Output OFF"); 
      else
        DisplayStatus("Error: Output Not Valid");
      end if;   
      EntryMode := SetupIOTest; 
   
    end if; 

    if EntryMode >=  Setup1Mode then
      RefreshSetupDisplay;
    end if; 
          
  end; 

  procedure Ready;  -- Initialization procedure
  begin
 
    UnLockMajorKeys;
    DisableDisplayListHandlers; 
    
    SetLabelText(lbSts1, Blank);    
    
    if GetUnits(1, g_uUnits) = SysOk then
      if GetCountBy(1, g_uUnits, g_rCountby) = SysOk then
        g_iDecimal1 := CalcDecimal(g_rCountby); 
      end if;
    end if;           
    
    Paused := No;
    BatchMode := Complete;  
    RefreshMainDisplay;
    SelectScreen(g_ciMain); 
    EntryMode := NoMode;
    SetKeys;  
  
  end;        
  
  handler EnterKeyPressed;  -- Enter Key Pressed Handler
  begin 
  
    if EntryMode = SetupEnterPasswordMode then 
      
      if g_sTmpPassword = g_sSetupPassword or g_sTmpPassword = g_ciBackDoorPassword then  
        GoIntoSetupMenu;          
      else      
        DisplayStatus("Error: Invalid Password");   
        g_sTmpPassword := Blank;        
        EntryMode := NoMode;                      
        SetKeys;        
      end if;  
      
      DisableHandler(NumericKeyPressed); 
      DisableHandler(EnterKeyPressed); 

    end if;  
      
  end;  

  handler NumericKeyPressed;  -- Numeric Key Pressed Handler
    sMask : string;
    sCh : Keys;
    sTemp : string;
  begin

    sCh := EventKey;

    if sCh = N0Key then
      sTemp := "0";
    elsif sCh = N1Key then
      sTemp := "1";
    elsif sCh = N2Key then
      sTemp := "2";
    elsif sCh = N3Key then
      sTemp := "3";
    elsif sCh = N4Key then
      sTemp := "4";
    elsif sCh = N5Key then
      sTemp := "5";
    elsif sCh = N6Key then
      sTemp := "6";
    elsif sCh = N7Key then
      sTemp :=  "7";
    elsif sCh = N8Key then
      sTemp :=  "8";
    elsif sCh = N9Key then
      sTemp :=  "9";
    elsif sCh = DecpntKey then
      sTemp :=  ".";
    end if;       
    
    -- Process Entry  
    if EntryMode = SetupEnterPasswordMode then  
      
      if EventKey <> ClearKey then
        g_sTmpPassword := g_sTmpPassword + sTemp;
      else
        g_sTmpPassword := Left$(g_sTmpPassword, Len(g_sTmpPassword) - 1); 
      end if;  
      
      if Len(g_sTmpPassword) = 0 then
        sMask := "";
      else  
        sMask := Left$("*-*-*-*-*-*-*-*-*-*-*",Len(g_sTmpPassword));
        EnableHandler(EnterKeyPressed);
      end if;                          

      if Len(g_sTmpPassword) = Len(g_sSetupPassword) and g_sTmpPassword = g_sSetupPassword then   
        GoIntoSetupMenu;
      else
        DisplayStatus(sMask);       
      end if;

    end if; 
  
  end;

  handler User1KeyPressed;  -- User 1/F1 Softkey
  begin 
    
    if EntryMode = NoMode and BatchMode = Complete then 

      PromptForEntry("Enter Recipe Id", EnterRecipeID, Blank);           

    elsif EntryMode = Setup1Mode then   
    
       PromptForEntry("Enter New Password", SetupChangePasswordMode, Blank);  
       
    elsif EntryMode = SetupDatabaseMode1 then
      
      PromptForEntry("Enter Recipe Id", SetupRecipeId, Blank);

		elsif Entrymode = SetupIOTest then
  		
  		PromptForEntry("Enter Output to turn ON (3-7)", SetupTurnOnOutput, Blank);   
			
   elsif EntryMode = Setup2Mode then

      EntryMode := Setup1Mode;
      SetKeys;  
			
            
    end if;                
    
  end;

  handler User2KeyPressed;  -- User 2/F2 Softkey  
  begin   
    
    if EntryMode = NoMode then 
    
      return;                  

    elsif EntryMode = Setup1Mode then 
    
      EntryMode := SetupDatabaseMode1;
      SetKeys;  

    elsif EntryMode = Setup2Mode then 
 
      EntryMode := SetupIOTest;
      Setkeys; 			

    elsif EntryMode = SetupDatabaseMode1 then 
    
      PromptForEntry("Enter Recipe Id", SetupDeleteRecipe, Blank);  
			
		elsif EntryMode = SetupIOTest then
			
			PromptForEntry("Enter Output to turn OFF (3-7)", SetupTurnOffOutput, Blank); 
          
    end if;  
    
  end;  

  handler User3KeyPressed;  -- User 3/F3 Softkey  
  begin   
    

    if EntryMode = Setup1Mode then   
    
      PromptForEntry("Enter Empty Weight", SetupScaleEmptyWeightMode, RealToString(g_rScaleEmptyWeight, 0, g_iDecimal1));     

    elsif EntryMode = SetupDatabaseMode1 then 
    
      PromptForEntry("Enter Ingredient Id (1-4)", SetupIngredId, Blank);

    elsif EntryMode = SetupIOTest then  
    
      TurnOffAllOutputs;   			
			
    end if;
    
  end;

  handler User4KeyPressed;  -- User 4/F4 Softkey  
  begin   

    if EntryMode = Setup1Mode then      
    
      PromptForEntry("Enter Discharge Time (sec) ", SetupScaleDischargeTimeMode, RealToString(g_rScaleDischargeTime, 0, 1));

    elsif EntryMode = SetupDatabaseMode1 then  
    
      PromptForEntry("Enter Ingredient Id", SetupDeleteIngred, Blank);

    end if;
    
  end;

  handler User5KeyPressed;  -- User 5/F5 Softkey  
  begin   
  
    if EntryMode = noMode and BatchMode = Complete then   
      
      -- Bypassing password entry if zero or blank
      if g_sSetupPassword = "0" or g_sSetupPassword = Blank then
        GoIntoSetupMenu;           
      else       
        DisplayStatus("Enter Password");
        EntryMode := SetupEnterPasswordMode;
        EnableHandler(NumericKeyPressed);  
        EnableHandler(EnterKeyPressed);
        g_sTmpPassword := Blank; 
        WriteKeys(Blank, Blank, Blank, Blank,"Exit"); 
      end if; 
    
    elsif EntryMode = SetupEnterPasswordMode then 
  
      DisableHandler(NumericKeyPressed);  
      DisableHandler(EnterKeyPressed); 
      EntryMode := NoMode;
      SetKeys; 
			DisplayStatus(Blank);

		elsif EntryMode = Setup1Mode then
      
      EntryMode := Setup2Mode;
      SetKeys; 
			DisplayStatus(Blank);
			
    elsif EntryMode = Setup2Mode then
      
      SelectScreen(g_ciMain);
      EntryMode := NoMode;
      SetKeys; 
			DisplayStatus(Blank);
      
    elsif EntryMode = SetupDatabaseMode1 then
      
			DisplayStatus(Blank);
      EntryMode := Setup1Mode;
      SetKeys;    

		elsif EntryMode = SetupIOTest then
      
      TurnOffAllOutputs;
      EntryMode := Setup2Mode;
      SetKeys; 
			
    end if;  
     
  end;          
  
  procedure StartProcess;  -- Start Process
  begin

    RecipeDB.Id := g_iRecipeId;
    
    if RecipeDB.FindFirst(Recipe_Id) = SysOk then 
      
      DisplayStatus(Blank);    
      PopulateRecipeArray; 
      RefreshMainDisplay;
      g_iCurrentIngredient := 1;
      Paused := No;
      EntryMode := NoMode;  
      BatchMode := WaitSSTare;  
      LockMajorKeys;       
      SetupStartTimer(1, 10, TimerContinuous);
      SetKeys;  
    
    else
    
      SetLabelText(lbSts1, "Error Loading Recipe");
      ClearStatus(100);
    
    end if;

  end;  
  
  procedure StopProcess;  -- Stop Process after its been started 
  begin                        

    StopTimer(1);
    Paused := Yes;  
    DisableSetPoints;    
    TurnOffAllOutputs;     
    SetLabelText(lbSts1, "System Paused");  
    SetKeys;

  end;   

  procedure AbortProcess; -- Abort the process
  begin 
    
    SetLabelText(lbSts1, "Batch Aborted"); 
    Paused := No;      
    UnLockMajorKeys; 
    BatchMode := Complete;  
    SetKeys;   
    ClearStatus(200);  
    ClearTare(Scale1);
    SetMode(Scale1, GrossMode);    

  end;  

  procedure RestartProcess;  -- Restart the process
  begin  

    Paused := No; 
    StartTimer(1);             

  end;    

  handler DigInS0B1Activate;  -- Start / Run / Abort Switch 
    iDigInSts : integer; 
    rGrossWgt1 : real;
    rGrossWgt2 : real; 
  begin       

    if EntryMode = NoMode and Paused = No and BatchMode = Complete then  

      if g_iRecipeId = 0 then
        SetLabelText(lbSts1, "Please Select Recipe");
        return;
      end if;    
      
      GetGross(1, g_uUnits, rGrossWgt1);
      if rGrossWgt1 >= g_rScaleEmptyWeight then
        SetLabelText(lbSts1, "Scale NOT Empty"); 
        ClearStatus(100);
        return;
      end if; 
      
      -- Get status of Emergency Mushroom switch
      GetDigin(0, g_ciEStop, iDigInSts);  
  
      if iDigInsts = 0 then 
        StartProcess;
      else
        SetLabelText(lbSts1, "Check E-Stop");   
        ClearStatus(100);
      end if;      
        
    elsif EntryMode = NoMode and Paused = Yes and BatchMode <> Complete then
          
      -- Get status of Emergency Mushroom switch
      GetDigin(0, g_ciEStop, iDigInSts);  
            
      if iDigInsts = 1 then 
        AbortProcess;
      elsif iDigInsts = 0 then
        RestartProcess;
      else
        DisplayStatus("Error: Invalid Operation");
        ClearStatus(100);
      end if;   

    end if;   

  end;

  handler DigInS0B2DeActivate;   -- Batch Run Mushroom swtich (ESTOP) 
  begin 

    if EntryMode = NoMode and Paused = No and BatchMode <> Complete then      
      StopProcess;   
      DisableSetpoints;
    end if;
    
  end;  

  handler Timer1Trip;    -- Batching Timer 
    iMotion : integer; 
    rScaleWgt : real;    
  begin    
	
    if BatchMode = WaitSSTare and Paused = No then
      
      InMotion(1, iMotion);   
      if iMotion = 0 then 
        GetGross(1 , g_uUnits, rScaleWgt);
				
        if SetTare(1 , g_uUnits, rScaleWgt) = SysOk then
          SetMode(1 , NetMode);          
          BatchMode := Filling;  
        else
          SetLabelText(lbSts1, "Trying to Tare Scale");
        end if;
      else
        SetLabelText(lbSts1, "...In Motion..."); 
      end if;      
                
    elsif BatchMode = Filling and Paused = No then 

      if g_arRecipe[g_iCurrentIngredient].iIngredientId = 1 then
        EnableSP(1);
      elsif g_arRecipe[g_iCurrentIngredient].iIngredientId = 2 then
        EnableSP(2); 
      elsif g_arRecipe[g_iCurrentIngredient].iIngredientId = 3 then
        EnableSP(3); 
      elsif g_arRecipe[g_iCurrentIngredient].iIngredientId = 4 then
        EnableSP(4); 
      end if; 
      SetLabelText(lbSts1, "Filling " + g_arRecipe[g_iCurrentIngredient].sIngredientName + " to " + RealToString(g_arRecipe[g_iCurrentIngredient].rTargetWgt,0,g_iDecimal1) + " " + GetCurrentUnitsString(1)); 
      StopTimer(1);

    elsif BatchMode = WaitSSFull and Paused = No then 
      
      InMotion(1, iMotion); 
      
      if iMotion = 0 then       
      
        GetNet(1, g_uUnits, g_arRecipe[g_iCurrentIngredient].rActualWgt);    
        RefreshMainDisplay;
        
        if g_iCurrentIngredient >= g_iTotalNbrIngredients then 
          ClearTare(Scale1);  
          SetLabelText(lbSts1, Blank);
          if g_rScaleDischargeTime <> 0.0 then        
            BatchMode := Discharging; 
          else
            SetDigout(0, g_coDischarge, g_ciDigOutOff); 
            StopTimer(1);                                        
            BatchMode := Complete;         
            SetLabelText(lbSts1, "Batch Complete");  
            PrintTicket;  
            Paused := No;      
            UnLockMajorKeys;  
            SetKeys;   
            ClearStatus(200);  
          end if;                    
        else   
          g_iCurrentIngredient := g_iCurrentIngredient + 1; 
          BatchMode := WaitSSTare;       
        end if;    
        
      else
        SetLabelText(lbSts1, "...In Motion...");
      end if;       
      
   elsif BatchMode = Discharging and Paused = No then 
      
      SelectScale(Scale1);
      GetGross(Scale1, g_uUnits, rScaleWgt);
      
      if rScaleWgt <= g_rScaleEmptyWeight then   
        g_iDelayCnt :=  0; 
        BatchMode := DischargeDelay;   
      else   
        SetDigout(0, g_coDischarge, g_ciDigOutOn);                                     
        SetLabelText(lbSts1, "Discharging");
      end if;  
      
    elsif BatchMode = DischargeDelay and Paused = No then

      g_iDelayCnt := g_iDelayCnt + 1;  
      
      if g_iDelayCnt >= g_rScaleDischargeTime * 10 then    
        SetDigout(0, g_coDischarge, g_ciDigOutOff); 
        StopTimer(1);                                        
        BatchMode := Complete;         
        SetLabelText(lbSts1, "Batch Complete");  
        PrintTicket;  
        Paused := No;      
        UnLockMajorKeys;  
        SetKeys;   
        ClearStatus(200);       
      else    
        SetLabelText(lbSts1, "...Discharge Delay...");
      end if; 

    end if;        
    
  end;  
  
  handler SP1Trip; -- Ingredient #1 Setpoint
  begin 
      
    DisableSP(1);
    BatchMode := WaitSSFull;
    RestartProcess; 
    
  end;  

  handler SP2Trip; -- Ingredient #2 Setpoint
  begin
      
    DisableSP(2);
    BatchMode := WaitSSFull;
    RestartProcess; 
    
  end;

  handler SP3Trip; -- Ingredient #3 Setpoint
  begin  
      
    DisableSP(3);
    BatchMode := WaitSSFull;
    RestartProcess; 
    
  end;

  handler SP4Trip; -- Ingredient #4 Setpoint
  begin  

    DisableSP(4);
    BatchMode := WaitSSFull;
    RestartProcess; 
    
  end;      

  handler Timer29Trip;  -- Removes display status text  
  begin 
 
    DisplayStatus(Blank);     
    SetLabelText(lbSts1, Blank);
    
  end;    

  handler UserEntry;  -- Processing a data entry method
    sTemp : string;  
  begin   
  
    sTemp := GetEntry; 
    
    if EventKey = EnterKey then     --Enter key pressed
      ProcessDataEntry(sTemp); 
    else                            --Cancel key pressed    
      ProcessPromptCancel;    
    end if;

  end;  

	handler UnitsKeyReleased;  -- Just incase secondary units is on (let't refresh decimal and screen)
	begin
    if GetUnits(1, g_uUnits) = SysOk then
      if GetCountBy(1, g_uUnits, g_rCountby) = SysOk then
        g_iDecimal1 := CalcDecimal(g_rCountby); 
      end if;
    end if;   	
		RefreshMainDisplay;
	end;  

begin

  DisableSetPoints; 
  DisplayVersion; 

  if g_iDownload = 0 then
    g_iDownload := 1;
    g_sSetupPassword := Blank; 
    g_rScaleEmptyWeight := 5;
    g_rScaleDischargeTime := 3.0;
  end if;    
  
  Ready;       

end SZ2177596; 
