/********************************************************************************
*                                                                               *
*      F i l e   I n f o r m a t i o n   a n d   M a n i p u l a t i o n        *
*                                                                               *
*********************************************************************************
* Copyright (C) 2000,2001 by Jeroen van der Zijp.   All Rights Reserved.        *
*********************************************************************************
* This library is free software; you can redistribute it and/or                 *
* modify it under the terms of the GNU Lesser General Public                    *
* License as published by the Free Software Foundation; either                  *
* version 2.1 of the License, or (at your option) any later version.            *
*                                                                               *
* This library is distributed in the hope that it will be useful,               *
* but WITHOUT ANY WARRANTY; without even the implied warranty of                *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             *
* Lesser General Public License for more details.                               *
*                                                                               *
* You should have received a copy of the GNU Lesser General Public              *
* License along with this library; if not, write to the Free Software           *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.    *
*********************************************************************************
* $Id: FXFile.h,v 1.44 2001/07/05 16:56:37 jeroen Exp $                         *
********************************************************************************/
#ifndef FXFILE_H
#define FXFILE_H


/// Declared as "C" so as to not clash tag-names
extern "C" { struct stat; }


/// This will be a namespace before long
class FXAPI FXFile {
public:
  /// Return value of environment variable name
  static FXString getEnvironment(const FXString& name);

  /// Return the home directory for the current user.
  static FXString getHomeDirectory();

  /// Return the home directory for a given user.
  static FXString getUserDirectory(const FXString& user);

  /// Set the current working directory
  static FXbool setCurrentDirectory(const FXString& path);

  /// Get the current working directory
  static FXString getCurrentDirectory();

  /// Set the current drive (for Win32 systems)
  static FXbool setCurrentDrive(const FXString& prefix);

  /// Return the current drive (for Win32 systems)
  static FXString getCurrentDrive();

  /// Get executable path
  static FXString getExecPath();

  /** 
  * Return the directory part of the path name.
  * Note that directory("/bla/bla/") is "/bla/bla" and NOT "/bla".
  * However, directory("/bla/bla") is "/bla" as we expect!
  */
  static FXString directory(const FXString& file);

  /**
  * Return name and extension part of the path name.
  * Note that name("/bla/bla/") is "" and NOT "bla". 
  * However, name("/bla/bla") is "bla" as we expect!
  */
  static FXString name(const FXString& file);

  /// Return file title, i.e. document name only
  static FXString title(const FXString& file);

  /// Return extension part of the file name
  static FXString extension(const FXString& file);

  /// Return file name less the extension
  static FXString stripExtension(const FXString& file);

  /// Return the drive letter prefixing this file name (if any).
  static FXString drive(const FXString& file);

  /// Perform tilde or environment variable expansion
  static FXString expand(const FXString& file);

  /**
  * Simplify a file path; the path will remain relative if it was relative.
  * For example, simplify("..//aaa/./bbb//../c/") becomes "../aaa/c/".
  * Note that a single trailing "/" is not removed!
  */
  static FXString simplify(const FXString& file);

  /// Return absolute path from current directory and file name
  static FXString absolute(const FXString& file);

  /// Return absolute path from base directory and file name
  static FXString absolute(const FXString& base,const FXString& file);
  
  /// Return relative path of file to the current directory
  static FXString relative(const FXString& file);
  
  /// Return relative path of file to given base directory
  static FXString relative(const FXString& base,const FXString& file);

  /// Generate unique filename of the form pathnameXXX.ext, where
  /// pathname.ext is the original input file, and XXX is a number,
  /// possibly empty, that makes the file unique.
  static FXString unique(const FXString& file);

  /// Search path list for this file, return full path name for first occurrence
  static FXString search(const FXString& pathlist,const FXString& file);

  /// Return path to directory above input directory name
  static FXString upLevel(const FXString& file);

  /// Return true if file name is absolute
  static FXbool isAbsolute(const FXString& file);

  /// Return true if input directory is a top-level directory
  static FXbool isTopDirectory(const FXString& file);

  /// Return true if input path is a file name
  static FXbool isFile(const FXString& file);

  /// Return true if input path is a link
  static FXbool isLink(const FXString& file);

  /// Return true if input path is a directory
  static FXbool isDirectory(const FXString& file);

  /// Return true if file is readable
  static FXbool isReadable(const FXString& file);

  /// Return true if file is writable
  static FXbool isWritable(const FXString& file);

  /// Return true if file is executable
  static FXbool isExecutable(const FXString& file);

  /// Return true if owner has read-write-execute permissions
  static FXbool isOwnerReadWriteExecute(const FXString& file);

