#import <CoreFoundation/CoreFoundation.h>
#import <CoreServices/CoreServices.h>
#import <QuickLook/QuickLook.h>

#import <Foundation/Foundation.h>

//START:QLPreviewBuildUp
NSString *bundleID = @"com.pragprog.quicklook.grokkingrecipe";

OSStatus GeneratePreviewForURL(void *thisInterface, 
                               QLPreviewRequestRef preview, 
                               CFURLRef url, 
                               CFStringRef contentTypeUTI, 
                               CFDictionaryRef options)
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  @try {
    NSDictionary *metadata;
    metadata = [NSDictionary dictionaryWithContentsOfURL:(NSURL*)url];
    if (!metadata) return noErr;
    NSLog(@"metadata: %@", metadata);
    
    NSString *imagePath = [metadata valueForKey:@"kPPImagePath"];
    NSData *imageData = [[NSData alloc] initWithContentsOfFile:imagePath];
    if (!imageData) return noErr;
    //END:QLPreviewBuildUp
    //START:QLPreviewHTMLBuildUp
    NSMutableDictionary *imageDict = [NSMutableDictionary dictionary];
    [imageDict setValue:imageData 
                 forKey:(id)kQLPreviewPropertyAttachmentDataKey];
    
    if (QLPreviewRequestIsCancelled(preview)) return noErr;
    
    NSMutableDictionary *attachments = [NSMutableDictionary dictionary];
    [attachments setValue:imageDict forKey:@"preview-image"];
    
    NSMutableDictionary *properties = [NSMutableDictionary dictionary];
    [properties setValue:attachments 
                  forKey:(id)kQLPreviewPropertyAttachmentsKey];
    [properties setValue:@"text/html" 
                  forKey:(id)kQLPreviewPropertyMIMETypeKey];
    [properties setValue:@"UTF-8" 
                  forKey:(id)kQLPreviewPropertyTextEncodingNameKey];
    [properties setValue:@"Recipe" 
                  forKey:(id)kQLPreviewPropertyDisplayNameKey];
    
    //END:QLPreviewHTMLBuildUp
    //START:QLPreviewHTMLLoad
    NSBundle *bundle = [NSBundle bundleWithIdentifier:bundleID];
    NSString *templatePath = [bundle pathForResource:@"preview" ofType:@"html"];
    NSURL *templateURL = [NSURL fileURLWithPath:templatePath];
        
    NSError *error = nil;
    NSXMLDocument *template;
    template = [[[NSXMLDocument alloc] initWithContentsOfURL:(NSURL*)templateURL 
                                                   options:NSXMLDocumentTidyHTML 
                                                     error:&error] autorelease];
    if (!template) {
      NSLog(@"Failed to build template: %@", error);
      return noErr;
    }
    //END:QLPreviewHTMLLoad
    //START:QLPreviewHTMLPopulate
    //Updating the Title
    error = nil;
    NSXMLElement *element = [[template nodesForXPath:
                              @"/html/body/div/*[@id='title']" 
                                               error:&error] lastObject];
    if (!element) {
      NSLog(@"Failed to find element: %@", error);
      return noErr;
    }
    [element setStringValue:[metadata valueForKey:(id)kMDItemDisplayName]];
    
    //Updating the description
    error = nil;
    element = [[template nodesForXPath:@"/html/body/div/*[@id='description']" 
                                 error:&error] lastObject];
    if (!element) {
      NSLog(@"Failed to find element: %@", error);
      return noErr;
    }
    [element setStringValue:[metadata valueForKey:(id)kMDItemTextContent]];
    
    //Updating the serves value
    error = nil;
    element = [[template nodesForXPath:@"/html/body/div/*[@id='serves']" 
                                 error:&error] lastObject];
    if (!element) {
      NSLog(@"Failed to find element: %@", error);
      return noErr;
    }
    NSNumber *serves = [metadata valueForKey:@"kPPServes"];
    [element setStringValue:[NSString stringWithFormat:@"Serves: %i", 
                             [serves integerValue]]];
    
    //Updating the last served value
    error = nil;
    element = [[template nodesForXPath:@"/html/body/div/*[@id='last_served']" 
                                 error:&error] lastObject];
    if (!element) {
      NSLog(@"Failed to find element: %@", error);
      return noErr;
    }
    NSDate *lastServedDate = [metadata valueForKey:(id)kMDItemLastUsedDate];
    if (lastServedDate) {
      NSDateFormatter *dateFormatter;
      dateFormatter = [[[NSDateFormatter alloc] init]  autorelease];
      [dateFormatter setDateStyle:NSDateFormatterMediumStyle];
      [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
      [element setStringValue:[NSString stringWithFormat:@"Last Served: %@", 
                               [dateFormatter stringFromDate:lastServedDate]]];
    } else {
      [element setStringValue:@"Last Served: Never"];
    }
    //END:QLPreviewHTMLPopulate
                   
    //START:QLPreviewWrapUp
    QLPreviewRequestSetDataRepresentation(preview, 
                                          (CFDataRef)[template XMLData], 
                                          kUTTypeHTML, 
                                          (CFDictionaryRef)properties);
  } @finally {
    [pool release], pool = nil;
  }
  return noErr;
}
//END:QLPreviewWrapUp

void CancelPreviewGeneration(void* thisInterface, QLPreviewRequestRef preview)
{
    // implement only if supported
}
