
------------------------------------------------------------------------------
-- Program Name: CheckWeigher
-- The 1280 Checkweigher application is included with the 1280 standard 
-- firmware and is loaded by importing the application from the Configuration 
-- menu "Import Files".  This application is a static checkweigher with a 
-- stored low and high Weight associated with an ID.  A digital output will 
-- be activated for a set time based on under, accept or over, and stores the 
-- ID, Weight, status (under, accept, over), and time/date in a database.  
-- The Print key can be pressed to Print the last transaction's ID, Weight, 
-- status and time/date.  
------------------------------------------------------------------------------

program Counting; 
 
#include Counting.iri 

  -- Constants and aliases definitions 
  g_csProgName          : constant string  := "Counting"; --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;   

  -- 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;    
  EnterSampleSize         : constant integer := 101; 
  EnterAPW                : constant integer := 102; 
	Sampling								: constant integer := 150; 
	
  -- Setup Modes
  SetupEnterPasswordMode   : constant integer := 999;
  Setup1Mode               : constant integer := 1000; 
    SetupChangePasswordMode  : constant integer := 1100;
      SetupVerifyPasswordMode  : constant integer := 1101;
			SetupClearTransactions  : constant integer := 1230;
    SetupThresholdWeight    : constant integer := 1300;
  Setup2Mode                     : constant integer :=  2000;

  EntryMode : integer; 

  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_sysResult1 : SysCode; 
  g_sysResult2 : SysCode;  
  g_iDebug : integer;
	
	g_iMotionTimeOut : integer;

  type IntArray is array [2] of integer;
  type RealArray is array [2] of real;
  
  g_rAveragePieceWgt : stored real;
  g_iPieces : integer;
	g_iSampleSize : stored integer;
  g_iSampleCounts : integer;
  g_iNbrofSamples : integer;
  ActualNum : integer;
	g_iOldSampleCounts : integer;
	g_rLiveWeight : real;

  g_arLCCC : IntArray;
	g_arLCCD : intArray;
	g_arCapacity : RealArray;

  TransDB : TransDatabase;   
  
  -- 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
      WriteKeys("Sample Size", "Change Scale", "APW", Blank,"Setup Menu"); 
    elsif EntryMode = Setup1Mode then
      WriteKeys("Setup Password", "Clear Transactions", Blank, Blank, "Exit"); 	
		elsif EntryMode = SetupClearTransactions then
			WriteKeys("Yes", Blank, Blank, Blank, "No");
		elsif EntryMode = Sampling then
			WriteKeys(Blank, Blank, Blank, Blank, Blank);
		end if;
  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; 
	
 -----------------------------------------------------------------------------
  --  GetScaleCalibration, Gets the scale calibration information for a
  --  scale.  
  --  var params :  iLCCD, iLCCW, iWVAL.
  -----------------------------------------------------------------------------
  procedure GetScaleInformation(iScale : integer);
  begin
		
    GetLCCC(iScale, g_arLCCC[iScale]);
		GetLCCD(iScale, g_arLCCD[iScale]);		
		GetCapacity(iScale, Primary, g_arCapacity[iScale]);

  end;

  procedure SetupStartTimer(iTimer : integer; iDuration : integer; itmMode : TimerMode);  -- Setup a Timer and Start                                
  begin
  
    SetTimer(iTimer, iDuration);
    SetTimerMode(iTimer, itmMode);
    StartTimer(iTimer);
    
  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;    

  procedure PrintTicket; 
		sUnits : string;
  begin  

    sUnits := GetCurrentUnitsString(1);    

		SetPrintText(1, RealToString(TransDB.Weight,0,g_iDecimal1) + " " + sUnits);
		SetPrintText(2, RealToString(TransDB.APW,0,4) + " " + sUnits);
		SetPrintText(3, IntegerToString(TransDB.Pieces,0));
		SetPrintText(4, Date$(TransDB.DT));
		SetPrintText(5, Time$(TransDB.DT));
		Print(AuxFmt1);
  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;   

  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 RefreshSetupDisplay;  -- Update display screen in setup menu 
    sUnits : string;    
  begin             
    
    sUnits := GetCurrentUnitsString(1);               

    SetLabelText(lbSet1, Blank);  
    SetLabelText(lbSet2, Blank);   
		SetLabelText(lbSet3, Blank);
		
  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 StoreTransaction;
	begin
	
		TransDB.APW := g_rAveragePieceWgt;
		TransDB.Weight := g_rLiveWeight;
		TransDB.Pieces := g_iPieces;
		TransDB.DT := SystemTime;
		g_sysResult1 := TransDB.Add;

	end;  
  
  procedure ProcessPromptCancel;   -- Performs Cancel operation when cancelling a prompt
  begin 
  
    ClosePrompt;  
    UnLockMajorKeys;
    
    
    if EntryMode >= Setup1Mode and EntryMode < Setup2Mode then  
        
			EntryMode := Setup1Mode;  
			
    else    
      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 = EnterAPW then
    
      if IsValid(sTemp, "r", 0) then
      	g_rAveragePieceWgt := StringToReal(sTemp);
				SetLabelText(lblAPW, RealToString(g_rAveragePieceWgt,0,4));
				EntryMode := NoMode;	
			end if;
			
		elsif EntryMode = EnterSampleSize then

			if IsValid(sTemp, "i", 0) then
      	g_iSampleSize := StringToReal(sTemp);
				SetLabelText(lblSam, IntegerToString(g_iSampleSize,0));
				EntryMode := Sampling;	
				SetKeys;
				g_iMotionTimeOut := 0;
    		g_iNbrofSamples := 1;
				g_iSampleCounts := 0;
				g_iOldSampleCounts := 0;				
				SetupStartTimer(1, 1, TimerContinuous);
			end if;

		elsif EntryMode = SetupClearTransactions then
			
			if sTemp = "Y" then
				if TransDB.Clear = SysOk then
				 	DisplayStatus("Transactions Database Cleared");
				else
					DisplayStatus("Error Clearing Transaction Database");
				end if;
			else
				DisplayStatus("Transaction Database NOT Cleared");
			end if;
			EntryMode := Setup1Mode;
			SetKeys;
   
    end if; 

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

  procedure Ready;  -- Initialization procedure
  begin
    
    UnLockMajorKeys;
    DisableDisplayListHandlers; 
		GetScaleInformation(1);
		GetScaleInformation(2);
		SetupStartTimer(2, 10, TimerContinuous);
		SetLabelText(lblSam, IntegerToString(g_iSampleSize,0));
		SetLabelText(lblAPW, RealToString(g_rAveragePieceWgt,0,4));
    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;  

