/*------------------------------------------------------------------------------
 src/lib/dj/djFileInfo.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

#ifndef DJ_FILE_INFO_H
#define DJ_FILE_INFO_H
#include <djSeq.h>

namespace dj {

// File information.
//
class FileInfo {
public:

  FileInfo();
  FileInfo(const Str &);
  
  // Set.
  //
  void set(const Str &);
  
  // Get.
  //
  const Str get(int frame = -1, bool path = true) const;
  
  // Components.
  //
  void path(const Str &);
  void base(const Str &);
  void number(const Str &);
  void extension(const Str &);
  const Str & path() const { return _path; }
  const Str & base() const { return _base; }
  const Str & number() const { return _number; }
  const Str & extension() const { return _extension; }

  // Information.
  //
  enum TYPE { FILE, SEQ, DIR };
  bool stat(const Str & path = Str());
  void type(TYPE);
  void size(uint64_t);
  void user(uid_t);
  enum PERM { READ = 1, WRITE = 2, EXEC = 4 };
  void perm(int);
  void time(time_t);
  TYPE type() const { return _type; }
  uint64_t size() const { return _size; }
  uid_t user() const { return _user; }
  int perm() const { return _perm; }
  const time_t & time() const { return _time; }
  
  // Sequence.
  //
  const Seq & seq() const { return _seq; }
  bool isSeq() const;
  int start() const { return _seq.start(); }
  int end() const { return _seq.end(); }
  int pad() const { return _seq.pad(); }
  bool seqAdd(const FileInfo &);
  
  // Convert.
  //
  operator Str() const { return get(); }

private:

  static void split(
    const Str &,
    Str * path, Str * base, Str * number, Str * extension
  );
  
  void init();
  
  Str _path, _base, _number, _extension;
  TYPE _type;
  uint64_t _size;
  uid_t _user;
  int _perm;
  time_t _time;
  Seq _seq;
};

// Sequence.
//
const List<FileInfo> seq(const List<FileInfo> &);
  
// Filter.
//
enum FILE_FILTER {
  FILE_FILTER_NONE = 0,
  FILE_FILTER_FILES = 1,
  FILE_FILTER_DIRS = 2,
  FILE_FILTER_HIDDEN = 4
};
const List<FileInfo> filter(
  const List<FileInfo> &, int filter, const StrList & globs = StrList()
);

// Sorting.
//
enum FILE_SORT {
  FILE_SORT_NAME,
  FILE_SORT_TYPE,
  FILE_SORT_SIZE,
  FILE_SORT_USER,
  FILE_SORT_PERM,
  FILE_SORT_TIME
};
const List<FileInfo> sort(
  const List<FileInfo> &, FILE_SORT, bool reverse = false
);
const List<FileInfo> sortDirsFirst(const List<FileInfo> &);

// Comparison.
//
bool operator == (const FileInfo &, const FileInfo &);
bool operator != (const FileInfo &, const FileInfo &);

// Labels.
//
inline const StrList fileTypeStr()
  { return StrList() + Str("File") + Str("Seq") + Str("Dir"); }
inline const StrList filePermStr()
  { return StrList() + Str("r") + Str("w") + Str("x"); }
const Str filePermStr(int);
inline const StrList fileSortStr()
  { return StrList() + Str("Name") + Str("Type") + Str("Size") + Str("User") +
    Str("Permissions") + Str("Time"); }

// Debugging.
//
Dbg & operator << (Dbg &, const FileInfo &);

}

#endif
