//
//  FSFileItem.m
//  PDFReader
//
//  Created by Dong Li on 12-4-26.
//  Copyright (c) 2013年 __MyCompanyName__. All rights reserved.
//

#import "FSFileItem.h"

@implementation FSFileItem

@synthesize path = _path;
@synthesize fileName = _fileName;
@synthesize displayName = _displayName;
@synthesize statistic = _statistic;
@synthesize extension = _extension;
@synthesize creationTime = _creationTime;
@synthesize iconName = _iconName;
@synthesize subitems = _subitems;
@synthesize fileSize = _fileSize;
@synthesize fileCategory = _fileCategory;
@synthesize isDirectory = _directory;
@synthesize selected = _selected;
@synthesize cut = _cut;

- (id)initWithParentPath:(NSString *)parentPath fileName:(NSString *)fileName {
    if (self = [super init]) {
        if ([fileName hasPrefix:@"."]) {
            return nil;
        }
        
        _fileName = [fileName copy];
        _path = [parentPath stringByAppendingPathComponent:_fileName];
        
        NSDictionary *attributes = [theFileManager attributesOfItemAtPath:_path error:NULL];
        NSString *fileType = [attributes valueForKey:NSFileType];
        
        DLog(@"attributes:\n%@", attributes);
        _fileSize = [[attributes valueForKey:NSFileSize] doubleValue];
        
        if ([fileType isEqualToString:NSFileTypeRegular]) {
            _extension = [[_fileName pathExtension] lowercaseString];
        } else if ([fileType isEqualToString:NSFileTypeDirectory]) {
            _directory = YES;
        } else {
            return nil;
        }
        
        NSData *data = [[attributes valueForKey:@"NSFileExtendedAttributes"] valueForKey:@"com.apple.TextEncoding"];
        
        if (data) {
            NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            
            DLog(@"encoding: %@", string);
            NSArray *comps = [string componentsSeparatedByString:@";"];
            
            if ([comps count] > 1) {
                DLog(@"%08X", [[comps objectAtIndex:1] unsignedIntValue]);
            }
        }
        
        _fileNumber = [[attributes valueForKey:NSFileSystemFileNumber] unsignedLongValue];
        _creationTime = [NSMainDateFormatter stringFromDate:[attributes valueForKey:NSFileCreationDate]];
    }
    return self;
}

- (id)initWithPath:(NSString *)path {
    NSString *parentPath = [path stringByDeletingLastPathComponent];
    NSString *fileName = [path lastPathComponent];
    
    return [self initWithParentPath:parentPath fileName:fileName];
}