  /// Return true if owner has read permissions
  static FXbool isOwnerReadable(const FXString& file);

  /// Return true if owner has write permissions
  static FXbool isOwnerWritable(const FXString& file);

  /// Return true if owner has execute permissions
  static FXbool isOwnerExecutable(const FXString& file);

  /// Return true if group has read-write-execute permissions
  static FXbool isGroupReadWriteExecute(const FXString& file);

  /// Return true if group has read permissions
  static FXbool isGroupReadable(const FXString& file);

  /// Return true if group has write permissions
  static FXbool isGroupWritable(const FXString& file);

  /// Return true if group has execute permissions
  static FXbool isGroupExecutable(const FXString& file);

  /// Return true if others have read-write-execute permissions
  static FXbool isOtherReadWriteExecute(const FXString& file);

  /// Return true if others have read permissions
  static FXbool isOtherReadable(const FXString& file);

  /// Return true if others have write permissions
  static FXbool isOtherWritable(const FXString& file);

  /// Return true if others have execute permissions
  static FXbool isOtherExecutable(const FXString& file);

  /// Return true if the file sets the user id on execution
  static FXbool isSetUid(const FXString& file);

  /// Return true if the file sets the group id on execution
  static FXbool isSetGid(const FXString& file);

  /// Return true if the file has the sticky bit set
  static FXbool isSetSticky(const FXString& file);

  /// Return owner name of file (if available, else "user")
  static FXString owner(const FXString& file);

  /// Return group name of file (if available, else "group")
  static FXString group(const FXString& file);

  /// Enquote filename to make safe for shell
  static FXString enquote(const FXString& file,FXbool forcequotes=FALSE);

  /// Decode filename to get original again
  static FXString dequote(const FXString& file);

  /// Match filenames using *, ?, [^a-z], and so on
  static FXbool match(const FXString& pattern,const FXString& file,FXuint flags=(FILEMATCH_NOESCAPE|FILEMATCH_FILE_NAME));

  /// Return file size in bytes
  static unsigned long size(const FXString& file);

  /// Return last modified time for this file
  static FXTime modified(const FXString& file);

  /// Return last accessed time for this file
  static FXTime accessed(const FXString& file);

  /// Return created time for this file
  static FXTime created(const FXString& file);

  /// Return touched time for this file
  static FXTime touched(const FXString& file);

  /// List all the files
  static FXint listFiles(FXString*& list,const FXString& path,const FXString& pattern="*",FXuint flags=(FILEMATCH_NOESCAPE|FILEMATCH_FILE_NAME));

  /// Return current time
  static FXTime now();

  /// Convert file time to date-string
  static FXString time(FXTime filetime);

  /**
  * Convert file time to date-string as per strftime.
  * Format characters supported by most systems are:
  *
  *  %a %A %b %B %c %d %H %I %j %m %M %p %S %U %w %W %x %X %y %Y %Z %%
  *
  * Some systems support additional conversions.
  */
  static FXString time(const FXchar *format,FXTime filetime);

  /// Return file info as reported by system stat() function
  static FXbool info(const FXString& file,struct stat& info);

  /// Return true if file exists
  static FXbool exists(const FXString& file);

  /// Return true if files are identical
  static FXbool identical(const FXString& file1,const FXString& file2);

  /// Return the mode flags for this file
  static FXuint mode(const FXString& file);

  /// Change the mode flags for this file
  static FXbool mode(const FXString& file,FXuint mode);

  /// Create new directory
  static FXbool createDirectory(const FXString& path,FXuint mode);

  /// Create new (empty) file
  static FXbool createFile(const FXString& file,FXuint mode);

  /// Concatenate srcfile1 and srcfile2 to a dstfile
  static FXbool concatenate(const FXString& srcfile1,const FXString& srcfile2,const FXString& dstfile,FXbool overwrite=FALSE);

  /// Remove file or directory
  static FXbool remove(const FXString& file);

  /// Copy file or directory
  static FXbool copy(const FXString& oldfile,const FXString& newfile,FXbool overwrite=FALSE);

  /// Rename or move file or directory
  static FXbool move(const FXString& oldfile,const FXString& newfile,FXbool overwrite=FALSE);

  /// Link file
  static FXbool link(const FXString& oldfile,const FXString& newfile,FXbool overwrite=FALSE);

  /// Symbolic link file
  static FXbool symlink(const FXString& oldfile,const FXString& newfile,FXbool overwrite=FALSE);

  /// Read symbolic link
  static FXString symlink(const FXString& file);
  };


#endif
