unit ZebraCtrlUnit;

interface
uses
  Classes, SysUtils, SuperObject, SuperXmlParser, CoreScanner_TLB, ActiveX;

type
  TUSB_HOST_MODE = (uhmIBMHID, uhmIBMTT, uhmHIDKB, uhmOPOS, uhmSNAPI_WITH_IMAGING, uhmSNAPI_WITHOUT_IMAGING, uhmCDC);




const
  C_ARR_HOST_MODE_USB : Array[0..7-1] of String = ('XUA-45001-1'
                                                  , 'XUA-45001-2'
                                                  , 'XUA-45001-3'
                                                  , 'XUA-45001-8'
                                                  , 'XUA-45001-9'
                                                  , 'XUA-45001-10'
                                                  , 'XUA-45001-11');

                                                  
  C_OPCODE_GET_VERSION						    	        = $3E8;    //1000
  C_OPCODE_REGISTER_FOR_EVENTS					        = $3E9;    //1001
  C_OPCODE_UNREGISTER_FOR_EVENTS				        = $3EA;    //1002

  C_OPCODE_CLAIM_DEVICE					    	          = $5DC;    //1500
  C_OPCODE_RELEASE_DEVICE						            = $5DD;    //1501

  C_OPCODE_DEVICE_ABORT_MACROPDF			      	  = $7D0;    //2000
  C_OPCODE_DEVICE_ABORT_UPDATE_FIRMWARE  		    = $7D1;    //2001
  C_OPCODE_DEVICE_AIM_OFF					        	    = $7D2;    //2002
  C_OPCODE_DEVICE_AIM_ON			          			  = $7D3;    //2003
  C_OPCODE_DEVICE_ENTER_LOW_POWER_MODE	  		  = $7D4;    //2004
  C_OPCODE_DEVICE_FLUSH_MACROPDF			      	  = $7D5;    //2005
  C_OPCODE_DEVICE_GET_PARAMETERS			      	  = $7D7;    //2007
  C_OPCODE_DEVICE_GET_SCANNER_CAPABILITIES		  = $7D8;    //2008
  C_OPCODE_DEVICE_LED_OFF			        			    = $7D9;    //2009
  C_OPCODE_DEVICE_LED_ON				          		  = $7DA;    //2010
  C_OPCODE_DEVICE_PULL_TRIGGER				      	  = $7DB;    //2011
  C_OPCODE_DEVICE_RELEASE_TRIGGER				        = $7DC;    //2012
  C_OPCODE_DEVICE_SCAN_DISABLE					        = $7DD;    //2013
  C_OPCODE_DEVICE_SCAN_ENABLE					          = $7DE;    //2014
  C_OPCODE_DEVICE_SET_PARAMETER_DEFAULTS	  	  = $7DF;    //2015
  C_OPCODE_DEVICE_SET_PARAMETERS			      	  = $7E0;    //2016
  C_OPCODE_DEVICE_SET_PARAMETER_PERSISTANCE	    = $7E1;    //2017
  C_OPCODE_DEVICE_BEEP_CONTROL					        = $7E2;    //2018
  C_OPCODE_REBOOT_SCANNER				  		          = $7E3;    //2019
  C_OPCODE_DISCONNECT_BT_SCANNER				        = $7E7;    //2023
  C_OPCODE_DEVICE_CAPTURE_IMAGE				          = $BB8;    //3000
  C_OPCODE_DEVICE_ABORT_IMAGE_XFER				      = $BB9;    //3001
  C_OPCODE_DEVICE_CAPTURE_BARCODE				        = $DAC;    //3500
  C_OPCODE_DEVICE_CAPTURE_VIDEO			  	        = $FA0;    //4000

  C_OPCODE_GET_PAIRING_BARCODE			    	      = $3ED;    //1005

  C_OPCODE_RSM_ATTR_GETALL					         	  = $1388;    //5000
  C_OPCODE_RSM_ATTR_GET					           	    = $1389;    //5001
  C_OPCODE_RSM_ATTR_GETNEXT				         	    = $138A;    //5002
  C_OPCODE_RSM_ATTR_GETOFFSET			              = $138B;    //5003
  C_OPCODE_RSM_ATTR_SET					           	    = $138C;    //5004
  C_OPCODE_RSM_ATTR_STORE					         	    = $138D;    //5005
  C_OPCODE_GET_DEVICE_TOPOLOGY			         	  = $138E;    //5006
  C_OPCODE_REFRESH_TOPOLOGY				         	    = $138F;    //5007
  C_OPCODE_UPDATE_DECODE_TONE			         	    = $13BA;    //5050
  C_OPCODE_ERASE_DECODE_TONE				         	  = $13BB;    //5051

  C_OPCODE_START_NEW_FIRMWARE				  	        = $1396;    //5014
  C_OPCODE_UPDATE_ATTRIB_META_FILE				      = $1397;    //5015
  C_OPCODE_DEVICE_UPDATE_FIRMWARE				        = $1398;    //5016
  C_OPCODE_DEVICE_UPDATE_FIRMWARE_FROM_PLUGIN   = $1399;    //5017


  C_OPCODE_DEVICE_SET_SERIAL_PORT_SETTINGS	  	= $17D5;    //6101
  C_OPCODE_SET_ACTION					            	  	= $1770;    //6000
  C_OPCODE_DEVICE_SWITCH_HOST_MODE			      	= $1838;    //6200

  //HID keyboard emulator opcodes
  C_OPCODE_KEYBOARD_EMULATOR_ENABLE			        = $189C;    //6300
  C_OPCODE_KEYBOARD_EMULATOR_SET_LOCALE	    	  = $189D;    //6301
  C_OPCODE_KEYBOARD_EMULATOR_GET_CONFIG	    	  = $189E;    //6302

  //DRIVER ADF COMMANDS
  C_OPCODE_CONFIGURE_DADF					          	  = $1900;    //6400
  C_OPCODE_RESET_DADF						            	  = $1901;    //6401


  //Scale opcodes
  C_OPCODE_SCALE_READ_WEIGHT				           	= $1b58;    //7000
  C_OPCODE_SCALE_ZERO_SCALE				           	  = $1B5A;    //7002
  C_OPCODE_SCALE_SYSTEM_RESET				         	  = $1B67;    //7015

  C_OPCODE_ERROR_OPCODE					             	  = -1;