- (void)loadAttributesIfNeeded {
    if (FC_UNKNOWN == _fileCategory) {
        const char *cIconName = NULL;
        
        if (_directory) {
            _fileCategory = FC_DIRECTORY;
            _displayName = _fileName;
            cIconName = ([_fileName hasSuffix:@".bundle"] || [_fileName hasSuffix:@".framework"]) ? "plugin" : "folder";
        } else {
            if (UISettingsShowFileExtensions()) {
                _displayName = _fileName;
            } else {
                _displayName = [_fileName stringByDeletingPathExtension];
            }
            _statistic = FSStringCreateWithFileSize(_fileSize);
            
            const char *cExtenstion = [_extension UTF8String];
            
            cIconName = cExtenstion;
            
            if (0 == strcmp(cExtenstion, "txt")) {
                _fileCategory = FC_PLAIN_TEXT;
            } else if (0 == strcmp(cExtenstion, "s")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "nasm")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "h")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "hpp")) {
                _fileCategory = FC_SOURCE_CODE;
                cIconName = "h";
            } else if (0 == strcmp(cExtenstion, "c")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "cpp")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "cc")) {
                _fileCategory = FC_SOURCE_CODE;
                cIconName = "cpp";
            } else if (0 == strcmp(cExtenstion, "m")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "mm")) {
                _fileCategory = FC_SOURCE_CODE;
                cIconName = "m";
            } else if (0 == strcmp(cExtenstion, "java")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "js")) {
                _fileCategory = FC_SOURCE_CODE;
            } else if (0 == strcmp(cExtenstion, "rtf")) {
                _fileCategory = FC_RICH_TEXT;
            } else if (0 == strcmp(cExtenstion, "rtfd")) {
                _fileCategory = FC_RICH_TEXT;
                cIconName = "rtf";
            } else if (0 == strcmp(cExtenstion, "doc")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "docm")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "docx")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "dot")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "dotm")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "dotx")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xls")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xlsm")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xlsx")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xlt")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xltm")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "xltx")) {
                _fileCategory = FC_OFFICE;
            } else if (0 == strcmp(cExtenstion, "htm")) {
                _fileCategory = FC_XML;
                cIconName = "html";
            } else if (0 == strcmp(cExtenstion, "html")) {
                _fileCategory = FC_XML;
            } else if (0 == strcmp(cExtenstion, "xhtml")) {
                _fileCategory = FC_XML;
            } else if (0 == strcmp(cExtenstion, "xib")) {
                _fileCategory = FC_XML;
            } else if (0 == strcmp(cExtenstion, "pdf")) {
                _fileCategory = FC_PDF;
            } else if (0 == strcmp(cExtenstion, "tif")) {
                _fileCategory = FC_PHOTO;
                cIconName = "tiff";
            } else if (0 == strcmp(cExtenstion, "tiff")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "jpg")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "jpeg")) {
                _fileCategory = FC_PHOTO;
                cIconName = "jpg";
            } else if (0 == strcmp(cExtenstion, "gif")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "png")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "bmp")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "bmpf")) {
                _fileCategory = FC_PHOTO;
                cIconName = "bmp";
            } else if (0 == strcmp(cExtenstion, "xbm")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "ico")) {
                _fileCategory = FC_PHOTO;
            } else if (0 == strcmp(cExtenstion, "cur")) {
                _fileCategory = FC_PHOTO;
                cIconName = "image";
            } else if (0 == strcmp(cExtenstion, "mp3")) {
                _fileCategory = FC_AUDIO;
            } else if (0 == strcmp(cExtenstion, "wav")) {
                _fileCategory = FC_AUDIO;
            } else if (0 == strcmp(cExtenstion, "m4a")) {
                _fileCategory = FC_AUDIO;
                cIconName = "audio";
            } else if (0 == strcmp(cExtenstion, "acc")) {
                _fileCategory = FC_AUDIO;
                cIconName = "audio";
            } else if (0 == strcmp(cExtenstion, "caf")) {
                _fileCategory = FC_AUDIO;
                cIconName = "audio";
            } else if (0 == strcmp(cExtenstion, "mov")) {
                _fileCategory = FC_VIDEO;
            } else if (0 == strcmp(cExtenstion, "mp4")) {
                _fileCategory = FC_VIDEO;
            } else if (0 == strcmp(cExtenstion, "3gp")) {
                _fileCategory = FC_VIDEO;
            } else if (0 == strcmp(cExtenstion, "3gpp")) {
                _fileCategory = FC_VIDEO;
                cIconName = "3gp";
            } else if (0 == strcmp(cExtenstion, "mpv")) {
                _fileCategory = FC_VIDEO;
                cIconName = "movie";
            } else if (0 == strcmp(cExtenstion, "m4v")) {
                _fileCategory = FC_VIDEO;
                cIconName = "movie";
            } else if (0 == strcmp(cExtenstion, "db")) {
                _fileCategory = FC_DATABASE;
                cIconName = "default";
            } else if (0 == strcmp(cExtenstion, "sqlite")) {
                _fileCategory = FC_DATABASE;
                cIconName = "default";
            } else if (0 == strcmp(cExtenstion, "sqlite3")) {
                _fileCategory = FC_DATABASE;
                cIconName = "default";
            } else if (0 == strcmp(cExtenstion, "zip")) {
                _fileCategory = FC_COMPRESSED;
            } else if (0 == strcmp(cExtenstion, "bz2")) {
                _fileCategory = FC_COMPRESSED;
            } else if (0 == strcmp(cExtenstion, "tar")) {
                _fileCategory = FC_COMPRESSED;
            } else if (0 == strcmp(cExtenstion, "tbz2")) {
                _fileCategory = FC_COMPRESSED;
            } else if (0 == strcmp(cExtenstion, "tgz")) {
                _fileCategory = FC_COMPRESSED;
            } else if (0 == strcmp(cExtenstion, "bin") || 0 == strcmp(cExtenstion, "dfu")) {
                _fileCategory = FC_BIN;
                cIconName = "default";
            } else {
                _fileCategory = FC_OTHERS;
                cIconName = "default";
            }
        }
        
        _iconName = [[NSString alloc] initWithFormat:@"fs/%s.png", cIconName];
    }
}

