Index: cprs/branches/tmg-cprs/CPRS-Chart/fImages.pas
===================================================================
--- cprs/branches/tmg-cprs/CPRS-Chart/fImages.pas	(revision 612)
+++ cprs/branches/tmg-cprs/CPRS-Chart/fImages.pas	(revision 729)
@@ -64,6 +64,6 @@
     ThumbsImageList: TImageList;
     CurrentNoteMemo: TMemo;
-    Panel1: TPanel;
-    Splitter1: TSplitter;
+    pnlTop: TPanel;
+    HorizSplitter: TSplitter;
     Splitter2: TSplitter;
     UploadImagesButton: TBitBtn;
@@ -73,7 +73,10 @@
     MemosPanel: TPanel;
     UploadImagesMnuAction: TMenuItem;
-    Panel2: TPanel;
+    pnlBottom: TPanel;
     TabControl: TTabControl;
     WebBrowser: TWebBrowser;
+    AutoScanUpload: TMenuItem;
+    PickScanFolder: TMenuItem;
+    OpenDialog: TOpenDialog;
     procedure mnuChartTabClick(Sender: TObject);
     procedure mnuActNewClick(Sender: TObject);
@@ -89,4 +92,6 @@
       var ImageIndex: Integer);
     procedure TabControlResize(Sender: TObject);
+    procedure EnableAutoScanUploadClick(Sender: TObject);
+    procedure PickScanFolderClick(Sender: TObject);
   private
     ImageInfoList : TList;
@@ -94,4 +99,6 @@
     CurImageToLoad : integer;
     InTimerFn : Boolean;
+    DropBoxDir : string;
+    UseDropBox : boolean;
     procedure EnsureImageListLoaded();
     procedure ClearImageList();
@@ -102,4 +109,5 @@
     procedure UpdateNoteInfoMemo();
     procedure UpdateImageInfoMemo(Rec: TImageInfo);
+    function FileSize(fileName : wideString) : Int64;
   public
     CacheDir : AnsiString;
@@ -107,6 +115,8 @@
     function Decode(input: AnsiString) : AnsiString;
     function Encode(input: AnsiString) : AnsiString;
