//
//  LFFolder.h
//  Localize Folder
//
//  Created by Kim Wittenburg on 05.07.13.
//  Copyright (c) 2013 Kim Wittenburg. All rights reserved.
//

#import <Foundation/Foundation.h>

extern NSString *const LFLocalizedFolderExtension;
extern NSString *const LFLocalizedFolderExtensionWithPeriod;
extern NSString *const LFLocalizedFolderSubdirName;


/* Use this class to represent and work with Localized Folders. Localized Folders are defined as the following:
    1) A Localized Folder is a directory in the file system. For security reasons the default directories (such as /Applications/ or ~/Documents/) are not supported to be localized with custom translations. (Also a different localization technique is used by the system).
    2) A Localized Folder must have the suffix .localized to be recognized by the system as Localized Folder.
    3) Inside the folder there must be a subdirectory named .localized containing the translation files

 A translation file is a file in the .strings format (using the Unicode UTF-16 encoding). The name of a translation file must match the represented locale identifier (for example de.strings or en.string for a German or English locale. You can also use exact locale identifiers as de_DE.strings for Germany or es_PE.strings for Spanish in Peru). Locale identifiers are based on the ISO 639-x/IETF BCP 47 standard.
 The contents of a translation file is a single key-value-mapping in the strings file format. The key must be the actual name of the directory (exclusive the .localized extension) and the value the translation for the represented locale. The strings file de.strings in a directory named "Developer.localized" could for example contain the following:
        "Developer" = "Entwickler";
 */
@interface LFFolder : NSObject

#pragma mark - *** Checking Directory Permissions ***

/* The following class methods are currently unsupported.
 */

/* Returns NO if neither writing nor reading operations can be performed on the passed file. To distinguish reading and writing permissions use canReadFromDirectoryAt...: and canWriteToDirectoryAt...:
 */
+ (BOOL)isDirectoryAtPathSupported:(NSString *)path;
+ (BOOL)isDirectoryAtURLSupported:(NSURL *)url;

/* Returns wether the given directory contents can be read. You may also want to check the writing permissions using canWriteToDirectoryAt...:
 */
+ (BOOL)canReadFromDirectoryAtPath:(NSString *)path;
+ (BOOL)canReadFromDirectoryAtURL:(NSURL *)url;

/* Returns wether you can use the given directory to write to.
 */
+ (BOOL)canWriteToDirectoryAtPath:(NSString *)path;
+ (BOOL)canWriteToDIrectoryAtURL:(NSURL *)url;

/* A dictionary of NSStrings identifying the translations for a specific locale. Use the locale identifier as key to store and receive the translated folder name.
 */
@property (strong, nonatomic) NSMutableDictionary *translations;

/* If specified this string is used as key in the localization .strings files. If not the save methods use the directory's current name. This property has no effect on the actual name of the directory the translations are written to.
 */
@property (strong, nonatomic) NSString *folderName;

#pragma mark *** Initialization ***

/* Initializer. Invoking any initializer other than the default init will cause LFFolder to send the corresponding loadTranslationsFrom...: or loadTranslationsFrom...:error: message to itself. All of the other initializers call init first.
 */
- (id)init;
- (id)initWithURL:(NSURL *)url;
- (id)initWithURL:(NSURL *)url error:(NSError *__autoreleasing *)error;
- (id)initWithFileWrapper:(NSFileWrapper *)fileWrapper;
- (id)initWithFileWrapper:(NSFileWrapper *)fileWrapper error:(NSError *__autoreleasing *)error;

#pragma mark *** Getting the File Manager

/* Returns the NSFileManager to be used when loading or saving translations. By default this returns the defaultManager of NSFileManager. Feel free to override this method as you need.
 */
- (NSFileManager *)fileManager;

#pragma mark *** Loading Translations ***