- (BOOL)isEqual:(FSFileItem *)otherItem {
    return (otherItem && otherItem->_fileNumber == _fileNumber);
}

- (void)dealloc {
}

- (NSArray *)subitems {
    if (_directory && nil == _subitems) {
        @autoreleasepool {
            NSArray *fileNames = [theFileManager contentsOfDirectoryAtPath:_path error:NULL];
            const NSInteger numberOfFiles = [fileNames count];
            NSMutableArray *subDirectories = [[NSMutableArray alloc] initWithCapacity:numberOfFiles];
            NSMutableArray *subFiles = [[NSMutableArray alloc] initWithCapacity:numberOfFiles];
            const FSSortingMode mode = UISettingsGetSortingMode();
            const FSSortingOrder sortingOrder = UISettingsGetSortingOrder();
            
            _subitems = [[NSMutableArray alloc] initWithCapacity:numberOfFiles];
            
            for (NSInteger i = numberOfFiles - 1; i >= 0; -- i) {
                NSString *name = [fileNames objectAtIndex:i];
                FSFileItem *newFileItem = [[FSFileItem alloc] initWithParentPath:_path fileName:name];
                
                if (newFileItem) {
                    NSMutableArray *sortedItems = newFileItem->_directory ? subDirectories : subFiles;
                    const NSInteger numberOfSortedItems = [sortedItems count];
                    NSInteger j = 0;
                    
                    while (j < numberOfSortedItems) {
                        FSFileItem *oldFileItem = [sortedItems objectAtIndex:j];
                        NSComparisonResult result;
                        
                        if (SORT_BY_SIZE == mode) {
                            if (newFileItem->_fileSize < oldFileItem->_fileSize) {
                                result = NSOrderedAscending;
                            } else if (newFileItem->_fileSize > oldFileItem->_fileSize) {
                                result = NSOrderedDescending;
                            } else {
                                result = NSOrderedSame;
                            }
                        } else if (SORT_BY_KIND == mode) {
                            result = [newFileItem->_extension caseInsensitiveCompare:oldFileItem->_extension];
                        } else if (SORT_BY_DATE == mode) {
                            result = [newFileItem->_creationTime caseInsensitiveCompare:oldFileItem->_creationTime];
                        } else {
                            result = [newFileItem->_fileName caseInsensitiveCompare:oldFileItem->_fileName];
                        }
                        if (sortingOrder == result) {
                            break;
                        }
                        j ++;
                    }
                    [sortedItems insertObject:newFileItem atIndex:j];
                    }
            }
            
            [_subitems addObjectsFromArray:subDirectories];
            [_subitems addObjectsFromArray:subFiles];
            
            }
    }
    return _subitems;
}

- (NSString *)statistic {
    if (_directory && nil == _statistic) {
        _statistic = [[NSString alloc] initWithFormat:@"%u %@", [[self subitems] count], LS(@"Items")];
    }
    return _statistic;
}

- (void)clearSubitems {
    if (_directory) {
        _subitems = nil;
        _statistic = nil;
    }
}

- (void)invertSelection {
    _selected = !_selected;
}

- (BOOL)isInboxDirectory {
    if ([_path hasPrefix:FSDocumentsDirectory]) {
        const NSRange range = { 0, [FSDocumentsDirectory length] };
        NSString *relativePath = [_path stringByReplacingCharactersInRange:range withString:NSStringEmpty];
        
        if (![relativePath isEqualToString:@"/Inbox"]) {
            return NO;
        }
    }
    return YES;
}

@end
