unit uUtils;
interface
uses
  ORFn
  , rGroupNote
  ;

function HintString(aHint:String;aLimit: Integer = 80):String;
function LongDescriptionByCode(aCode,aDefault:String;aDate:TFMDateTime;AI10Active:Boolean):String;
function RemoveDuplicate(aTarget,aDelimeter:String):String;
function DebugInfo:String;
function IsCorrectVersion(bDebug:Boolean): Boolean;
function getLongDescriptionByCode(aCode,aDefault:String):String;

{$IFDEF ICD10TEST01}
var
  gDebugProblemList: Boolean; // setting to True forces open an editor of data
                              // returned by the RPC call
{$ENDIF}

implementation
uses
  Classes
  , SysUtils
  , ORNet
  , rPCE
  , rMisc
  , Forms
  , VAUtils
  , ORSystem
  , Dialogs
  , fxBroker
  , Windows
  ;
const
  TX_VER1       = 'This is version ';
  TX_VER2       = ' of GroupNotes.exe.';
  TX_VER3       = CRLF + 'The running server version is ';
  TX_VER_REQ    = ' version server is required.';
  TX_VER_OLD    = CRLF + 'It is strongly recommended that you upgrade.';
  TX_VER_OLD2   = CRLF + 'The program cannot be run until the client is upgraded.';
  TX_VER_NEW    = CRLF + 'The program cannot be run until the server is upgraded.';
  TC_VER        = 'Server/Client Incompatibility';
  TC_CLIERR     = 'Client Specifications Mismatch';

  TX_CLIENT_MISMATCH = 'Client "version" does not match client "required" server.';

