/* TreeSize for Unix  http://treesize.sf.net/
 * Copyright (c) 2006-2007 Marcos Diez <marcos_AT_unitron.com.br>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 3 of the License, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _FIFODERINFO_H_
#define _FIFODERINFO_H_

#include <sys/types.h>
#include <stdbool.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include "util.h"
#include "LLlinkedList.h"
#include "bigFiles.h"
#include "BTbinaryTree.h"

typedef struct strDevInfo{
  dev_t st_dev;
  struct strFolderInfo* rootFolder;
  BTree equalFiles;		/* for this filesystem */
  fileSizeUnit freeSpace;
} *DevInfo; 


typedef struct strFolderInfo{
  char *name;
  char *fullPath;
  fileSizeUnit totalLogicalSize;
  fileSizeUnit totalPhysicalSize;
  fileSizeUnit filesLogicalSize;
  fileSizeUnit filesPhysicalSize;

  bool fileFolder;
  bool accessible;
  
  struct strDevInfo *device;
  struct strFolderInfo* father;

  list subFolders;
} *FolderInfo;



#define FIgetName( f )           (f)->name
#define FIgetDev( f )            (f)->device->st_dev
#define FIgetFreeSpace( f )      (f)->device->freeSpace
#define FIgetPath( f )           (f)->fullPath

#define FIisFileFolder( f )      ((f)->fileFolder )
#define FIisMountPoint( f )      ((f)->father ? 0 : 1 )
#define FIisFolderAccessible(f)  ((f)->accessible)
#define FIgetFather(f)           (f)->father
#define FIgetSubFolderList(f)    (f)->subFolders
#define FIgetSubFolders(f)       LLlist2Array( FIgetSubFolderList( f ) )
#define FIgetNumSubFolders(f)    LLlistSize(   FIgetSubFolderList( f ) )


#define FIgetLogicalSize( f)     (f)->totalLogicalSize
#define FIgetPhysicalSize( f)    (f)->totalPhysicalSize
#define FIgetLogicalFilesSize(f) (f)->filesLogicalSize
#define FIgetPhysicalFilesSize(f) (f)->filesPhysicalSize 



#define FIgetLogicalPorcent( f)        ( (f)->device->rootFolder ? (f)->device->rootFolder->totalLogicalSize  ? ((fileSizeUnit) (100.*( (f)->totalLogicalSize  / (float)(f)->device->rootFolder->totalLogicalSize  ))) : 100 : 98)  
#define FIgetPhysicalPorcent( f)       ( (f)->device->rootFolder ? (f)->device->rootFolder->totalPhysicalSize ? ((fileSizeUnit) (100.*( (f)->totalPhysicalSize / (float)(f)->device->rootFolder->totalPhysicalSize ))) : 100 : 98)  
#define FIgetLogicalFilesPorcent( f)   ( (f)->device->rootFolder ? (f)->device->rootFolder->totalLogicalSize  ? ((fileSizeUnit) (100.*( (f)->filesLogicalSize  / (float)(f)->device->rootFolder->totalLogicalSize  ))) : 100 : 98)  
#define FIgetPhysicalFilesPorcent( f)  ( (f)->device->rootFolder ? (f)->device->rootFolder->totalPhysicalSize ? ((fileSizeUnit) (100.*( (f)->filesPhysicalSize / (float)(f)->device->rootFolder->totalPhysicalSize ))) : 100 : 98) 


#define FIsameDevs( f1 , f2 )   (((f1)->device->st_dev) == ((f2)->device->st_dev))

void FIfree( FolderInfo thisFolder );
fileSizeUnit FIgetDirFreeSpace( char *directory );
FolderInfo FInew( char *name , struct stat *dirStat  , bool accessible , FolderInfo father );
void FIaddFile( FolderInfo theFolder , char *fileName , struct stat *fileStat );
void FIaddFolder( FolderInfo theFolder, char *newFolderName, struct stat *newFolderStat , bool onlyOneFileSystem );
void FIprint( FolderInfo theFolder );

void FIaddFileFolder( FolderInfo theFolder  );

#endif
