/*
HMFoundationUtil.m

Author: Makoto Kinoshita

Copyright 2004-2006 The Shiira Project. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted 
provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions 
  and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of 
  conditions and the following disclaimer in the documentation and/or other materials provided 
  with the distribution.

THIS SOFTWARE IS PROVIDED BY THE SHIIRA PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE SHIIRA PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
POSSIBILITY OF SUCH DAMAGE.
*/

#import "HMFoundationUtil.h"

//--------------------------------------------------------------//
#pragma mark -- String --
//--------------------------------------------------------------//

NSString* HMCreateUUID()
{
    // Create CFUUID
    CFUUIDRef   uuid;
    uuid = CFUUIDCreate(NULL);
    
    // Create UUID string
    NSString*   string;
    string = (NSString*)CFUUIDCreateString(NULL, uuid);
    [string autorelease];
    
    // Release CFUUID
    CFRelease(uuid);
    
    return string;
}

NSString* HMTruncateString(
        NSString* string, int trunctedLength, NSLineBreakMode breakMode)
{
    // Truncate string
    int length;
    length = [string length];
    if (length > trunctedLength) {
        static NSString*    _horizontalEllipsis = nil;
        if (!_horizontalEllipsis) {
            unichar uni[1];
            uni[0] = 0x2026;
            _horizontalEllipsis = [[NSString stringWithCharacters:uni length:1] retain];
        }
        
        // Switch by line break mode
        switch (breakMode) {
        case NSLineBreakByTruncatingHead: {
            string = [NSString stringWithFormat:@"%@%@", 
                    _horizontalEllipsis, 
                    [string substringWithRange:NSMakeRange(length - trunctedLength, trunctedLength)]];
            break;
        }
        case  NSLineBreakByTruncatingMiddle: {
            int half;
            half = trunctedLength / 2;
            string = [NSString stringWithFormat:@"%@%@%@", 
                    [string substringWithRange:NSMakeRange(0, half)], 
                    _horizontalEllipsis, 
                    [string substringWithRange:NSMakeRange(length - half, half)]];
            break;
        }
        case  NSLineBreakByTruncatingTail:
        default: {
            string = [NSString stringWithFormat:@"%@%@", 
                    [string substringWithRange:NSMakeRange(0, trunctedLength)], 
                    _horizontalEllipsis];
            break;
        }
        }
    }
    
    return string;
}

#pragma mark -

//--------------------------------------------------------------//
#pragma mark -- File operations --
//--------------------------------------------------------------//

BOOL HMCreateFile(NSString* filePath)
{
    return HMCreateDirectoryFile(filePath, NO);
}

BOOL HMCreateDirectoryFile(
        NSString* filePath, 
        BOOL directory)
{
    // Get path component
    NSArray*    components;
    components = [filePath pathComponents];
    
    NSFileManager*  fileMgr;
    fileMgr = [NSFileManager defaultManager];
    
    // Create directory and file
    NSEnumerator*   enumerator;
    NSString*       component;
    NSString*       path = @"";
    enumerator = [components objectEnumerator];
    while (component = [enumerator nextObject]) {
        // Create subpath
        path = [path stringByAppendingPathComponent:component];
        
        // Check existense
        if (![fileMgr fileExistsAtPath:path]) {
            // Create file
            if ([path isEqualToString:filePath] && !directory) {
                NSDictionary*   attr;
                attr = [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithInt:0644], NSFilePosixPermissions, nil];
                if (![fileMgr createFileAtPath:path contents:[NSData data] attributes:attr]) {
                    // Error
                    NSLog(@"Could not create file at %@", path);
                    return NO;
                }
            }
            // Create directory
            else {
                NSDictionary*   attr;
                attr = [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithInt:0755], NSFilePosixPermissions, nil];
                if (![fileMgr createDirectoryAtPath:path attributes:attr]) {
                    // Error
                    NSLog(@"Could not create directory at %@", path);
                    return NO;
                }
            }
        }
    }
    
    return YES;
}

NSString* HMCreateUniqueFileName(
        NSString* fileExtension)
{
    if (!fileExtension) {
        return HMCreateUUID();
    }
    else {
        return [NSString stringWithFormat:@"%@.%@", HMCreateUUID(), fileExtension];
    }
}

NSString* HMApplicationSupportFolder(
        NSString* appName)
{
    NSFileManager*	fileMgr;
    fileMgr = [NSFileManager defaultManager];
    
    // Get the paths of ~/Library/Application Support/
    NSArray*	libraryPaths;
    NSString*	libraryPath = nil;
    libraryPaths = NSSearchPathForDirectoriesInDomains(
            NSApplicationSupportDirectory, NSUserDomainMask, YES);
    if ([libraryPaths count] > 0) {
        libraryPath = [libraryPaths objectAtIndex:0];
    }
    
    if (!libraryPath || ![fileMgr fileExistsAtPath:libraryPath]) {
        // Error
        NSLog(@"Could not find applicaiton support directory");
        return nil;
    }
    
    // Check application name directory
    NSString*   path;
    path = [libraryPath stringByAppendingPathComponent:appName];
    if (![fileMgr fileExistsAtPath:path]) {
        // Create application name directory
        [fileMgr createDirectoryAtPath:path attributes:nil];
    }
    
    return path;
}

#pragma mark -

//--------------------------------------------------------------//
#pragma mark -- URL --
//--------------------------------------------------------------//

BOOL HMIsRSSURL(
        NSURL* url)
{
    // Check scheme
    NSString*   scheme;
    scheme = [url scheme];
    if ([scheme isEqualToString:@"feed"]) {
        return YES;
    }
    
    // Check path extension
    NSString*   extension;
    extension = [[url path] pathExtension];
    if ([extension isEqualToString:@"xml"] || 
        [extension isEqualToString:@"rdf"])
    {
        return YES;
    }
    
    return NO;
}

BOOL HMIsRSSURLString(
        NSString* URLString)
{
    return HMIsRSSURL([NSURL URLWithString:URLString]);
}

BOOL HMIsJavaScriptURL(
        NSURL* url)
{
    return HMIsJavaScriptURLString([url absoluteString]);
}

BOOL HMIsJavaScriptURLString(
        NSString* URLString)
{
    // Check scheme
    return [URLString hasPrefix:@"javascript:"];
}

#pragma mark -

//--------------------------------------------------------------//
#pragma mark -- Sorting --
//--------------------------------------------------------------//

NSArray* HMSortWithKey(
        NSArray* array, NSString* key, BOOL ascending)
{
    NSSortDescriptor*   sortDescriptor;
    NSArray*            sortedArray;
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending];
    sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
    [sortDescriptor release];
    
    return sortedArray;
}

#pragma mark -

//--------------------------------------------------------------//
#pragma mark -- Data size --
//--------------------------------------------------------------//

NSString* SRCreateDataSizeString(
        long long dataSize)
{
    // Byte
    if (dataSize < 1024) {
        return [NSString stringWithFormat:@"%d B", (int)dataSize];
    }
    // KByte
    if (dataSize < 1024 * 1024) {
        return [NSString stringWithFormat:@"%.1f KB", dataSize / 1024.0];
    }
    // MByte
    if (dataSize < 1024 * 1024 * 1024) {
        return [NSString stringWithFormat:@"%.2f MB", dataSize / (1024.0 * 1024.0)];
    }
    // GByte
    return [NSString stringWithFormat:@"%f.2 GB", dataSize / (1024.0 * 1024.0 * 1024.0)];
}
