//
//  Artwork.swift
//  Tag for iTunes
//
//  Created by Kim Wittenburg on 30.05.15.
//  Copyright (c) 2015 Kim Wittenburg. All rights reserved.
//

import Cocoa

/// Represents an Artwork from the
/// [Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html).
public class Artwork: iTunesType {
    
    // MARK: Properties
    
    /// The URL for the artwork, sized to 60x60 pixels.
    public let url60: NSURL
    
    /// The URL for the artwork, sized to 100x100 pixels.
    public let url100: NSURL
    
    /// The URL for the artwork with full resolution.
    ///
    /// - note: This URL is aquired by using an unofficial hack. If Apple changes
    ///         the way the full resolution artworks are stored this URL may be
    ///         `nil`.
    public let hiResURL: NSURL!
    
    // MARK: Initializers
    
    public required init(data: [iTunesAPI.Field: AnyObject]) {
        url60 = NSURL(string: data[.ArtworkUrl60] as! String)!
        url100 = NSURL(string: data[.ArtworkUrl100] as! String)!
        var hiResURLString = (data[.ArtworkUrl100] as! String)
        let hotSpotRange = hiResURLString.rangeOfString("100x100", options: .BackwardsSearch, range: nil, locale: nil)!
        hiResURLString.replaceRange(hotSpotRange, with: "1500x1500")
        hiResURL = NSURL(string: hiResURLString)
    }
    
    public static var requiredFields: [iTunesAPI.Field] {
        return [.ArtworkUrl60, .ArtworkUrl100]
    }
    
    // MARK: Methods
    
    /// Saves the high resolution artwork to the specified URL. If there is
    /// alread a file at the specified URL it will be overwritten.
    ///
    /// - parameters:
    ///   - url: The URL of the directory the artwork is going to be saved to.
    ///          This must be a valid file URL.
    ///   - filename: The filename to be used (without the file extension).
    public func saveToURL(url: NSURL, filename: String) throws {
        let directory = url.filePathURL!.path!
        let filePath = directory.stringByAppendingString("/\(filename).tiff")
        
        if !Preferences.sharedPreferences.overwriteExistingFiles && NSFileManager.defaultManager().fileExistsAtPath(filePath) {
            return
        }
            
        try NSFileManager.defaultManager().createDirectoryAtPath(directory, withIntermediateDirectories: true, attributes: nil)
        let _ = NSFileManager.defaultManager().createFileAtPath(filePath, contents: saveImage?.TIFFRepresentation, attributes: nil)
    }

    // MARK: Calculated Properties
    
    private var cachedImage60: NSImage?
    
    /// Returns an `NSImage` instance of the image located at `url60`.
    ///
    /// - attention: The first time this method is called the current thread will
    ///              be blocked until the image is loaded.
    public var image60: NSImage? {
        if cachedImage60 == nil {
            cachedImage60 = NSImage(byReferencingURL: url60)
        }
        return cachedImage60
    }
    
    private var cachedImage100: NSImage?
    
    /// Returns an `NSImage` instance of the image located at `url100`.
    ///
    /// - attention: The first time this method is called the current thread will
    ///              be blocked until the image is loaded.
    public var image100: NSImage? {
        if cachedImage100 == nil {
            cachedImage100 = NSImage(byReferencingURL: url100)
        }
        return cachedImage100
    }
    
    private var cachedHiResImage: NSImage?
    
    /// Returns an `NSImage` instance of the image located at `hiResURL`.
    ///
    /// - attention: The first time this method is called the current thread will
    ///              be blocked until the image is loaded.
    public var hiResImage: NSImage? {
        if hiResURL == nil {
            return nil
        }
        if cachedHiResImage == nil {
            cachedHiResImage = NSImage(byReferencingURL: hiResURL)
        }
        return cachedHiResImage
    }
    
    /// Returns the url of an image that should be used to display this artwork
    /// with respect to the user's preferences.
    public var displayImageURL: NSURL {
        if !Preferences.sharedPreferences.useLowResolutionArtwork && hiResURL != nil {
            return hiResURL
        }
        return url100
    }
    
    /// Returns the image that should be used to save this artwork.
    public var saveImage: NSImage? {
        return hiResImage != nil ? hiResImage : image100
    }
    
}