function HintString(aHint:String;aLimit: Integer = 80):String;
  var
    i: integer;
    s,sHint: String;
    sl: TStringList;
  begin
    // ICD-10. Removing duplicate data from Hint text
    if pos(' - ',aHint) > 0 then
      sHint := copy(aHint,pos(' - ',aHint)+3,Length(aHint))
    else
      sHint := aHint;

    sHint := StringReplace(sHint, #9, ' ', [rfReplaceAll]);

    sl := TStringList.Create;
    sl.Delimiter := ' ';
    sl.DelimitedText := sHint;
    s := '';
    for i  := 0 to sl.Count - 1 do
      begin
        if Length(s+sl[i]) > aLimit then
          begin
            Result := Result + s + #13#10;
            s := sl[i]+ ' ';
          end
        else
          s := s + sl[i]+ ' ';
      end;
    Result := Result + s;
  end;

function FMDateToWindowsDate(aDate:String):TFMDateTime;
var
  year,month,day: Word;
begin
  year  := StrToIntDef(Copy(aDate, 1, 3), 0) + 1700;
  month := StrToIntDef(Copy(aDate, 4, 2), 0);
  day   := StrToIntDef(Copy(aDate, 6, 2), 0);
  Result := EncodeDate(year, month, day);
end;

//ICD-10 Remediation. CodeCR:184
function getLongDescriptionByCode(aCode,aDefault:String):String;
var
  SL: TStringList;
  S: String;
begin
  Result := aDefault;
  SL := TStringList.Create;
  tCallV(SL,'ORWPCE GET DX TEXT',['',aCode]);
  if SL.Count > 0 then
    begin
      s := SL[0];
      FreeAndNil(SL);
      if (pos('-',s) =1) or (trim(s) = '') then
        Result := aDefault
      else
        Result := copy(s,4,Length(s));
    end
  else
    Result := aDefault;
end;

function LongDescriptionByCode(aCode,aDefault:String;aDate:TFMDateTime;AI10Active:Boolean):String;
var
  s: String;
  bExtend,bActive: Boolean;
  dDate: TFMDateTime;
  LexResults: TSTringList;
begin
  if trim(aCode) = '' then
    begin
      Result := aDefault;
      Exit;
    end;

  LexResults := TStringList.Create;

  if pos('ICD-10',aDefault)> 0 then
    begin
      dDate := StrToFloat(GImplementationDate);
      bExtend := True;
      bActive := True;
    end
  else
    begin
      dDate := FMDateToWindowsDate(GImplementationDate) -1;
      dDate := DateTimeToFMDateTime(dDate);
      bExtend := True;
      bActive := False;
    end;

  ListLexicon(LexResults,aCode,LX_ICD,dDate,bExtend,bActive);
  s := LexResults.Text;
  if (pos('-',s) =1) or (trim(s) = '') then
    Result := aDefault
  else
    Result := Piece(S,U,2) + ' ('+Piece(s,U,3) + ' '+ Piece(s,U,4) + ')';

  FreeAndNil(LexResults);
end;

function RemoveDuplicate(aTarget,aDelimeter:String):String;
begin
  if pos(aDelimeter,aTarget) > 0 then
    Result := copy(aTarget,pos(aDelimeter,aTarget)+Length(aDelimeter),Length(aTarget))
  else
    Result := aTarget;
end;

function DebugInfo:String;
begin
   Result :=
   'This is the DEBUG version of the Group Notes application.'+CRLF+
   'File Version: ' +  FileVersionValue(Application.ExeName, 'FileVersion')+
   ' ('+FileVersionValue(Application.ExeName, FILE_VER_FILEDESCRIPTION)+')'+
   CRLF+CRLF+
   'Code CRs addressed:' + CRLF +
//                     '  ??   - incorrect date value passed to LEX search'+ CRLF +
                        '  184  - Code truncated in the diagnosis list'+ CRLF +
                        '  186  - invalid codes can be selected if entered in CPRS'+ CRLF +
                        '  235  - missing default provider'+ CRLF +
   CRLF+
   'Compiled with conditionals:' + CRLF +
                         '  ICD10DEBUG  - dubug code included'+ CRLF +
{$IFDEF RPCLOG}          '  RPCLOG      - enhanced RPC Log support' + CRLF + {$ENDIF}
{$IFDEF ICD10DEBUG235}   '  ICD10DEBUG235 - debug details for CodeCR 235' + CRLF + {$ENDIF}
{$IFDEF ICD10TEST01}     '  ICD10TEST01 - Problems List items editing' + CRLF + {$ENDIF}
{$IFDEF ICD10NOPREVDIAG} '  ICD10NOPREVDIAG - no support for "Previous Diagnosis" section' + CRLF + {$ENDIF}
   CRLF + 'Debug Info:' + CRLF+ '  ' + FileVersionValue(Application.ExeName, 'DEBUG')+CRLF+
   CRLF +
   'The debug version supports all functions of the production one plus:'+CRLF+
   '- /ICD10DEBUG startup parameter'+CRLF+
{$IFDEF RPCLOG} '- Enhanced RPC Log.'+ CRLF + {$ENDIF}
   CRLF+
   'Use /ICD10DEBUG parameter to: ' + CRLF+
   '- bypass the GUI version control (registered in the Log) ' + CRLF+
   '- enable selection of the future dates for the Encounters' + CRLF+
{$IFDEF RPCLOG} '- open RPC Log window at the startup.' + CRLF + {$ENDIF}
   ''
   ;
end;

function IsCorrectVersion(bDebug:Boolean): Boolean;
var
  sMessage,
  ClientVer, ServerVer, ServerReq: string;
begin
{$IFDEF DEBUG}
  Result := True;
  InfoBox('The DEBUG build ignores version validation.'+CRLF+CRLF+
    ' DO NOT USE IT IN PRODUCTION ACCOUNTS!', 'DEBUG INFO', MB_OK);
{$ELSE}
  Result := False;
{$ENDIF}
  if not IsAuthUser then
  begin
    ShowMessage('You are not authorized to use Group Notes.');
{$IFDEF DEBUG}
{$ELSE}
    Exit;
{$ENDIF}
  end;

  ClientVer := ClientVersion(Application.ExeName);
  ServerVer := ServerVersion('OR GN SET LOCATIONS', ClientVer);
  if (ServerVer = '0.0.0.0') then
  begin
//    InfoBox('Unable to determine current version of server, please make sure you installed latest patch OR*3*222.', 'Group Notes', MB_OK);
    InfoBox('Unable to determine current version of server, please make sure you installed latest patch OR*3*412.', 'Group Notes', MB_OK);
    Exit;
  end;
  // ICD-10 Remediation. Removing 4th piece of the version from the internal name
  ServerReq := Piece(FileVersionValue(Application.ExeName, FILE_VER_INTERNALNAME), ' ', 1);
//  ServerReq := ServerReq + '.7';//  ICD-10 remediation. CodeCR CPRS177

  if (CompareVersion(ServerVer, ClientVer) > 0) then // Server newer than Client
  begin
    AddLogLine(TX_CLIENT_MISMATCH, TC_CLIERR); //
    InfoBox(TX_CLIENT_MISMATCH, TC_CLIERR, MB_OK);
    Result := bDebug;
    Exit;
  end;

  if (CompareVersion(ServerVer, ServerReq) <> 0) then
  begin
    if (CompareVersion(ServerVer, ServerReq) > 0) then // Server newer than Required
    begin
      if (CompareVersion(ServerVer, ClientVer) > 0) then  //  Server newer than Client
      begin
        sMessage :=TX_VER1 + ClientVer + TX_VER2 + CRLF + ServerReq + TX_VER_REQ + TX_VER3 + ServerVer + '.' + TX_VER_OLD2;
        AddLogLine(sMessage,TC_VER);
        InfoBox(sMessage, TC_VER, MB_OK);
        Result := bDebug;
        Exit;
      end;
    end;
    if (CompareVersion(ServerVer, ServerReq) < 0) then // Server older then Required
    begin
      sMessage := TX_VER1 + ClientVer + TX_VER2 + CRLF + ServerReq + TX_VER_REQ + TX_VER3 + ServerVer + '.' + TX_VER_NEW;
      AddLogLine(sMessage, TC_VER);
      InfoBox(sMessage, TC_VER, MB_OK);
      Result := bDebug;
      Exit;
    end;
  end;
  sMessage :=
    'Client:          '+ClientVer + CRLF +
    'Server:          ' + ServerVer + CRLF +
    'Required Server: ' + ServerReq;

  AddLogLine(sMessage,'Version Info');
  Result := True;
end;

end.
