/*
    FileManager.h

    Interface declaration of the FileManager class for the
    ProjectManager application.

    Copyright (C) 2005  Saso Kiselkov

    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 2 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, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#import <Foundation/NSObject.h>
#import "../../ProjectModule.h"

@class NSBrowser,
       NSMatrix,
       NSNotification,
       NSMutableArray,
       NSImage,
       NSError;

@protocol NSDraggingInfo,
          FileManagerDelegate;

/*
 * The pasteboard type used when dragging project files. The data
 * of the pasteboard is a property list of the form:
 * {
 *   Category = source-category;
 *   Project = project-file;     <- used to distinguish dragged files
 *                                  within projects and from one project
 *                                  to another project
 *   Contents = (
 *     <list-of-filenames>
 *   );
 * }
 */
extern NSString * const ProjectFilesPboardType;

/**
 * These identify the type of a file in a project. The values mean the
 * following:
 *
 * - ProjectFileTypePlain: the file is a plain disk file which can be
 *   opened and written to.
 * - ProjectFileTypeLink: the file is a link to a plain disk-file.
 * - ProjectFileTypeCategory: the file is in fact a virtual aggregation
 *   of further files of any other type.
 * - ProjectFileTypeVirtual: the file is a virtual non-disk file and only
 *   serves as a placeholder or virtual representative of information
 *   which can be represented as quasi-file information. E.g. the `Frameworks'
 *   section contains these entries.
 */
typedef enum {
  FMFileTypePlain,
  FMFileTypeLink,
  FMFileTypeCategory,
  FMFileTypeVirtual
} FMFileType;

extern NSString * const ProjectFilesDidChangeNotification;

extern NSString * const ProjectFilesErrorDomain;

enum {
  ProjectFilesAlreadyExistError,
  ProjectFilesInvalidFileTypeError,
  ProjectFilesCreationError,
  ProjectFilesDeletionError,
  ProjectFilesCopyError,
  ProjectFilesMoveError,
  ProjectFilesGenericFileImportError
};

@class ProjectBrowser,
       ProjectImageView,
       NSTextField,
       NSImageView;

@interface FileManager : NSObject <ProjectModule>
{
  id view;
  id bogusWindow;

  ProjectBrowser * browser;
  ProjectImageView * fileIcon;
  NSTextField * fileNameField;
  NSTextField * filePathField;
  NSTextField * fileSizeField;
  NSTextField * fileTypeField;
  NSTextField * lastModifiedField;

  // the root category contents array
  NSMutableArray * files;
  id <FileManagerDelegate> delegate;    // weak reference
  ProjectDocument * document;
}

- delegate;

- (void) openFile: (id)sender;

- (void)      browser: (NSBrowser *) sender
  createRowsForColumn: (int) column
             inMatrix: (NSMatrix *) matrix;
- (NSString *) browser: (NSBrowser *)sender titleOfColumn: (int)column;

- (void) selectFile: sender;
- (void) changeName: sender;

- (void) selectAndEditNameAtPath: (NSString *) aPath;

- (NSArray *) selectedFiles;
- (NSString *) containingCategory;

- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender;

- (BOOL) openPath: (NSString *) aPath;

/* project file/category management */
- (BOOL) fileExistsAtPath: (NSString *) aPath;
- (NSArray *) filesAtPath: (NSString *) category;
- (FMFileType) typeOfFileAtPath: (NSString *) aPath;
- (NSString *) targetOfLinkAtPath: (NSString *) aPath;
- (unsigned long long) measureDiskUsageAtPath: (NSString *) aPath;
- (NSString *) pathToFileAtPhysicalPath: (NSString *) diskLocation;

- (NSArray *) filesAtPath: (NSString *) aCategory
                   ofType: (FMFileType) aFileType
                recursive: (BOOL) recursive;

- (BOOL) importFile: (NSString *) filePath
             toPath: (NSString *) category
               link: (BOOL) linkFlag
              error: (NSError **) error;
- (BOOL) importFile: (NSString *) filePath
           renameTo: (NSString *) aNewName
             toPath: (NSString *) category
               link: (BOOL) linkFlag
              error: (NSError **) error;
- (BOOL) createCategory: (NSString *) categoryName
                 atPath: (NSString *) category
                  error: (NSError **) error;
- (BOOL) createCategoryAndIntermediateCategories: (NSString *) category
                                           error: (NSError **) error;
- (BOOL) createVirtualFileNamed: (NSString *) filename
                         atPath: (NSString *) category
                          error: (NSError **) error;

/**
 * Removes the specified file at `aPath'. If deleteFlag = YES, then any
 * disk files and links are deleted from disk as well.
 */
- (BOOL) removePath: (NSString *) aPath
             delete: (BOOL) deleleFlag
              error: (NSError **) error;

- (BOOL) copyPath: (NSString *) aPath
           toPath: (NSString *) newPath
            error: (NSError **) error;

- (BOOL) movePath: (NSString *) aPath
           toPath: (NSString *) newPath
            error: (NSError **) error;

- (BOOL) linkPath: (NSString *) aPath
         fromPath: (NSString *) newPath
            error: (NSError **) error;

- (NSImage *) iconForPath: (NSString *) aPath;

// menu actions
- (void) importFiles: sender;
- (void) newEmptyFile: sender;
- (void) newFileFromTemplate: sender;
- (void) newCategory: sender;
- (void) deleteFiles: sender;

// notifications
- (void) filesChanged: (NSNotification *) notif;
- (void) projectNameChanged: (NSNotification *) notif;

@end