-    function DownloadFile(FPath,FName,LocalSaveFNamePath: AnsiString): boolean;
-    function UploadFile(LocalFNamePath,FPath,FName: AnsiString): boolean;
+    function DownloadFileViaDropbox(FPath,FName,LocalSaveFNamePath: AnsiString;CurrentImage,TotalImages: Integer): boolean;
+    function DownloadFile(FPath,FName,LocalSaveFNamePath: AnsiString;CurrentImage,TotalImages: Integer): boolean;
+    function UploadFileViaDropBox(LocalFNamePath,FPath,FName: AnsiString;CurrentImage,TotalImages: Integer): boolean;
+    function UploadFile(LocalFNamePath,FPath,FName: AnsiString;CurrentImage,TotalImages: Integer): boolean;
     procedure SplitLinuxFilePath(FullPathName : AnsiString;
                                  var Path : AnsiString;
@@ -114,4 +124,6 @@
     procedure GetImageList();
     procedure NewNoteSelected(EditIsActive : boolean);
+    function CreateBarcode(MsgStr: AnsiString; ImageType: AnsiString): AnsiString;
+    function DecodeBarcode(LocalFNamePath,ImageType: AnsiString): AnsiString;
   published
   end;
@@ -134,6 +146,7 @@
      mshtml,  {//kt added 5-2-05}
      UploadImages, {//kt added 9/25/05}
-     UPloadProgress, {//kt 10-1-05}
-     rHTMLTools, fNotes;  {//kt added 5-27-05 for IsHTMLDocument}
+     //ImageTransferForm, {//kt 10-1-05}
+     uTMGOptions,  //kt 3/10/10
+     rHTMLTools, fNotes, frmImageTransferProgress;  {//kt added 5-27-05 for IsHTMLDocument}
 
 
@@ -146,4 +159,8 @@
     if CurImageToLoad <> -1 then begin //-1 means RPC-> no avail images.
       if CurImageToLoad < ImageInfoList.Count then begin
+        ImageTransferForm.ProgressMsg.Caption := 'Downloading Images';
+        //if ImageTransferForm.Visible = false then begin
+        //   ImageTransferForm.Show;
+        //end;
         DownloadToCache(CurImageToLoad); //Only load 1 image per timer firing.
         SetupTab(CurImageToLoad);
@@ -153,4 +170,7 @@
       end else begin
         timLoadImages.Enabled := false;
+        //ImageTransferForm.ProgressBar.Position := 100;
+        //Sleep(1000);
+        //ImageTransferForm.Hide;
       end;
     end;
@@ -193,4 +213,12 @@
   NullImageName := ExtractFilePath(ParamStr(0)) + 'images\blank.htm';
   if not DirectoryExists(CacheDir) then ForceDirectories(CacheDir);
+
+  UseDropBox := uTMGOptions.ReadBool('Use dropbox directory for transfers',false);
+  DropBoxDir := uTMGOptions.ReadString('Dropbox directory','??');
+  if DropBoxDir='??' then begin  //just on first run.
+    uTMGOptions.WriteBool('Use dropbox directory for transfers',false);
+    uTMGOptions.WriteString('Dropbox directory','');
+  end;
+  AutoScanUpload.Checked := uTMGOptions.ReadBool('Scan Enabled',false);
 end;
 
@@ -206,5 +234,5 @@
 var
   TIUIEN : AnsiString;
-
+                                                          
 begin
   inherited;
@@ -396,65 +424,70 @@
   try
     TIUIEN := IntToStr(frmNotes.lstNotes.ItemID);
-    StatusText('Retrieving images information...');
-    CallV('MAG3 CPRS TIU NOTE', [TIUIEN]);
-    for i:=0 to (RPCBrokerV.Results.Count-1) do begin
-      s :=RPCBrokerV.Results[i];
-      if i=0 then begin
-        if piece(s,'^',1)='0' then break //i.e. abort due to error signal
-        else continue;   //ignore rest of header (record #0)
-      end;
-      Rec := TImageInfo.Create; // ImageInfoList will own this.
-      Rec.LongDesc := nil;
-      Rec.TabIndex := -1;
-      Rec.TabImageIndex := 0;
-      s2 := piece(s,'^',2); if s2='' then s2 := '0'; //IEN
-      Rec.IEN := StrToInt(s2);
-      ImageFPathName := piece(s,'^',3);       //Image FullPath and name
-      ThumbnailFPathName := piece(s,'^',4);   //Abstract FullPath and Name
-      Rec.ShortDesc := piece(s,'^',5);            //SHORT DESCRIPTION field
-      s2 := piece(s,'^',6); if s2='' then s2 := '0'; //PROCEDURE/ EXAM DATE/TIME field
-      Rec.DateTime := s2;
-      s2 := piece(s,'^',7); if s2='' then s2 := '0';  //OBJECT TYPE
-      Rec.ImageType := StrToInt(s2);
-      Rec.ProcName := piece(s,'^',8);                 //PROCEDURE field
-      Rec.DisplayDate := piece(s,'^',9);              //Procedure Date in Display format
-      s2 := piece(s,'^',10); if s2='' then s2 := '0'; //PARENT DATA FILE image pointer
-      Rec.ParentDataFileIEN := StrToInt(s2);
-      Rec.AbsType := piece(s,'^',11)[1];              //the ABSTYPE :  'M' magnetic 'W' worm  'O' offline
-      Rec.Accessibility := piece(s,'^',12)[1];        //Image accessibility   'A' accessable  or  'O' offline
-      s2 := piece(s,'^',13); if s2='' then s2 := '0'; //Dicom Series number
-      Rec.DicomSeriesNum := StrToInt(s2);
-      s2 := piece(s,'^',14); if s2='' then s2 := '0'; //Dicom Image Number
-      Rec.DicomImageNum := StrToInt(s2);
-      s2 := piece(s,'^',15); if s2='' then s2 := '0'; //Count of images in the group, or 1 if a single image
-      Rec.GroupCount := StrToInt(s2);
-
-      SplitLinuxFilePath(ImageFPathName,ServerPathName,ServerFName);
-      Rec.ServerPathName := ServerPathName;
-      Rec.ServerFName := ServerFName;
-      Rec.CacheFName := CacheDir + '\' + ServerFName;
-      SplitLinuxFilePath(ThumbnailFPathName,ServerPathName,ServerFName);
-      Rec.ServerThumbPathName := ServerPathName;
-      Rec.ServerThumbFName := ServerFName;
-      Rec.CacheThumbFName := CacheDir + '\' + ServerFName;
-      ImageInfoList.Add(Rec);  // ImageInfoList will own Rec.
-    end;
-    for i:= 0 to ImageInfoList.Count-1 do begin
-      Rec := TImageInfo(ImageInfoList.Items[i]);
-      ImageIEN := Rec.IEN;
-      CallV('TMG GET IMAGE LONG DESCRIPTION', [ImageIEN]);
-      for j:=0 to (RPCBrokerV.Results.Count-1) do begin
-        if (j>0) then begin
-          if Rec.LongDesc = nil then Rec.LongDesc := TStringList.Create;
-          Rec.LongDesc.Add(RPCBrokerV.Results.Strings[j]);
-        end else begin
-          if RPCBrokerV.Results[j]='' then break;
-        end;
-      end;
-    end;
+
   except
     //Error occurs after note is signed, and frmNotes.lstNotes.ItemID is "inaccessible"
     on E: Exception do exit;
   end;
+  //----MOVED
+  StatusText('Retrieving images information...');
+  CallV('MAG3 CPRS TIU NOTE', [TIUIEN]);
+  for i:=0 to (RPCBrokerV.Results.Count-1) do begin
+    s :=RPCBrokerV.Results[i];
+    if i=0 then begin
+      if piece(s,'^',1)='0' then break //i.e. abort due to error signal
+      else continue;   //ignore rest of header (record #0)
+    end;
+    if Pos('-1~',s)>0 then continue;  //abort if error signal.
+    Rec := TImageInfo.Create; // ImageInfoList will own this.
+    Rec.LongDesc := nil;
+    Rec.TabIndex := -1;
+    Rec.TabImageIndex := 0;
+    s2 := piece(s,'^',2); if s2='' then s2 := '0'; //IEN
+    Rec.IEN := StrToInt(s2);
+    ImageFPathName := piece(s,'^',3);       //Image FullPath and name
+    ThumbnailFPathName := piece(s,'^',4);   //Abstract FullPath and Name
+    Rec.ShortDesc := piece(s,'^',5);            //SHORT DESCRIPTION field
+    s2 := piece(s,'^',6); if s2='' then s2 := '0'; //PROCEDURE/ EXAM DATE/TIME field
+    Rec.DateTime := s2;
+    s2 := piece(s,'^',7); if s2='' then s2 := '0';  //OBJECT TYPE
+    Rec.ImageType := StrToInt(s2);
+    Rec.ProcName := piece(s,'^',8);                 //PROCEDURE field
+    Rec.DisplayDate := piece(s,'^',9);              //Procedure Date in Display format
+    s2 := piece(s,'^',10); if s2='' then s2 := '0'; //PARENT DATA FILE image pointer
+    Rec.ParentDataFileIEN := StrToInt(s2);
+    Rec.AbsType := piece(s,'^',11)[1];              //the ABSTYPE :  'M' magnetic 'W' worm  'O' offline
+    s2 := piece(s,'^',12); if s2='' then s2 :='O';
+    Rec.Accessibility := s2[1];                     //Image accessibility   'A' accessable  or  'O' offline
+    s2 := piece(s,'^',13); if s2='' then s2 := '0'; //Dicom Series number
+    Rec.DicomSeriesNum := StrToInt(s2);
+    s2 := piece(s,'^',14); if s2='' then s2 := '0'; //Dicom Image Number
+    Rec.DicomImageNum := StrToInt(s2);
+    s2 := piece(s,'^',15); if s2='' then s2 := '0'; //Count of images in the group, or 1 if a single image
+    Rec.GroupCount := StrToInt(s2);
+
+    SplitLinuxFilePath(ImageFPathName,ServerPathName,ServerFName);
+    Rec.ServerPathName := ServerPathName;
+    Rec.ServerFName := ServerFName;
+    Rec.CacheFName := CacheDir + '\' + ServerFName;
+    SplitLinuxFilePath(ThumbnailFPathName,ServerPathName,ServerFName);
+    Rec.ServerThumbPathName := ServerPathName;
+    Rec.ServerThumbFName := ServerFName;
+    Rec.CacheThumbFName := CacheDir + '\' + ServerFName;
+    ImageInfoList.Add(Rec);  // ImageInfoList will own Rec.
+  end;
+  for i:= 0 to ImageInfoList.Count-1 do begin
+    Rec := TImageInfo(ImageInfoList.Items[i]);
+    ImageIEN := Rec.IEN;
+    CallV('TMG GET IMAGE LONG DESCRIPTION', [ImageIEN]);
+    for j:=0 to (RPCBrokerV.Results.Count-1) do begin
+      if (j>0) then begin
+        if Rec.LongDesc = nil then Rec.LongDesc := TStringList.Create;
+        Rec.LongDesc.Add(RPCBrokerV.Results.Strings[j]);
+      end else begin
+        if RPCBrokerV.Results[j]='' then break;
+      end;
+    end;
+  end;
+   //----END MOVED
   StatusText('');
 end;
@@ -473,10 +506,10 @@
   ServerPathName := Rec.ServerPathName;
   if not FileExists(Rec.CacheFName) then begin
-    DownloadFile(ServerPathName,ServerFName,Rec.CacheFName);
+    DownloadFile(ServerPathName,ServerFName,Rec.CacheFName,(ImageIndex*2)-1,ImageInfoList.Count*2);
   end;
   ServerFName := Rec.ServerThumbFName;
   ServerPathName := Rec.ServerThumbPathName;
   if not FileExists(Rec.CacheThumbFName) then begin
-    DownloadFile(ServerPathName,ServerFName,Rec.CacheThumbFName);
+    DownloadFile(ServerPathName,ServerFName,Rec.CacheThumbFName,ImageIndex*2,ImageInfoList.Count*2);
   end;
   Application.ProcessMessages;
@@ -502,5 +535,33 @@
 
 
-function TfrmImages.UploadFile(LocalFNamePath,FPath,FName: AnsiString): boolean;
+function TfrmImages.UploadFileViaDropBox(LocalFNamePath,FPath,FName: AnsiString;CurrentImage,TotalImages: Integer): boolean;
+var
+  DropboxFile : AnsiString;
+begin
+  //First copy LocalFileNamePath --> DropBox\FileName
+  DropboxFile := ExcludeTrailingBackslash(DropboxDir) + '\' + FName;
+  if CopyFile(pchar(LocalFNamePath),pchar(DropboxFile),false)=false then begin
+    MessageDlg('Dropbox file transfer failed.  Code='+InttoStr(GetLastError),
+               mtError,[mbOK],0);
+    result := false;
+    exit;
+  end;
+
+  // CallV('TMG UPLOAD FILE DROPBOX', ...);
+  RPCBrokerV.ClearParameters := true;
+  RPCBrokerV.remoteprocedure := 'TMG UPLOAD FILE DROPBOX';
+  RPCBrokerV.param[0].PType := literal;
+  RPCBrokerV.param[0].Value := FPath;
+  RPCBrokerV.Param[1].PType := literal;
+  RPCBrokerV.Param[1].Value := FName;
+  RPCBrokerV.Param[2].PType := literal;
+  RPCBrokerV.Param[2].Value := '1'; //see comments in UploadFile re '1' hardcoding
+
+  RPCBrokerV.Call;  //Move file into dropbox.
+  Result := (Piece(RPCBrokerV.Results[0],'^',1)='1');  //1=success, 0=failure
+end;
+
+
+function TfrmImages.UploadFile(LocalFNamePath,FPath,FName: AnsiString;CurrentImage,TotalImages: Integer): boolean;
 const
   RefreshInterval = 500;
@@ -523,4 +584,8 @@
   result := false;  //default of failure
   if not FileExists(LocalFNamePath) then exit;
+  if UseDropBox then begin
+    Result := UploadFileViaDropBox(LocalFNamePath,FPath,FName,CurrentImage,TotalImages);
+    exit;
+  end;
   try
     InFile := TFileStream.Create(LocalFNamePath,fmOpenRead or fmShareCompat);
@@ -529,8 +594,8 @@
     // the RPC call, and I can't make a progress bar change during that...
     // (or I could, but I'm not going to change the RPC broker...)
-    UploadProgressForm.setMax(InFile.Size);
-    //UploadProgressForm.ResetStartTime;
-    UploadProgressForm.ProgressMsg.Caption := 'Prepairing to upload...';
-    UploadProgressForm.Show;
+    ImageTransferForm.setMax(InFile.Size);
+    //ImageTransferForm.ResetStartTime;
+    ImageTransferForm.ProgressMsg.Caption := 'Preparing to upload...';
+    ImageTransferForm.Show;
     totalReadCount := 0;
   except
@@ -567,5 +632,5 @@
     LocalOutFile.Write(Buffer,ReadCount); //for local copy
     totalReadCount := totalReadCount + ReadCount;
-    UploadProgressForm.updateProgress(totalReadCount);
+    ImageTransferForm.updateProgress(totalReadCount);
     OneLine := '';
     if ReadCount > 0 then begin
@@ -588,5 +653,5 @@
   SavedCursor := Screen.Cursor;
   Screen.Cursor := crHourGlass;
-  UploadProgressForm.ProgressMsg.Caption := 'Uploading file to server...';
+  ImageTransferForm.ProgressMsg.Caption := 'Uploading file to server...';
   Application.ProcessMessages;
 
@@ -595,5 +660,5 @@
   RPCResult := RPCBrokerV.Results[0];
   result := (Piece(RPCResult,'^',1)='1');
-  UploadProgressForm.Hide;
+  ImageTransferForm.Hide;
   if result=false then begin
     Application.MessageBox('Error uploading file','Error');
@@ -606,5 +671,43 @@
 
 
-function TfrmImages.DownloadFile(FPath,FName,LocalSaveFNamePath: AnsiString): boolean;
+function TfrmImages.DownloadFileViaDropbox(FPath,FName,LocalSaveFNamePath: AnsiString;CurrentImage,TotalImages: Integer): boolean;
+var
+  DropboxFile : AnsiString;
+  CurrentFileSize : Integer;
+begin
+  // CallV('TMG DOWNLOAD FILE DROPBOX', ...);
+  RPCBrokerV.ClearParameters := true;
+  RPCBrokerV.remoteprocedure := 'TMG DOWNLOAD FILE DROPBOX';
+  RPCBrokerV.param[0].PType := literal;
+  RPCBrokerV.param[0].Value := FPath;
+  RPCBrokerV.Param[1].PType := literal;
+  RPCBrokerV.Param[1].Value := FName;
+  RPCBrokerV.Param[2].PType := literal;
+  RPCBrokerV.Param[2].Value := '1'; //see comments in UploadFile re '1' hardcoding
+
+  RPCBrokerV.Call;  //Move file into dropbox.
+  Result := (Piece(RPCBrokerV.Results[0],'^',1)='1');  //1=success, 0=failure
+  CurrentFileSize := strtoint(Piece(RPCBrokerV.Results[0],'^',3));  //Piece 3 = file size
+
+  if Result=true then begin
+    DropboxFile := ExcludeTrailingBackslash(DropboxDir) + '\' + FName;
+    if ImageTransferForm.visible = False then ImageTransferForm.show;
+    while FileSize(DropboxFile) <> CurrentFileSize do sleep(1000);   //elh
+    ImageTransferForm.ProgressBar.Max := TotalImages;                //elh
+    ImageTransferForm.ProgressBar.Position := CurrentImage+2;          //elh
+    if TotalImages = (CurrentImage+2) then begin
+       Sleep(1000);
+       ImageTransferForm.hide;
+    end;
+    //Now move DropBox\FileName --> LocalFileNamePath
+    if MoveFile(pchar(DropboxFile),pchar(LocalSaveFNamePath))=false then begin
+      MessageDlg('Dropbox file transfer failed.  Code='+InttoStr(GetLastError),
+                 mtError,[mbOK],0);
+    end;
+  end;
+end;
+
+
+function TfrmImages.DownloadFile(FPath,FName,LocalSaveFNamePath: AnsiString;CurrentImage,TotalImages: Integer): boolean;
 var
   i,count                       : integer;
@@ -621,4 +724,8 @@
   if FileExists(LocalSaveFNamePath) then begin
     DeleteFile(LocalSaveFNamePath);
+  end;
+  if UseDropBox then begin
+    Result := DownloadFileViaDropBox(FPath,FName,LocalSaveFNamePath,CurrentImage,TotalImages);
+    exit;
   end;
   Result := true; //default to success;
@@ -916,4 +1023,196 @@
 end;
 
+function TfrmImages.CreateBarcode(MsgStr: AnsiString; ImageType: AnsiString): AnsiString;
+//Create a local barcode file, in .png format, from MsgStr
+//ImageType is optional, default ='png'.  It should NOT contain '.'
+//Returns file path on local client of new barcode image.
+//Note: this function is not related to uploading or downloading images
+//      to the server for attaching to progress notes.  It is included
+//      in this unit because the functionality used is nearly identical to
+//      the other code.
+  function UniqueFName : AnsiString;
+    var  FName,tempFName : AnsiString;
+         count : integer;
+  begin
+    FName := 'Barcode-Image';
+    count := 0;
+    repeat
+      tempFName := CacheDir + '\' + FName + '.' + ImageType;
+      FName := FName + '1';
+      count := count+1;
+    until (fileExists(tempFName)=false) or (count> 32);
+    result := tempFName;
+  end;
+
+var
+  i,count                       : integer;
+  j                             : word;
+  OutFile                       : TFileStream;
+  s                             : AnsiString;
+  Buffer                        : array[0..1024] of byte;
+  LocalSaveFNamePath            : AnsiString;
+
+begin
+  StatusText('Getting Barcode...');
+  LocalSaveFNamePath := UniqueFName;
+  Result := LocalSaveFNamePath;  //default to success;
+
+  // CallV('TMG BARCODE ENCODE', [MsgStr]);
+  RPCBrokerV.ClearParameters := true;
+  RPCBrokerV.remoteprocedure := 'TMG BARCODE ENCODE';
+  RPCBrokerV.param[0].Value := MsgStr;
+  RPCBrokerV.param[0].PType := literal;
+  RPCBrokerV.Param[1].Value := '.X';  //<-- is this needed or used?
+  RPCBrokerV.Param[1].PType := list;
+  RPCBrokerV.Param[1].Mult['"IMAGE TYPE"'] := ImageType;
+  RPCBrokerV.Call;
+
+  Application.ProcessMessages;
+  //Note:RPCBrokerV.Results[0]=1 if successful load, =0 if failure
+  if (RPCBrokerV.Results.Count>0) and (RPCBrokerV.Results[0]='1') then begin
+    OutFile := TFileStream.Create(LocalSaveFNamePath,fmCreate);
+    for i:=1 to (RPCBrokerV.Results.Count-1) do begin
+      s :=Decode(RPCBrokerV.Results[i]);
+      count := Length(s);
+      if count>1024 then begin
+        Result := ''; //failure of load.
+        break;
+      end;
+      for j := 1 to count do Buffer[j-1] := ord(s[j]);
+      OutFile.Write(Buffer,count);
+    end;
+    OutFile.Free;
+  end else begin
+    result := '';
+  end;
+  StatusText('');
+end;
+
+
+function TfrmImages.DecodeBarcode(LocalFNamePath,ImageType: AnsiString): AnsiString;
+//Decode data from barcode on image, or return '' if none
+//Note: if I could find a cost-effective way of decoding this on client side,
+//      then that code be done here in the function, instead of uploading image
+//      to the server for decoding.
+const
+  RefreshInterval = 500;
+  BlockSize = 512;
+
+var
+  ReadCount                     : Word;
+  ParamIndex                    : LongWord;
+  j                             : word;
+  InFile                        : TFileStream;
+  Buffer                        : array[0..1024] of byte;
+  RefreshCountdown              : integer;
+  OneLine                       : AnsiString;
+  RPCResult                     : AnsiString;
+  SavedCursor                   : TCursor;
+  totalReadCount                : integer;
+begin
+  result := '';  //default of failure
+  if not FileExists(LocalFNamePath) then exit;
+  try
+    InFile := TFileStream.Create(LocalFNamePath,fmOpenRead or fmShareCompat);
+    //Note: I may well cut this out.  Most of the delay occurs during
+    // the RPC call, and I can't make a progress bar change during that...
+    // (or I could, but I'm not going to change the RPC broker...)
+    ImageTransferForm.setMax(InFile.Size);
+    //ImageTransferForm.ResetStartTime;
+    ImageTransferForm.ProgressMsg.Caption := 'Preparing to upload...';
+    ImageTransferForm.Show;
+    totalReadCount := 0;
+  except
+    // catch failure here...  on eError...
+    exit;
+  end;
+
+  StatusText('Checking image for barcodes...');
+  Application.ProcessMessages;
+
+  RPCBrokerV.ClearParameters := true;
+  RPCBrokerV.Param.Clear;
+  RPCBrokerV.Param[0].PType := list;
+  ParamIndex := 0;
+  RefreshCountdown := RefreshInterval;
+  //Put image data into parameter 0 (ARRAY parameter of RPC on server side)
+  repeat
+    ReadCount := InFile.Read(Buffer,BlockSize);
+    OneLine := '';
+    totalReadCount := totalReadCount + ReadCount;
+    ImageTransferForm.updateProgress(totalReadCount);
+    if ReadCount > 0 then begin
+      SetLength(OneLine,ReadCount);
+      for j := 1 to ReadCount do OneLine[j] := char(Buffer[j-1]);
+      RPCBrokerV.Param[0].Mult[IntToStr(ParamIndex)] := Encode(OneLine);
+      Inc(ParamIndex);
+      Dec(RefreshCountdown);
+      if RefreshCountdown < 1 then begin
+        Application.ProcessMessages;
+        RefreshCountdown := RefreshInterval;
+      end;
+    end;
+  until (ReadCount < BlockSize);
+  RPCBrokerV.Param[1].PType := literal;
+  RPCBrokerV.Param[1].Value := ImageType;
+
+  RPCBrokerV.remoteprocedure := 'TMG BARCODE DECODE';
+
+  SavedCursor := Screen.Cursor;
+  Screen.Cursor := crHourGlass;
+  ImageTransferForm.ProgressMsg.Caption := 'Uploading file to server...';
+  Application.ProcessMessages;
+
+  CallBroker;  //this is the slow step, pass to server and get response.
+
+  Screen.Cursor := SavedCursor;
+  ImageTransferForm.Hide;
+  //Get result: 1^DecodedMessage, or 0^Error Message
+  RPCResult := RPCBrokerV.Results[0];
+  if Piece(RPCResult,'^',1)='0' then begin
+    MessageDlg(Piece(RPCResult,'^',2),mtError,[mbOK],0);
+  end else begin
+    result := Piece(RPCResult,'^',2);
+  end;
+
+  InFile.Free;
+  StatusText('');
+end;
+
+
+procedure TfrmImages.EnableAutoScanUploadClick(Sender: TObject);
+begin
+  inherited;
+  AutoScanUpload.Checked := not AutoScanUpload.Checked;
+  uTMGOptions.WriteBool('Scan Enabled',AutoScanUpload.Checked);
+end;
+
+
+procedure TfrmImages.PickScanFolderClick(Sender: TObject);
+var
+  CurScanDir : string;
+begin
+  inherited;
+  CurScanDir := UploadForm.ScanDir;
+  OpenDialog.InitialDir := CurScanDir;
+  MessageDlg('Please pick ANY file in the desired directory.',mtInformation,[mbOK],0);
+  if OpenDialog.Execute then begin
+    UploadForm.SetScanDir(ExtractFilePath(OpenDialog.FileName));
+  end;
+  AutoScanUpload.Checked := true;
+end;
+
+function TfrmImages.FileSize(fileName : wideString) : Int64;
+var
+  sr : TSearchRec;
+begin
+  if FindFirst(fileName, faAnyFile, sr ) = 0 then
+     result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) +  Int64(sr.FindData.nFileSizeLow)
+  else
+     result := -1;
+
+  FindClose(sr) ;
+end;
+
 initialization
   //put init code here
