 constructor THeoEMPVytezovaniDokThread.Create (AOnTerminate: TNotifyEvent; AService: TService);
  begin
   inherited Create (false);          // Create thread in NOT suspended mode
   FMainService:= AService;
   FLock:= TCriticalSection.Create;
   FRunning:= false;
   FTermEvent:= TEvent.Create (nil, False, False, '');

//   OnTerminate:= AOnTerminate;
//   FreeOnTerminate:= true;
   FreeOnTerminate:= false;          // Ensure manual freeing of thread resources
  end;




 destructor THeoEMPVytezovaniDokThread.Destroy;
  begin
{$IFDEF DEBUG}
   Write('Ukoncuji thread EMP vytezovani dokumentu...');
{$ENDIF}
   if (FTimer<>0) then
    CloseHandle (FTimer);
   FTermEvent.Free;
   FRunning:= false;
   FMainService:= nil;
   Terminate;
   FLock.Free;
   inherited;
{$IFDEF DEBUG}
   WriteLn('OK');
{$ENDIF}
  end;



 procedure THeoEMPVytezovaniDokThread.TerminatedSet;
  begin
   FTermEvent.SetEvent;
  end;



 procedure THeoEMPVytezovaniDokThread.ThreadTerminate;
  begin
   Terminate;
   WaitFor;
  end;



 procedure THeoEMPVytezovaniDokThread.Execute;
  const _Second = 10_000_000;
  var lSQL, errMsg, url, authHash, outData, fName, loopCasTyp: string;
      lLoop, idDZ, cnt, idx: Integer;
      lLoopMax, koefProCas: integer;
      logRunCnt: integer;
      Msg: TMsg;
      firstRun, inProg, inDL: boolean;
      lQry, lQry2: TFDQuery;
      sqlConnX, sqlConnX2: TFDConnection;
      sqlTrans: IFDPhysTransaction;
      f, lOpenSSLLib: string;

      lBusy: LongInt;
      liDueTime: LARGE_INTEGER;

      mamSSLLibs: boolean;
      sslLibPath, dataSouboru: string;
      http1: System.Net.HTTPClient.THTTPClient;
      iResp: System.Net.HTTPClient.IHTTPResponse;
      aResp: TMemoryStream;
      http2: TIdHttp;
      sslHndlr: TIdSSLIOHandlerSocketOpenSSL;
      respHttp2: TStream;
      i: integer;
      sTemp, outData2: string;

      cfgFile: string;
      specCfgXML: XML.XmlIntf.IXMLDocument;
      n1: XML.XmlIntf.IXMLNode;
      attribs: IXMLNodeList;
      attrIdx: integer;

    function StringToHex (const inStr: string): string;
     var i: integer;
     begin
      result:= '';
      for i:=1 to Length(inStr) do
       result:= result + IntToHex(Ord(inStr[i]), 2); // 2 means two hex digits per character
     end;

   function MemStreamToHex (aStream: TMemoryStream): string;
    var i: integer;
        b: byte;
    begin
     result:= '';
     for i:=0 to aStream.Size-1 do
      begin
       b:= PByte(TMemoryStream(aStream).Memory)[i];
       result:= result + IntToHex(b,2);
      end;
    end;

  begin
   lLoop:= 0;
   idDZ:= 0;
   logRunCnt:= 1;
   url:= '';
   authHash:= '';
   lLoopMax:= 20; // v sekundach !!!!

   try
     try
       CoInitialize(nil); // kvuli pouziti TXMLDocument

       cfgFile:= ExtractFilePath(ParamStr(0)) + 'empolar.xml';
       if (FileExists(cfgFile)) then
        begin
         specCfgXML:= Xml.XMLDoc.TXMLDocument.Create(nil);
         specCfgXML.LoadFromFile (cfgFile);
         specCfgXML.Active:= true;
         if not(specCfgXML.IsEmptyDoc) then
          begin
           if (specCfgXML.DocumentElement<>nil) then
            begin
             n1:= specCfgXML.DocumentElement;
             if (n1.NodeName='config_aidocu') then
              begin
               attribs:= n1.AttributeNodes;
               attrIdx:= attribs.IndexOf('vytezovaniDokumentuSek');
               if (attrIdx>-1) then
                if (attribs.Get(attrIdx).NodeValue<>null) then
                 lLoopMax:= attribs.Get(attrIdx).NodeValue;

               attrIdx:= attribs.IndexOf('url');
               if (attrIdx>-1) then
                if (attribs.Get(attrIdx).NodeValue<>null) then
                 url:= attribs.Get(attrIdx).NodeValue;

               attrIdx:= attribs.IndexOf('auth');
               if (attrIdx>-1) then
                if (attribs.Get(attrIdx).NodeValue<>null) then
                 authHash:= attribs.Get(attrIdx).NodeValue;
{$IFDEF DEBUG}
               if (Length(authHash)<350) then
                begin
                 authHash:= (FMainService as THDCDZApiService).ReturnEncrypted (authHash);
                 WriteLn('API HASH: ' + authHash);
                end;
{$ENDIF}
               if (authHash<>'') and (FMainService<>nil) then
                authHash:= (FMainService as THDCDZApiService).ReturnDecrypted (authHash);
              end; // n1 = config
            end; // specCfgXML.DocumentElement<>nil
          end; // not specCfgXML.IsEmptyDoc
        end; // FileExists(cfgFile)
      except
     end; // try

    finally
     begin
      if (specCfgXML<>nil) then
       specCfgXML:= nil;
      CoUninitialize;
     end;
   end;

   
   datMod.LogInfo (Quick.Logger.etInfo, 'Interval vytezovani dokumentu: ' + lLoopMax.ToString + ' sek');

   firstRun:= true;
   inProg:= false;

   sslLibPath:= '';
   f:= ExtractFilePath (ParamStr(0));
   mamSSLLibs:= false;
   for lOpenSSLLib in OPENSSL_LIBS do
    begin
     if (FileExists(TPath.Combine(f, lOpenSSLLib))) then
      begin
       mamSSLLibs:= true;
       sslLibPath:= ExcludeTrailingPathDelimiter (f);
      end;
    end;

   FRunning:= true;

   if (1=1) then // pro rychle vypnuti
    begin
     FTimer:= CreateWaitableTimer (nil, true, 'EMPVytezDokumWaitableTimer');
     liDueTime.QuadPart:= -1*_Second;


     sqlConnX:= TFDConnection.Create (nil);
     sqlConnX2:= TFDConnection.Create (nil);
     lQry:= TFDQuery.Create(nil);
     lQry2:= TFDQuery.Create(nil);
     try
       try 
         sqlConnX.Params.SetStrings (datMod.sqlConnParams);
         sqlConnX2.Params.SetStrings (datMod.sqlConnParams);