-- -----------------------------------------------------------------------------
--  --  ProcessSampleNumerics, This is used by the NumericKeyPressed handler when
--  --  the sample amount is being entered by the user.
--  -----------------------------------------------------------------------------
--  procedure ProcessSampleNumerics;
--
--    Char : string;
--
--  begin
--
--    if EventKey = N1KEY then
--      Char := "1";
--    elsif EventKey = N2KEY then
--      Char := "2";
--    elsif EventKey = N3KEY then
--      Char := "3";
--    elsif EventKey = N4KEY then
--      Char := "4";
--    elsif EventKey = N5KEY then
--      Char := "5";
--    elsif EventKey = N6KEY then
--      Char := "6";
--    elsif EventKey = N7KEY then
--      Char := "7";
--    elsif EventKey = N8KEY then
--      Char := "8";
--    elsif EventKey = N9KEY then
--      Char := "9";
--    elsif EventKey = N0KEY then
--      Char := "0";
--    end if;
--
--    PromptUser("Sample=>");
--    SetEntry(Char);
--    DisableHandler(NumericKeyPressed);
--    DisableHandler(EnterKeyPressed);
--		EntryMode := NoMode;
--		SetLabelText(lblSam, IntegerToString(Sample,0));
--
--  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;
--			
--		elsif EntryMode = SampleMode then
--
--      ProcessSampleNumerics;
			
    end if; 
  
  end;

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

      PromptForEntry("Enter Sample Size", EnterSampleSize, Blank);         

    elsif EntryMode = Setup1Mode then   
    
       PromptForEntry("Enter New Password", SetupChangePasswordMode, Blank);  
			
   	elsif EntryMode = Setup2Mode then

      EntryMode := Setup1Mode;
      SetKeys;  
			
		elsif EntryMode = SetupClearTransactions then
			
			ProcessDataEntry("Y");
    
    end if;                
    
  end;

  handler User2KeyPressed;  -- User 2/F2 Softkey  
  begin   
    
    if EntryMode = NoMode then 
    
      if SelectScale(CurrentScale + 1) <> SysOk then
        SelectScale(Scale1);
      end if;                 

    elsif EntryMode = Setup1Mode then 
    
		  DisplayStatus("Are You Sure?");
      EntryMode := SetupClearTransactions;
			SetKeys;
          
    end if;  
    
  end;  

  handler User3KeyPressed;  -- User 3/F3 Softkey  
  begin   
    
    if EntryMode = NoMode then   
    
      PromptForEntry("Enter Average Piece Weight", EnterAPW, Blank);   
			
    end if;
    
  end;

  handler User5KeyPressed;  -- User 5/F5 Softkey  
  begin   
  
    if EntryMode = noMode 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
      
      SelectScreen(g_ciMain);
      EntryMode := NoMode;
      SetKeys; 
			DisplayStatus(Blank);
			EnableSP(1);   

		elsif EntryMode = SetupClearTransactions then
			
			ProcessDataEntry("N");			
			
    end if;  
     
  end; 

  -----------------------------------------------------------------------------  
  --  Timer1Trip, collects the samples for determining the apw.
  -----------------------------------------------------------------------------  
  handler Timer1Trip;

    iCurrentCounts : integer;
    rRealCounts : real := 0.0;
    iRoundedCounts : integer;
    iMotion : integer;
    rTareWgt : real;
		rAveragePieceWgt : real;

  begin
		
		GetTare(CurrentScale, Primary, rTareWgt);
    InMotion(CurrentScale, iMotion);    
    
    if iMotion <> 0 then
			
			g_iMotionTimeOut := g_iMotionTimeOut + 1;

      if g_iMotionTimeOut > 4 then
        DisplayStatus("Sample Stopped: Motion");
        StopTimer(1);
        StopTimer(3);
				EntryMode := NoMode;
				SetKeys;
        return;
      end if;

      StopTimer(1);
      SetupStartTimer(3, 100, TimerOneShot);

    end if;
    --
    -- Get the raw count sample and add to the raw counts accumulator.
    -- 
		GetFilteredCount(CurrentScale, iCurrentCounts);
    --
    --  This step is needed to weed out duplicate samples
    --
    if iCurrentCounts <> g_iOldSampleCounts then
      g_iSampleCounts := g_iSampleCounts + iCurrentCounts;
      g_iNbrofSamples := g_iNbrofSamples + 1;
    end if;

    g_iOldSampleCounts := iCurrentCounts;
    --
    --  When the samples collected > 100 then calculate the APW.
    --
    if g_iNbrofSamples >= 100 then

      StopTimer(1);
      --
      -- Convert the samples to an averaged real value
      --
      rRealCounts := (g_iSampleCounts / (g_iNbrofSamples - 1));
      --
      --  Round if necessary.
      --
      iRoundedCounts := rRealCounts;
      if (rRealCounts - iRoundedCounts) > 0.5 then
        iRoundedCounts := iRoundedCounts + 1;
      end if;
      rRealCounts := iRoundedCounts;

      if rTareWgt > 0.0 then
				rAveragePieceWgt := rRealCounts - g_arLCCD[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt / g_arLCCC[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt * g_arCapacity[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt - rTareWgt;
				rAveragePieceWgt := rAveragePieceWgt / g_iSampleSize;
      else          
				rAveragePieceWgt := rRealCounts - g_arLCCD[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt / g_arLCCC[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt * g_arCapacity[CurrentScale];
				rAveragePieceWgt := rAveragePieceWgt / g_iSampleSize;
      end if;
			
			g_rAveragePieceWgt := rAveragePieceWgt;
			SetLabelText(lblAPW, RealToString(g_rAveragePieceWgt,0,4));
			EntryMode := NoMode;
			SetKeys;
			
    end if;
    
  end;
  
  

  -----------------------------------------------------------------------------  
  --  Timer2Trip, Writes data to the count widget.
  -----------------------------------------------------------------------------  
  handler Timer2Trip;

    rRealPieces : real;
    rRealCounts : integer;
    iRangeOk : integer;
    rTareWgt : real;
	  rNetWgt : real;
		
  begin

    rTareWgt := 0.0;
    GetTare(CurrentScale, Primary, rTareWgt);
		GetNet(CurrentScale, Primary, rNetWgt);

    if EntryMode = Sampling then
		
      --  If we're calculating the APW then display this.
      SetLabelText(lbCnt, "Sampling");

    else
      --  Make sure we are not out of range.
      InRange(CurrentScale, iRangeOk);
      
      if iRangeOk = 0 then
        SetLabelText(lbCnt, "XXXXXXX");
      else
        --  Otherwise we can display the pieces.
        if g_rAveragePieceWgt = 0 then
          g_iPieces := 0;
        else
          	--  Get the current weight in filtered counts.
					GetFilteredCount(CurrentScale, rRealCounts);
					
					if rTareWgt > 0.0 then

						rRealPieces := (rRealCounts - g_arLCCD[CurrentScale]);
						rRealPieces := rRealPieces / g_arLCCC[CurrentScale];
						rRealPieces := rRealPieces * g_arCapacity[CurrentScale];
						rRealPieces := rRealPieces - rTareWgt;
						rRealPieces := rRealPieces / g_rAveragePieceWgt;

					else
						
						rRealPieces := (rRealCounts - g_arLCCD[CurrentScale]);
						rRealPieces := rRealPieces / g_arLCCC[CurrentScale];
						rRealPieces := rRealPieces * g_arCapacity[CurrentScale];
						rRealPieces := rRealPieces / g_rAveragePieceWgt;
					
					end if;

          g_iPieces := rRealPieces;
					g_rLiveWeight := rNetWgt;
        
          if rRealPieces - g_iPieces > 0.5 then
            g_iPieces := g_iPieces + 1;
          end if;		
					
				end if;
				
				SetLabelText(lbCnt, IntegerToString(g_iPieces, 0));
	
		end if;
		
	end if;
	
end;

  handler Timer3Trip;
  begin
	
    SetupStartTimer(1, 1, TimerContinuous);
		g_iMotionTimeOut := 0;
    g_iNbrofSamples := 1;
		g_iSampleCounts := 0;
		g_iOldSampleCounts := 0;
    EntryMode := Sampling;
		
  end; 
	
  handler Timer29Trip;  -- Removes display status text  
  begin 
 
    DisplayStatus(Blank);     
    
  end;    
	
	handler PrintKeyPressed;
		iMotion : integer;
	begin
	
		InMotion(CurrentScale, iMotion);
		if iMotion = 0 then 
			StoreTransaction;
			PrintTicket;
			if g_sysResult1 = SysOk then
				DisplayStatus("Transaction Printed & Stored");
			else
				DisplayStatus("DB Error " + SysCodeToString(g_sysResult1));
			end if;
		else
			DisplayStatus("Motion Detected - Try Again");
		end if;
		ClearStatus(100);
		
	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; 

begin
  
  DisplayVersion; 

  if g_iDownload = 0 then
    g_iDownload := 1;
    g_sSetupPassword := Blank; 
  end if;
		
  Ready;   

end Counting; 
