
------------------------------------------------------------------------------
-- 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 CheckWeighing; 
 
#include CheckWeighing.iri 

  -- Constants and aliases definitions 
  g_csProgName          : constant string  := "Checkweighing"; --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;   
  
  -- Inputs/Outputs  
  g_coUnder   : constant integer := 1;
  g_coAccept  : constant integer := 2;  
  g_coOver    : constant integer := 3;

  -- 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;    
  EnterItemID             : 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;  
      SetupItemId               : constant integer := 1210;
        SetupItemName             : constant integer := 1211;
        SetupItemLowWeight        : constant integer := 1212;
        SetupItemHighWeight       : constant integer := 1213;               
      SetupDeleteItem         : constant integer := 1220;
			SetupClearTransactions  : constant integer := 1230;
    SetupThresholdWeight    : constant integer := 1300;
  Setup2Mode                     : constant integer :=  2000;
    SetupIOTest              : constant integer := 2200; 
      SetupTurnOnOutput        : constant integer := 2210; 
      SetupTurnOffOutput       : constant integer := 2220; 	

  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_sItemId : stored string;   
  g_sItemName : stored string;  
  g_rLowWeight : stored real;
  g_rHighWeight : stored real;     
  g_iAutoPrint : stored real;
  g_rThresholdWeight : stored real;
       
  ItemDB : ItemDatabase;
  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("Item", Blank, Blank, Blank,"Setup Menu"); 
    elsif EntryMode = Setup1Mode then
      WriteKeys("Setup Password", "Database Setup", "Threshold Weight", "Auto Print", "More=>");
		elsif EntryMode = Setup2Mode then
			WriteKeys("<=Back", "IO Test Screen", Blank, Blank, "Exit");
    elsif EntryMode = SetupDatabaseMode1 then
      WriteKeys("Add/Edit Items" ,"Delete Item", "Clear Transactions", Blank, "Exit");         
    elsif EntryMode = SetupIOTest then
      WriteKeys("Turn ON Output" ,"Turn OFF Output", "Turn OFF ALL Outputs", Blank, "Exit");  	
		elsif EntryMode = SetupClearTransactions then
			WriteKeys("Yes", Blank, Blank, Blank, "No");
		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);
    
  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, TransDB.ItemId);
		SetPrintText(2, TransDB.ItemName);
		SetPrintText(3, RealToString(TransDB.Weight,0,g_iDecimal1) + " " + sUnits);
		SetPrintText(4, TransDB.Status);
		SetPrintText(5, Date$(TransDB.DT));
		SetPrintText(6, 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;   
  
  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 := 1 to 3
    loop
      SetDigout(0, i, g_ciDigOutOff);
    end loop;  
  
  end;     
  
  procedure RefreshSetupDisplay;  -- Update display screen in setup menu 
    sUnits : string;    
  begin             
    
    sUnits := GetCurrentUnitsString(1);               

    SetLabelText(lbSet1, "Threshold Weight: " + RealToString(g_rThresholdWeight,0,g_iDecimal1) + " " + sUnits);  
    if g_iAutoPrint = 1 then
      SetLabelText(lbSet2, "Auto Print: ON");   
    else
      SetLabelText(lbSet2, "Auto Print: OFF");  
    end if;
		SetLabelText(lbSet3, Blank);
		
  end; 
  
  procedure RefreshMainDisplay; 
    sUnits : string;      
  begin
		
		if g_sItemId <> Blank then
    
    	sUnits := GetCurrentUnitsString(1);

    	SetLabelText(lbId, g_sItemId + " " +  g_sItemName); 
    	SetLabelText(lbLow, RealToString(g_rLowWeight,0,g_iDecimal1) + " " + sUnits);      
    	SetLabelText(lbHigh, RealToString(g_rHighWeight,0,g_iDecimal1) + " " + sUnits);
		
		else

    	SetLabelText(lbId, Blank); 
    	SetLabelText(lbLow, Blank);      
    	SetLabelText(lbHigh, Blank);
			
		end if;
  
  end;
  
  procedure GoIntoSetupMenu;  -- Enters Setup Menu
  begin
 
    DisableSetPoints;
    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(rWeight : real);
	begin
	
		TransDB.ItemId := g_sItemId;
		TransDB.ItemName := g_sItemName;
		TransDB.Weight := rWeight;
		TransDB.DT := SystemTime;

		g_sysResult1 := TransDB.Add;
		if g_sysResult1 <> SysOk then
			DisplayStatus("DB Error " + SysCodeToString(g_sysResult1));
		end if;
		
	end;  
  
  procedure ProcessPromptCancel;   -- Performs Cancel operation when cancelling a prompt
  begin 
  
    ClosePrompt;  
    UnLockMajorKeys;
    
    
    if EntryMode >= Setup1Mode and EntryMode < Setup2Mode then 

      if EntryMode = SetupThresholdWeight or EntryMode = SetupChangePasswordMode or EntryMode = SetupVerifyPasswordMode then  
        EntryMode := Setup1Mode;  
      else
        EntryMode := SetupDatabaseMode1; 
        SetKeys;
      end if;
			
		elsif EntryMode = SetupTurnOnOutput or EntryMode = SetupTurnOffOutput then
			
			EntryMode := SetupIOTest;
			
    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 = SetupThresholdWeight then
      if IsValid(stemp, "r", 1) then
        g_rThresholdWeight := StringToInteger(sTemp);  
    		SetSPValue(1, g_rThresholdWeight);
    		SetSPValue(2, g_rThresholdWeight);  
				EntryMode := Setup1Mode;
      end if;   

    elsif EntryMode = SetupItemId then
      if IsValid(stemp, "s", 15) then
        ItemDB.Id  :=  sTemp;
        if ItemDB.FindFirst(Item_Id) = SysOk then
          g_bUpdate := True;
          PromptForEntry("Enter Item Name", SetupItemName, ItemDB.Name);
        else
          g_bUpdate := False;
          PromptForEntry("Enter Item Name", SetupItemName, Blank);
        end if;
      end if;

    elsif EntryMode = SetupItemName then
      if IsValid(stemp, "s",15) then
        ItemDB.Name  :=  sTemp;
        if g_bUpdate = True then
          PromptForEntry("Enter Item Low Weight", SetupItemLowWeight, RealToString(ItemDB.Low,0,g_iDecimal1));
        else
          PromptForEntry("Enter Item Low Weight", SetupItemLowWeight, Blank);
        end if;
      end if;

    elsif EntryMode = SetupItemLowWeight then
      if IsValid(stemp, "r", 1) then
        ItemDB.Low := StringToInteger(sTemp);  
        if g_bUpdate = True then
          PromptForEntry("Enter Item High Weight", SetupItemHighWeight, RealToString(ItemDB.High,0,g_iDecimal1));
        else
          PromptForEntry("Enter Item High Weight", SetupItemHighWeight, Blank);
        end if;       
      end if;   

    elsif EntryMode = SetupItemHighWeight then
      if IsValid(stemp, "r", 1 ) then 
        if StringToReal(sTemp) > ItemDB.Low then
          ItemDB.High := StringToInteger(sTemp);  
          if g_bUpdate = True then
            if ItemDB.Update = SysOk then
              DisplayStatus("Item Updated");
            else 
              DisplayStatus("Error: Item DB");
            end if;
						-- If Item selected was updated were updating screen
						if ItemDB.Id = g_sItemId then 
        			g_sItemId := ItemDB.Id;    
        			g_sItemName := ItemDB.Name;
        			g_rLowWeight := ItemDB.Low;
        			g_rHighWeight := ItemDB.High;    
        			RefreshMainDisplay;   
        			SetLabelText(lbSts1, Blank);  	
						end if;						
          else
            if ItemDB.Add = SysOk then
              DisplayStatus("Item Added");
            else 
              DisplayStatus("Error: Item DB");
            end if;
          end if; 				
          EntryMode := SetupDatabaseMode1;    
          SetKeys;      
        else
          PromptForEntry("Error High < Low", SetupItemHighWeight, Blank);
        end if; 
      end if;       

    elsif EntryMode = SetupDeleteItem then
      ItemDB.Id := sTemp;
      if ItemDB.FindFirst(Item_Id) = SysOk then
        if ItemDB.Delete = SysOk then    
          DisplayStatus("Item Deleted"); 
        else  
          DisplayStatus("Error: Item DB");
        end if;
				
				-- If Item selected was updated were updating screen
				if ItemDB.Id = g_sItemId then 
        	g_sItemId := Blank;    
        	g_sItemName := Blank;
        	g_rLowWeight := 0.0;
        	g_rHighWeight := 0.0;    
        	RefreshMainDisplay;   
        	SetLabelText(lbSts1, Blank);  	
				end if;	
				
      else
        DisplayStatus("Item NOT FOUND");
      end if;
      EntryMode := SetupDatabaseMode1;

    elsif EntryMode = EnterItemID then
      
      ItemDB.Id := sTemp;
      
      if ItemDB.FindFirst(Item_Id) = SysOk then
        g_sItemId := ItemDB.Id;    
        g_sItemName := ItemDB.Name;
        g_rLowWeight := ItemDB.Low;
        g_rHighWeight := ItemDB.High;    
        RefreshMainDisplay;   
        SetLabelText(lbSts1, Blank);   
        EntryMode := NoMode;
      else
        PromptForEntry("Item NOT Found - Retry", EnterItemID, 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; 
			
		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 := SetupDatabaseMode1;
			SetKeys;
   
    end if; 

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

  procedure Ready;  -- Initialization procedure
  begin
    
    UnLockMajorKeys;
    DisableDisplayListHandlers; 
    
    SetLabelText(lbSts1, Blank);    
		SetLabelText(lbAOU, 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;           
	
    RefreshMainDisplay;
    SelectScreen(g_ciMain);  
    SetSPValue(1, g_rThresholdWeight);
    SetSPValue(2, g_rThresholdWeight);
		EnableSP(1);
    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  then 

      PromptForEntry("Enter Id to Checkweigh", EnterItemID, Blank);           

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

		elsif Entrymode = SetupIOTest then
  		
  		PromptForEntry("Enter Output to turn ON (1-3)", SetupTurnOnOutput, 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 
    
      return;                  

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

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

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

  handler User3KeyPressed;  -- User 3/F3 Softkey  
  begin   
    

    if EntryMode = Setup1Mode then   
    
      PromptForEntry("Enter Threshold Weight", SetupThresholdWeight, RealToString(g_rThresholdWeight, 0, g_iDecimal1));     

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

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

  handler User4KeyPressed;  -- User 4/F4 Softkey  
  begin   

    if EntryMode = Setup1Mode then       

		  if g_iAutoPrint = 1 then
        g_iAutoPrint := 0;
      else        
        g_iAutoPrint := 1;
      end if;
      RefreshSetupDisplay; 	

    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
      
      EntryMode := Setup2Mode;
      SetKeys; 
			DisplayStatus(Blank);
			
    elsif EntryMode = Setup2Mode then
      
      SelectScreen(g_ciMain);
      EntryMode := NoMode;
      SetKeys; 
			DisplayStatus(Blank);
			EnableSP(1);
      
    elsif EntryMode = SetupDatabaseMode1 then
      
			DisplayStatus(Blank);
      EntryMode := Setup1Mode;
      SetKeys;    

		elsif EntryMode = SetupIOTest then
      
      TurnOffAllOutputs;
      EntryMode := Setup2Mode;
      SetKeys; 

		elsif EntryMode = SetupClearTransactions then
			
			ProcessDataEntry("N");			
			
    end if;  
     
  end;   
  
  handler Timer25Trip;  -- Wait for Standstill check
    iMotion : integer;   
    rNetWgt : real;
		iInRange : integer;
  begin 

    -- Make sure Item selected
    if g_sItemId = Blank then  
      return;
    end if;		 

    InMotion(1, iMotion);
    
    if iMotion = 0 then  
    
      StopTimer(25);
      DisplayStatus(Blank);  
      SetLabelText(lbSts1,  Blank); 
      
      GetUnits(1, g_uUnits);
      g_sysResult1 := GetNet(1, g_uUnits, rNetWgt); 
  		g_sysResult2 := InRange(1, iInRange);   
  
  		-- Get Net Command
      if g_sysResult1 <> SysOk then
        SetLabelText(lbSts1, "Scale Error: " + SysCodeToString(g_sysResult1));  
  		  return;
      end if;
  		
  		-- Check In Range
      if g_sysResult2 <> SysOk then
        SetLabelText(lbSts1, "Scale Error: " + SysCodeToString(g_sysResult2));  
  		  return;
      end if;			
    	
      -- Validate InRage
      if iInRange = 0 then  
        SetLabelText(lbSts1, "Scale NOT In Range");  
        return;
      end if;  
                        
      if rNetWgt < g_rLowWeight then                       
        SetLabelText(lbAOU, "UNDER");
				SetWidgetColor(lbAOU, "Orange"); 
				SetDigout(0, g_coUnder, g_ciDigOutOn);
				SetBargraphLevel(BarO, 0);
				SetBargraphLevel(BarA, 0);
				SetBargraphLevel(BarU, 100);
				TransDB.Status := "UNDER";
      elsif rNetWgt > g_rHighWeight then
        SetLabelText(lbAOU, "OVER");
				SetWidgetColor(lbAOU, "Red"); 
				SetDigout(0, g_coOver, g_ciDigOutOn);
				TransDB.Status := "OVER";
				SetBargraphLevel(BarO, 100);
				SetBargraphLevel(BarA, 0);
				SetBargraphLevel(BarU, 0);			
      else
        SetLabelText(lbAOU, "ACCEPTED");
				SetWidgetColor(lbAOU, "Green"); 	
				SetDigout(0, g_coAccept, g_ciDigOutOn);
				TransDB.Status := "ACCEPTED";
				SetBargraphLevel(BarO, 0);
				SetBargraphLevel(BarA, 100);
				SetBargraphLevel(BarU, 0);			
      end if; 
			
			StoreTransaction(rNetWgt);
			
			if g_iAutoPrint = 1 then
				PrintTicket;
			end if;
			
		end if; 
 
  end;       

  handler SP1Trip; -- Item Above Threshold
  begin 

    DisableSP(1);   
    SetupStartTimer(25, 5, TimerContinuous); 
    EnableSP(2);
    
  end;  

  handler SP2Trip; -- Item Dropped below Threshold
  begin

    DisableSP(2);
    StopTimer(25);  
		TurnOffAllOutputs;
		SetBargraphLevel(BarO, 0.0);
		SetBargraphLevel(BarA, 0.0);
		SetBargraphLevel(BarU, 0.0);			
    SetLabelText(lbSts1, Blank);
		SetLabelText(lbAOU, Blank);	
    EnableSP(1);
 
  end;   

  handler Timer29Trip;  -- Removes display status text  
  begin 
 
    DisplayStatus(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_rThresholdWeight := 10;
    g_iAutoPrint := 1;
  end if;    
  
  Ready;       

end SZ2177596; 