/* The following methods all do essentially the same: Load the translations table from a file representation. These methods expect the given directory file to be in the appropriate localized format (for a description about how to localize your folders in the appropriate format see above). If no localization files are found the translations dictionary is set to an empty dictionary (not nil) and the loading methods return successfully. If an error occurs during reading the translations NO is returned and the error parameter (if present) is set to the appropriate NSError object. If loading was successful YES is returned and the error parameter is left unmodified.
 */
- (BOOL)loadTranslationsFromURL:(NSURL *)url; // Invokes the method below with a NULL for the error parameter
- (BOOL)loadTranslationsFromURL:(NSURL *)url error:(NSError *__autoreleasing *)error;
- (BOOL)loadTranslationsFromFileWrapper:(NSFileWrapper *)fileWrapper; // Invokes the method below with a NULL for the error parameter
- (BOOL)loadTranslationsFromFileWrapper:(NSFileWrapper *)fileWrapper error:(NSError *__autoreleasing *)error;

/* These methods get called during the loading process but you can also call them on your own. These methods actually just call the addTranslationsFrom...:forLocale:error: methods with a locale identifer generated from the filename (that is the lastPathComponent of the url or the filename or preferredFilename of the file wrapper).
 For a more detailed description see addTranslationFrom...:forLocale:error:
 */
- (BOOL)addTranslationFromURL:(NSURL *)url error:(NSError *__autoreleasing *)error;
- (BOOL)addTranslationFromFileWrapper:(NSFileWrapper *)fileWrapper error:(NSError *__autoreleasing *)error;

/* These methods are used to generate the locale identifier by a given file representation. The given file representation must represent one of the .strings files is the .localized subdirectory.
 */
- (NSString *)localeIdentifierForURL:(NSURL *)url;
- (NSString *)localeIdentifierForFileWrapper:(NSFileWrapper *)fileWrapper;

/* These methods get called during the loading process but you can also call them on your own. The given file representation (either an url or a file wrapper) is expected to be a .strings file. (The loadTranslationsFrom...: and loadTranslationsFrom...:error: methods expect a folder) The loaded translations are added to the translations dictionary (replacing any previous value for that locale).
 */
- (BOOL)addTranslationFromURL:(NSURL *)url forLocale:(NSString *)localeID error:(NSError *__autoreleasing *)error;
- (BOOL)addTranslationFromFileWrapper:(NSFileWrapper *)fileWrapper forLocale:(NSString *)localeID error:(NSError *__autoreleasing *)error;

/* This method gets called during the loading process but you can also call it on your own. The given strings file's contents are parsed and the first value is set in the translations dictionary for the given locale identifier (replacing any previous value for that locale).
 */
- (BOOL)addTranslationFromStringsFile:(NSString *)stringsFile forLocale:(NSString *)localeID error:(NSError *__autoreleasing *)error;

#pragma mark *** Saving Translations ***

/* The following methods all do essentially the same: Save the translations to a file representation. The translations are saved appropriately based on the corresponding locale identifier in the .strings file format. By default these methods replace the complete .localized subdirectory so any files stored there before will be deleted. If an error occurs NO is returned and the error parameter (if present) is set to the appropriate NSError object. If saving completes successfully YES is returned and the error parameter is left unmodified.
 */
- (BOOL)saveTranslationsToURL:(NSURL *)url; // Invokes the method below with a NULL for the error parameter
- (BOOL)saveTranslationsToURL:(NSURL *)url error:( NSError *__autoreleasing *)error;
- (BOOL)saveTranslationsToFileWrapper:(NSFileWrapper *)fileWrapper; // Invokes the method below with a NULL for the error parameter
- (BOOL)saveTranslationsToFileWrapper:(NSFileWrapper *)fileWrapper error:(NSError *__autoreleasing *)error;

/* These methods are used if the folderName property is nil or empty. They guess a name by the given file representation.
 */
- (NSString *)folderNameForURL:(NSURL *)url;
- (NSString *)folderNameForFileWrapper:(NSFileWrapper *) fileWrapper;

@end