type
  PRecScannerInfo_Zebra = ^TRecScannerInfo_Zebra;
  TRecScannerInfo_Zebra = record
    ScannerID : String;
    InterfaceType : String;
  end;

  TScannerInfoList_Zebra = class(TList)
  protected
    procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  end;



procedure Open_Zebra;
procedure Close_Zebra;
procedure Discover_Zebra;

function SetEvent_Zebra(const aScannerID : String) : Boolean;
function SwitchHostMode_Zebra(const aScannerID : String; const aHostMode : TUSB_HOST_MODE) : Boolean;


var
  g_CoreScanner : TCCorescanner;
  g_ScannerInfoList_Zebra : TScannerInfoList_Zebra;

implementation

procedure Open_Zebra;
var
  SafeArrBound : SAFEARRAYBOUND;
  pSafeArr : PSafeArray;
  ArrScannerTypes : Array[0..0] of SmallInt;
  aStatus : Integer;
  i : Integer;
begin
  aStatus := 1;

  SafeArrBound.cElements := 1;
  SafeArrBound.lLbound := 0;

  pSafeArr := SafeArrayCreate(VT_I2, 1, SafeArrBound);
  ArrScannerTypes[0] := 1;

  for i:=0 to Length(ArrScannerTypes)-1 do
    SafeArrayPutElement(pSafeArr, i, ArrScannerTypes[i]);

  g_CoreScanner.Open(0, pSafeArr, 1, aStatus);

end;

procedure Close_Zebra;
var
  aStatus : Integer;
begin
  g_CoreScanner.Close(0, aStatus);
end;

procedure Discover_Zebra;
var
  aNUmberOfScanners : SmallInt;
  aStatus : Integer;
  pSafeArr : PSafeArray;
  SafeArrBound : SAFEARRAYBOUND;
  aOutXML : WideString;
  SuperObj : ISuperObject;
  i : Integer;
  pItem : PRecScannerInfo_Zebra;
begin
  SafeArrBound.cElements := 255;
  SafeArrBound.lLbound := 0;
  pSafeArr := SafeArrayCreate(VT_I2, 1, SafeArrBound);

  g_ScannerInfoList_Zebra.Clear;
  g_CoreScanner.GetScanners(aNumberOfScanners, pSafeArr, aOutXML, aStatus);

  SuperObj := XMLParseString(aOutXML, true);

  for i:=0 to aNUmberOfScanners-1 do
  begin
    New(pItem);
    with pItem^ do
    begin
      ScannerID       := SuperObj['scanner.scannerID'].AsString;
      InterfaceType   := SuperObj['scanner.type'].AsString;
    end;
    g_ScannerInfoList_Zebra.Add(pItem);
  end;
end;

{ TScannerInfoList_Zebra }

procedure TScannerInfoList_Zebra.Notify(Ptr: Pointer;
  Action: TListNotification);
begin
  inherited;

  if Action = lnDeleted then
    Dispose(PRecScannerInfo_Zebra(Ptr));
end;

function SetEvent_Zebra(const aScannerID : String) : Boolean;
var
  aInputXML : WideString;
  aOutputXML : WideString;
  aStatus : Integer;
begin
  Result := false;

  if g_ScannerInfoList_Zebra.Count < 1 then
    exit;

  aInputXML := '<inArgs><cmdArgs>';
  // target event count
  aInputXML := aInputXML + '<arg-int>6</arg-int>';
  // target event id 1(SUBSCRIBE_BARCODE)
  aInputXML := aInputXML + '<arg-int>1,2,4,8,16,32</arg-int></cmdArgs></inArgs>';

  g_CoreScanner.ExecCommand(C_OPCODE_REGISTER_FOR_EVENTS, aInputXML, aOutputXML, aStatus);
  Result := true;
end;

function SwitchHostMode_Zebra(const aScannerID : String; const aHostMode : TUSB_HOST_MODE) : Boolean;
var
  aInXML, aOutXML : WideString;
  aStatus : Integer;
begin
  Result := false;

  aInXML := '<inArgs><scannerID>%s</scannerID><cmdArgs><arg-string>%s</arg-string><arg-bool>%s</arg-bool><arg-bool>%s</arg-bool></cmdArgs></inArgs>';
  aInXML := format(aInXML, [aScannerID, C_ARR_HOST_MODE_USB[Ord(aHostMode)], 'FALSE', 'FALSE']);
  g_CoreScanner.ExecCommand(C_OPCODE_DEVICE_SWITCH_HOST_MODE, aInXML, aOutXML, aStatus);
end;


initialization
  g_CoreScanner := TCCoreScanner.Create(nil);
  g_ScannerInfoList_Zebra := TScannerInfoList_Zebra.Create;

finalization
  FreeAndNil(g_ScannerInfoList_Zebra);
  FreeAndNil(g_CoreScanner);


end.

