unit vxFilesys;
// Just generic file stuff
interface

uses
  Windows, SysUtils, Registry, Classes;


function GetWindowsDir: TFileName;
function GetTempDir: TFileName;
function TempFile: TFileName;
function GetAppDataDir: TFileName;

function LoadFile(const FileName: TFileName): string;
procedure SaveFile(const FileName: TFileName; const content: string);

procedure CopyFile(const inputFileName:string; const outputFileName:string);
function AppendBackslash(const s:string):string;

function CrossExtractFolder(const filepath:string): string;
function CrossNormalizeFilename(const filepath:string): string;



//==============================================================================
implementation
//==============================================================================


//==============================================================================
//  Returns the textual contents of file as string.
//==============================================================================
function LoadFile(const FileName: TFileName): string;
begin
  with TFileStream.Create(FileName,
      fmOpenRead or fmShareDenyWrite) do begin
    try
      SetLength(Result, Size);
      Read(Pointer(Result)^, Size);
    except
      Result := '';  // Deallocates memory
      Free;
      raise;
    end;
    Free;
  end;
end;

//==============================================================================
//  Save string into a file.
//==============================================================================
procedure SaveFile(const FileName: TFileName; const content: string);
begin
  with TFileStream.Create(FileName, fmCreate) do
    try
      Write(Pointer(content)^, Length(content));
    finally
      Free;
    end;
end;

//==============================================================================
//  Copy one file to another, forces overwrite.
//==============================================================================
procedure CopyFile(const inputFileName:string; const outputFileName:string);
begin
    windows.CopyFile(pchar(inputFileName), pchar(outputFileName), false);
end;

//==============================================================================
//  Returns application directory path
//==============================================================================
function GetAppDataDir: TFileName;
var
  Registry: TRegistry;
begin
  Registry := TRegistry.Create(KEY_READ);
  try
    Registry.RootKey := HKEY_CURRENT_USER;
    // False because we do not want to create it if it doesn't exist
    Registry.OpenKey('\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', False);
    Result := Registry.ReadString('AppData');
  finally
    Registry.Free;
  end;
  if (Result='') then begin
      Result:=ExtractFileDir(ParamStr(0));
  end else if DirecToryExists(Result+'\vexorian') or CreateDirectory(PChar(Result+'\vexorian'),nil) then
          Result:=Result+'\vexorian';
end;

//==============================================================================
//  Returns widows directory path
//==============================================================================
function GetWindowsDir: TFileName;
var
  WinDir: array [0..MAX_PATH-1] of char;
begin
  SetString(Result, WinDir, GetWindowsDirectory(WinDir, MAX_PATH));
  if Result = '' then
    raise Exception.Create(SysErrorMessage(GetLastError));
end;

//==============================================================================
//  Appends Backslash to a path if needed
//==============================================================================
function AppendBackslash(const s:string):string;
var L:integer;
begin
    L:=Length(s);
    if(L=0) then Result:='\'
    else if (s[L]='\') then Result:=s
    else Result:=s+'\';

end;

//==============================================================================
// Creates a temporary directory and returns its name and path
//==============================================================================
function GetTempDir: TFileName;
var
  TmpDir: array [0..MAX_PATH-1] of char;
begin
  try
    SetString(Result, TmpDir, GetTempPath(MAX_PATH, TmpDir));
    if not DirectoryExists(Result) then
      if not CreateDirectory(PChar(Result), nil) then begin
        Result := AppendBackslash(GetWindowsDir) + 'TEMP'; //Of course it is specific to a platform! It is supposed to!
        if not DirectoryExists(Result) then
          if not CreateDirectory(Pointer(Result), nil) then begin
            Result := ExtractFileDrive(Result) + '\TEMP';
            if not DirectoryExists(Result) then
              if not CreateDirectory(Pointer(Result), nil) then begin
                Result := ExtractFileDrive(Result) + '\TMP';
                if not DirectoryExists(Result) then
                  if not CreateDirectory(Pointer(Result), nil) then begin
                    raise Exception.Create(SysErrorMessage(GetLastError));
                  end;
              end;
          end;
      end;
  except
    Result := '';
    raise;
  end;
end;

//==============================================================================
// Creates a temporary file and returns its name and path
//==============================================================================
function TempFile: TFileName;
var
  NomArchTemp: array [0..MAX_PATH-1] of char;
begin
  if GetTempFileName(PChar(GetTempDir),'V', 0, NomArchTemp) = 0 then
    raise Exception.Create(SysErrorMessage(GetLastError));
  Result := NomArchTemp;
end;

//==============================================================================
function CrossExtractFolder(const filepath:string): string;
  var i,L:integer;
begin
    L:=Length(filepath);
    i:=L;
    while(i>=1) do begin
        if(filepath[i]='/') or (filepath[i]='\') then begin
            break;
        end;
        i:=i-1;
    end;
    if(i=0) then begin
        result:='';
        exit;
    end;
    result:=Copy(filepath,1,i);
end;

//==============================================================================
function CrossNormalizeFilename(const filepath:string): string;
begin
    result:= StringReplace(StringReplace(filepath,'\\','\',[rfREPLACEALL]), '\','/', [rfREPLACEALL]);
end;

end.
