unit dvHelpers;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, fpg_base;

const
  OWN_HELP_MARKER = '[DOCVIEWHELP]';


function GetOwnHelpFileName: String;
// Given a filename, which may or may not contain a path or extension,
// finds the actual file. This can involve searching
// the help and bookshelf paths.
function FindHelpFile(const AFilename: TfpgString): TfpgString;

function SearchHelpPaths( const Filename: TfpgString; var ResultFilename: TfpgString; const IncludeAppDir: boolean ): boolean;

function GetApplicationDir: TfpgString;
function SearchPath( PathEnvVar: TfpgString; Filename: TfpgString; var FilenameFound: string ): boolean;

implementation

uses
  fpg_utils
  ,dvConstants
  ,nvUtilities
  ;


function GetOwnHelpFileName: String;
begin
  { TODO -oGraeme -cown help : Maybe later we will have different language versions }
  result := fpgExtractFilePath(ParamStr(0)) + cDocViewHelpFile;
  if not fpgFileExists(Result) then
  begin
     Result := FindHelpFile(cDocViewHelpFile);
  end;
end;

// Given a "filename" which may include a path, find it in various paths and extensions
function FindHelpFile(const AFilename: TfpgString): TfpgString;
var
  AlternativeFileName: TfpgString;
  lFilename: TfpgString;
begin
  lFilename := AFilename;
  if lFileName = OWN_HELP_MARKER then
  begin
    Result := GetOwnHelpFileName;
    exit;
  end;

  Result := '';

  AlternativeFileName := '';
  if fpgExtractFileExt( lFilename ) = '' then
  begin
    lFilename := fpgChangeFileExt(lFilename, '.inf');
    AlternativeFileName := fpgChangeFileExt(lFilename, '.hlp');
  end;

  if fpgExtractFilePath( lFileName ) <> '' then
  begin
    // Path specified; just see if it exists

    // expand out relative paths
    lFilename := fpgExpandFileName( lFileName );
    AlternativeFilename := fpgExpandFileName( AlternativeFilename );

    if fpgFileExists( lFilename ) then
      Result := lFilename
    else if fpgFileExists( AlternativeFilename ) then
      Result := AlternativeFilename;

  end
  else
  begin
    // Path not specified; search current
    if fpgFileExists( fpgExpandFileName( lFileName ) ) then
    begin
      Result := fpgExpandFileName( lFileName );
      exit;
    end;

    if (AlternativeFilename <> '') and fpgFileExists(fpgExpandFileName(AlternativeFilename)) then
    begin
      Result := fpgExpandFileName( AlternativeFilename );
      exit;
    end;

    // Search help paths
    if not SearchHelpPaths( lFileName,
                            Result,
                            false // don't search our app dir
                             ) then
    begin
      // Didn't find as specified or as .inf, try .hlp
      if AlternativeFilename <> '' then
      begin
        if not SearchHelpPaths( AlternativeFileName,
                                Result,
                                false // don't search our app dir
                                ) then
        begin
          Result := '';
        end;
      end;
    end;
  end;
//  Result := AFileName;
end;

Function SearchHelpPaths( const Filename: TfpgString;
                          var ResultFilename: TfpgString;
                          const IncludeAppDir: boolean ): boolean;
begin
  Result := SearchPath( HelpPathEnvironmentVar,
                        FileName,
                        ResultFilename );
  if not Result then
    Result := SearchPath( BookshelfEnvironmentVar,
                          FileName,
                          ResultFilename );
  if ( not Result ) and IncludeAppDir then
  begin
    ResultFilename := fpgAppendPathDelim(GetApplicationDir)
                      + Filename;
    Result := fpgFileExists( ResultFilename );
    if not Result then
      ResultFilename := '';
  end;

end;

function GetApplicationDir: TfpgString;
begin
  Result := fpgExtractFilePath(ParamStr(0));
end;

function SearchPath( PathEnvVar: TfpgString; Filename: TfpgString; var FilenameFound: string ): boolean;
var
  lFilename: string;
  lDir: TfpgString;
  fl: TStrings;
  i: integer;
begin
  Result := False;
  FilenameFound := '';

  lDir := GetEnvironmentVariable(PathEnvVar);

  fl := TStringList.Create;
  ListFilesInDirectory(lDir, AllFilesMask, True, fl);
  TStringList(fl).Sort;
  for i := 0 to fl.Count-1 do
  begin
    lFilename := fpgExtractFileName(fl[i]);
    if SameText(lFilename, Filename) then
    begin
      FilenameFound := fl[i];
      Result := True;
      Exit;
    end;
  end;
end;


end.