//                sqlConnX.TxOptions.AutoCommit:= false;
         sqlConnX.Open;
         sqlConnX2.Open;
         lQry.Connection:= sqlConnX;
         lQry2.Connection:= sqlConnX2;

         while not(Terminated) or not(FRunning) do
          begin
           if (HDCDZApiService<>nil) then
            if (HDCDZApiService.Terminated) then
             begin
              Terminate;
              FRunning:= false;
             end;

           PeekMessage (&Msg, 0, 0, 0, PM_NOREMOVE); { Create message queue }

           if (lLoop=lLoopMax) or (firstRun) then  // pri startu a pak podle lLoopMax sek (prednastaveno 10 sek)
            begin
             idDZ:= 0;
             firstRun:= false;

             if (logRunCnt<4) then
              datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim vytezovani ' + logRunCnt.toString + '...');
             if (logRunCnt=4) then
              datMod.LogInfo (Quick.Logger.etInfo, 'Spoustim vytezovani - bezi ale dal neloguju');

             try
               if not(inProg) then // nebezi uz ?
                begin

                 if (1=1) then // pro rychle vypnuti
                  begin                  
                   if (sqlConnX.Connected) then
                    begin
                     lSQL:= '/* hdcDZApiSvc-emp */ SELECT ID FROM ' + tblDZ
                          + ' WHERE BlokovaniEditoru IS NULL AND DruhPohybuZbo=18 AND CisloOrg IS NULL ORDER BY ID';

                     try
                       lQry.Open(lSQL);
                       if (lQry.RecordCount>0) then
                        begin
                         lQry.First;
                         inProg:= true;
                         while not(lQry.EOF) do
                          begin
                           idDZ:= lQry.FieldByName('ID').asInteger;
                           if (idDZ>0) then
                            begin
                             dataSouboru:= '';
                             lSQL:= 'SELECT 1 FROM ' + tblDokumVaz + ' v JOIN ' + tblDokum + ' d ON (d.ID=v.IDDok) WHERE v.IDTab=' + idDZ.ToString
                                  + ' AND v.IdentVazby=9 AND UPPER(d.JmenoACesta) LIKE N''%PDF'' AND d.VelikostSouboru>0';
                             lQry2.Open (lSQL);
                             if (lQry2.RecordCount=1) then // mam dokument PDF
                              begin
                               lQry2.Close;
                               lSQL:= lSQL.Replace(' 1 ', ' TOP(1) /*CONVERT(varchar(max), Dokument, 2)*/ BASE64_ENCODE(Dokument) AS DataSouboru ');
                               lQry2.Open (lSQL);
                               if (lQry2.Recordcount=1) then
                                begin
                                 dataSouboru:= lQry2.FieldByName('DataSouboru').AsString;
                                 lQry2.Close;
                                end;
                              end; // mam dokument PDF
                             if (dataSouboru<>'') then
                              begin
                              end;  // dataSouboru<>''                              
                            end; // idDZ>0
                           lQry.Next;
                          end;
                        end;
                      finally
                       lQry.Close;
                       FreeAndNil (lQry);
   //                    lQry.Free;
   //                    lQry:= nil;
                     end;
                     inProg:= false;
                     sqlConnX.Close;
                    end; //  sqlConnX Connected
                  end; //  1=1  -- pro rychle vypnuti
                  
                end;  //  not(inProg)

              except on E:Exception do
               begin
                inProg:= false;
                if (lQry<>nil) then
                 begin
                  lQry.Close;
                  FreeAndNil (lQry);
                 end;
                if (sqlConnX<>nil) then
                 sqlConnX.Close;

                errMsg:= E.Message; // datMod.sqlQry11.FieldByName('ErrMsg').AsString;
                if (mamTabPrijataData) then
                 datMod.LogInfo (Quick.Logger.etError, 'Chyba zpracovani API souboru FaktPrij ID ' + idDZ.ToString + ' : ' + errMsg);
               end;
             end; // try


             lLoop:= 0;
             if (logRunCnt<5) then
              Inc (logRunCnt);
            end;
           Inc (lLoop);

// sleep na vterinu
           if (FTimer<>0) then
            SetWaitableTimer (FTimer, TLargeInteger(liDueTime), 0, nil, nil, false);
           repeat
            lBusy:= MsgWaitForMultipleObjects (1, FTimer, false, INFINITE, QS_ALLINPUT);
           until lBusy = WAIT_OBJECT_0;

          end;
        except
       end;        
      finally
       sqlConnX.Close;
       FreeAndNil (sqlConnX);
     end;

    end;   // 1=1   -- pro rychle vypnuti

   if (sqlConnX2<>nil) then
    begin
     if (sqlConnX2.Connected) then
      sqlConnX2.Close;
     FreeAndNil (sqlConnX2);
    end;

  end;


