OSDN Git Service

MacGui: Sparkle Updater preferences changes.
[handbrake-jp/handbrake-jp-git.git] / macosx / Controller.mm
index 5072e61..6ca4fdc 100644 (file)
@@ -9,15 +9,18 @@
 #import "HBPreferencesController.h"
 #import "HBDVDDetector.h"
 #import "HBPresets.h"
+#import "HBPreviewController.h"
 
 #define DragDropSimplePboardType       @"MyCustomOutlineViewPboardType"
 
-/* We setup the toolbar values here */
+/* We setup the toolbar values here ShowPreviewIdentifier */
 static NSString *        ToggleDrawerIdentifier             = @"Toggle Drawer Item Identifier";
 static NSString *        StartEncodingIdentifier            = @"Start Encoding Item Identifier";
 static NSString *        PauseEncodingIdentifier            = @"Pause Encoding Item Identifier";
 static NSString *        ShowQueueIdentifier                = @"Show Queue Item Identifier";
 static NSString *        AddToQueueIdentifier               = @"Add to Queue Item Identifier";
+static NSString *        ShowPictureIdentifier             = @"Show Picture Window Item Identifier";
+static NSString *        ShowPreviewIdentifier             = @"Show Preview Window Item Identifier";
 static NSString *        ShowActivityIdentifier             = @"Debug Output Item Identifier";
 static NSString *        ChooseSourceIdentifier             = @"Choose Source Item Identifier";
 
@@ -35,6 +38,15 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         return nil;
     }
 
+    /* replace bundled app icon with one which is 32/64-bit savvy */
+#if defined( __LP64__ )
+    fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake-64.icns"]];
+#else
+    fApplicationIcon = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForImageResource:@"HandBrake.icns"]];
+#endif
+    if( fApplicationIcon != nil )
+        [NSApp setApplicationIconImage:fApplicationIcon];
+    
     [HBPreferencesController registerUserDefaults];
     fHandle = NULL;
     fQueueEncodeLibhb = NULL;
@@ -42,28 +54,34 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
      * outputPanel needs it right away, as may other future methods
      */
     NSString *libraryDir = [NSSearchPathForDirectoriesInDomains( NSLibraryDirectory,
-                                                                 NSUserDomainMask,
-                                                                 YES ) objectAtIndex:0];
+                                                                NSUserDomainMask,
+                                                                YES ) objectAtIndex:0];
     AppSupportDirectory = [[libraryDir stringByAppendingPathComponent:@"Application Support"]
-                                       stringByAppendingPathComponent:@"HandBrake"];
+                           stringByAppendingPathComponent:@"HandBrake"];
     if( ![[NSFileManager defaultManager] fileExistsAtPath:AppSupportDirectory] )
     {
         [[NSFileManager defaultManager] createDirectoryAtPath:AppSupportDirectory
                                                    attributes:nil];
     }
-
+    /* Check for and create the App Support Preview directory if necessary */
+    NSString *PreviewDirectory = [AppSupportDirectory stringByAppendingPathComponent:@"Previews"];
+    if( ![[NSFileManager defaultManager] fileExistsAtPath:PreviewDirectory] )
+    {
+        [[NSFileManager defaultManager] createDirectoryAtPath:PreviewDirectory
+                                                   attributes:nil];
+    }                                                            
     outputPanel = [[HBOutputPanelController alloc] init];
-    fPictureController = [[PictureController alloc] initWithDelegate:self];
+    fPictureController = [[PictureController alloc] init];
     fQueueController = [[HBQueueController alloc] init];
     fAdvancedOptions = [[HBAdvancedController alloc] init];
     /* we init the HBPresets class which currently is only used
-    * for updating built in presets, may move more functionality
-    * there in the future
-    */
+     * for updating built in presets, may move more functionality
+     * there in the future
+     */
     fPresetsBuiltin = [[HBPresets alloc] init];
     fPreferencesController = [[HBPreferencesController alloc] init];
     /* Lets report the HandBrake version number here to the activity log and text log file */
-    NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleGetInfoString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
+    NSString *versionStringFull = [[NSString stringWithFormat: @"Handbrake Version: %@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]] stringByAppendingString: [NSString stringWithFormat: @" (%@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]];
     [self writeToActivityLog: "%s", [versionStringFull UTF8String]];    
     
     return self;
@@ -73,26 +91,42 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 - (void) applicationDidFinishLaunching: (NSNotification *) notification
 {
     /* Init libhb with check for updates libhb style set to "0" so its ignored and lets sparkle take care of it */
-    fHandle = hb_init(HB_DEBUG_ALL, 0);
+    int loggingLevel = [[[NSUserDefaults standardUserDefaults] objectForKey:@"LoggingLevel"] intValue];
+    fHandle = hb_init(loggingLevel, 0);
+    /* Optional dvd nav UseDvdNav*/
+    hb_dvd_set_dvdnav([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue]);
     /* Init a separate instance of libhb for user scanning and setting up jobs */
-    fQueueEncodeLibhb = hb_init(HB_DEBUG_ALL, 0);
+    fQueueEncodeLibhb = hb_init(loggingLevel, 0);
     
        // Set the Growl Delegate
     [GrowlApplicationBridge setGrowlDelegate: self];
     /* Init others controllers */
     [fPictureController SetHandle: fHandle];
+    [fPictureController   setHBController: self];
+    
     [fQueueController   setHandle: fQueueEncodeLibhb];
     [fQueueController   setHBController: self];
 
     fChapterTitlesDelegate = [[ChapterTitles alloc] init];
     [fChapterTable setDataSource:fChapterTitlesDelegate];
     [fChapterTable setDelegate:fChapterTitlesDelegate];
+    
+    /* setup the subtitles delegate and connections to table */
+    fSubtitlesDelegate = [[HBSubtitles alloc] init];
+    [fSubtitlesTable setDataSource:fSubtitlesDelegate];
+    [fSubtitlesTable setDelegate:fSubtitlesDelegate];
+    [fSubtitlesTable setRowHeight:25.0];
+    
+    [fPresetsOutlineView setAutosaveName:@"Presets View"];
+    [fPresetsOutlineView setAutosaveExpandedItems:YES];
+    
+    dockIconProgress = 0;
 
     /* Call UpdateUI every 1/2 sec */
     [[NSRunLoop currentRunLoop] addTimer:[NSTimer
                                           scheduledTimerWithTimeInterval:0.5 target:self
                                           selector:@selector(updateUI:) userInfo:nil repeats:YES]
-                                 forMode:NSEventTrackingRunLoopMode];
+                                 forMode:NSDefaultRunLoopMode];
 
     // Open debug output window now if it was visible when HB was closed
     if ([[NSUserDefaults standardUserDefaults] boolForKey:@"OutputPanelIsOpen"])
@@ -114,26 +148,94 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
      * user if they want to reload the queue */
     if ([QueueFileArray count] > 0)
        {
+        /* run  getQueueStats to see whats in the queue file */
+        [self getQueueStats];
+        /* this results in these values
+         * fEncodingQueueItem = 0;
+         * fPendingCount = 0;
+         * fCompletedCount = 0;
+         * fCanceledCount = 0;
+         * fWorkingCount = 0;
+         */
+        
         /*On Screen Notification*/
-        NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"HandBrake Has Detected Item(s) From Your Previous Queue.", nil)];
+        NSString * alertTitle;
+        
+        /* We check to see if there is already another instance of hb running.
+         * Note: hbInstances == 1 means we are the only instance of HandBrake.app
+         */
+        if ([self hbInstances] > 1)
+        {
+        alertTitle = [NSString stringWithFormat:
+                         NSLocalizedString(@"There is already an instance of HandBrake running.", @"")];
         NSBeginCriticalAlertSheet(
-            alertTitle,
-            NSLocalizedString(@"Reload Queue", nil),
-            nil,
-            NSLocalizedString(@"Empty Queue", nil),
-            fWindow, self,
-            nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
-            NSLocalizedString(@" Do you want to reload them ?", nil));
+                                      alertTitle,
+                                      NSLocalizedString(@"Reload Queue", nil),
+                                      nil,
+                                      nil,
+                                      fWindow, self,
+                                      nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
+                                      NSLocalizedString(@" HandBrake will now load up the existing queue.", nil));    
+        }
+        else
+        {
+            if (fWorkingCount > 0)
+            {
+                alertTitle = [NSString stringWithFormat:
+                              NSLocalizedString(@"HandBrake Has Detected %d Previously Encoding Item and %d Pending Item(s) In Your Queue.", @""),
+                              fWorkingCount,fPendingCount];
+            }
+            else
+            {
+                alertTitle = [NSString stringWithFormat:
+                              NSLocalizedString(@"HandBrake Has Detected %d Pending Item(s) In Your Queue.", @""),
+                              fPendingCount];
+            }
+            
+            NSBeginCriticalAlertSheet(
+                                      alertTitle,
+                                      NSLocalizedString(@"Reload Queue", nil),
+                                      nil,
+                                      NSLocalizedString(@"Empty Queue", nil),
+                                      fWindow, self,
+                                      nil, @selector(didDimissReloadQueue:returnCode:contextInfo:), nil,
+                                      NSLocalizedString(@" Do you want to reload them ?", nil));
+        }
+        
         // call didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
         // right below to either clear the old queue or keep it loaded up.
     }
     else
     {
-     
-    /* Show Browse Sources Window ASAP */
-    [self performSelectorOnMainThread:@selector(browseSources:)
-                           withObject:nil waitUntilDone:NO];
-   }
+        /* We show whichever open source window specified in LaunchSourceBehavior preference key */
+        if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+        {
+            [self browseSources:nil];
+        }
+        
+        if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
+        {
+            [self browseSources:(id)fOpenSourceTitleMMenu];
+        }
+    }
+}
+
+- (int) hbInstances
+{
+    /* check to see if another instance of HandBrake.app is running */
+    NSArray *runningAppDictionaries = [[NSWorkspace sharedWorkspace] launchedApplications];
+    NSDictionary *aDictionary;
+    int hbInstances = 0;
+    for (aDictionary in runningAppDictionaries)
+       {
+        //     NSLog(@"Open App: %@", [aDictionary valueForKey:@"NSApplicationName"]);
+        
+        if ([[aDictionary valueForKey:@"NSApplicationName"] isEqualToString:@"HandBrake"])
+               {
+            hbInstances++;
+               }
+       }
+    return hbInstances;
 }
 
 - (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
@@ -141,28 +243,51 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     if (returnCode == NSAlertOtherReturn)
     {
         [self clearQueueAllItems];
+        /* We show whichever open source window specified in LaunchSourceBehavior preference key */
+        if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source"])
+        {
+            [self browseSources:nil];
+        }
+        
+        if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"LaunchSourceBehavior"] isEqualToString: @"Open Source (Title Specific)"])
+        {
+            [self browseSources:(id)fOpenSourceTitleMMenu];
+        }
+    }
+    else
+    {
+        if ([self hbInstances] == 1)
+        {
+            [self setQueueEncodingItemsAsPending];
+        }
+        [self showQueueWindow:NULL];
     }
-    
-    [self performSelectorOnMainThread:@selector(browseSources:)
-                           withObject:nil waitUntilDone:NO];
 }
 
 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
 {
-    // Warn if encoding a movie
+    /* if we are in preview full screen mode, we need to go to
+     * windowed mode and release the display before we terminate.
+     * We do it here (instead of applicationWillTerminate) so we 
+     * release the displays and can then see the alerts below.
+     */
+    if ([fPictureController previewFullScreenMode] == YES)
+    {
+        [fPictureController previewGoWindowed:nil];
+    }
+    
     hb_state_t s;
-    hb_get_state( fHandle, &s );
+    hb_get_state( fQueueEncodeLibhb, &s );
     
     if ( s.state != HB_STATE_IDLE )
     {
         int result = NSRunCriticalAlertPanel(
-                NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
-                NSLocalizedString(@"If you quit HandBrake, your movie will be lost. Do you want to quit anyway?", nil),
-                NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil, @"A movie" );
+                                             NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
+                                             NSLocalizedString(@"If you quit HandBrake your current encode will be reloaded into your queue at next launch. Do you want to quit anyway?", nil),
+                                             NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil, @"A movie" );
         
         if (result == NSAlertDefaultReturn)
         {
-            [self doCancelCurrentJob];
             return NSTerminateNow;
         }
         else
@@ -170,12 +295,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     }
     
     // Warn if items still in the queue
-    else if ( hb_count( fHandle ) > 0 )
+    else if ( fPendingCount > 0 )
     {
         int result = NSRunCriticalAlertPanel(
-                NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
-                NSLocalizedString(@"One or more encodes are queued for encoding. Do you want to quit anyway?", nil),
-                NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil);
+                                             NSLocalizedString(@"Are you sure you want to quit HandBrake?", nil),
+                                             NSLocalizedString(@"There are pending encodes in your queue. Do you want to quit anyway?",nil),
+                                             NSLocalizedString(@"Quit", nil), NSLocalizedString(@"Don't Quit", nil), nil);
         
         if ( result == NSAlertDefaultReturn )
             return NSTerminateNow;
@@ -188,9 +313,14 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 
 - (void)applicationWillTerminate:(NSNotification *)aNotification
 {
-       [browsedSourceDisplayName release];
+    
+    [browsedSourceDisplayName release];
     [outputPanel release];
        [fQueueController release];
+    [fPreviewController release];
+    [fPictureController release];
+    [fApplicationIcon release];
+
        hb_close(&fHandle);
     hb_close(&fQueueEncodeLibhb);
 }
@@ -201,17 +331,17 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     [fWindow center];
     [fWindow setExcludedFromWindowsMenu:YES];
     [fAdvancedOptions setView:fAdvancedView];
-
+    
     /* lets setup our presets drawer for drag and drop here */
     [fPresetsOutlineView registerForDraggedTypes: [NSArray arrayWithObject:DragDropSimplePboardType] ];
     [fPresetsOutlineView setDraggingSourceOperationMask:NSDragOperationEvery forLocal:YES];
     [fPresetsOutlineView setVerticalMotionCanBeginDrag: YES];
-
+    
     /* Initialize currentScanCount so HB can use it to
-               evaluate successive scans */
+     evaluate successive scans */
        currentScanCount = 0;
-
-
+    
+    
     /* Init UserPresets .plist */
        [self loadPresets];
     
@@ -219,15 +349,38 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     [self loadQueueFile];
        
     fRipIndicatorShown = NO;  // initially out of view in the nib
+    
+    /* For 64 bit builds, the threaded animation in the progress
+     * indicators conflicts with the animation in the advanced tab
+     * for reasons not completely clear. jbrjake found a note in the
+     * 10.5 dev notes regarding this possiblility. It was also noted
+     * that unless specified, setUsesThreadedAnimation defaults to true.
+     * So, at least for now we set the indicator animation to NO for
+     * both the scan and regular progress indicators for both 32 and 64 bit
+     * as it test out fine on both and there is no reason our progress indicators
+     * should require their own thread.
+     */
 
+    [fScanIndicator setUsesThreadedAnimation:NO];
+    [fRipIndicator setUsesThreadedAnimation:NO];
+  
+    
+    
        /* Show/Dont Show Presets drawer upon launch based
-               on user preference DefaultPresetsDrawerShow*/
-       if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0)
+     on user preference DefaultPresetsDrawerShow*/
+       if( [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultPresetsDrawerShow"] > 0 )
        {
+        [fPresetDrawer setDelegate:self];
+        NSSize drawerSize = NSSizeFromString( [[NSUserDefaults standardUserDefaults] 
+                                               stringForKey:@"Drawer Size"] );
+        if( drawerSize.width )
+            [fPresetDrawer setContentSize: drawerSize];
                [fPresetDrawer open];
        }
-       
-       
+    
+    /* Initially set the dvd angle widgets to hidden (dvdnav only) */
+    [fSrcAngleLabel setHidden:YES];
+    [fSrcAnglePopUp setHidden:YES];
     
     /* Destination box*/
     NSMenuItem *menuItem;
@@ -238,43 +391,37 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
        // MKV file
     menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"MKV file" action: NULL keyEquivalent: @""];
     [menuItem setTag: HB_MUX_MKV];
-    // AVI file
-    menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"AVI file" action: NULL keyEquivalent: @""];
-    [menuItem setTag: HB_MUX_AVI];
-    // OGM file
-    menuItem = [[fDstFormatPopUp menu] addItemWithTitle:@"OGM file" action: NULL keyEquivalent: @""];
-    [menuItem setTag: HB_MUX_OGM];
+    
     [fDstFormatPopUp selectItemAtIndex: 0];
-
+    
     [self formatPopUpChanged:nil];
-
+    
        /* We enable the create chapters checkbox here since we are .mp4 */
        [fCreateChapterMarkers setEnabled: YES];
        if ([fDstFormatPopUp indexOfSelectedItem] == 0 && [[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultChapterMarkers"] > 0)
        {
                [fCreateChapterMarkers setState: NSOnState];
        }
-
-
-
-
+    
+    
+    
+    
     [fDstFile2Field setStringValue: [NSString stringWithFormat:
-        @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
-
+                                     @"%@/Desktop/Movie.mp4", NSHomeDirectory()]];
+    
     /* Video encoder */
     [fVidEncoderPopUp removeAllItems];
     [fVidEncoderPopUp addItemWithTitle: @"FFmpeg"];
-    [fVidEncoderPopUp addItemWithTitle: @"XviD"];
-
-
-
+    
+    
+    
     /* Video quality */
     [fVidTargetSizeField setIntValue: 700];
        [fVidBitrateField    setIntValue: 1000];
-
+    
     [fVidQualityMatrix   selectCell: fVidBitrateCell];
     [self videoMatrixChanged:nil];
-
+    
     /* Video framerate */
     [fVidRatePopUp removeAllItems];
        [fVidRatePopUp addItemWithTitle: NSLocalizedString( @"Same as source", @"" )];
@@ -283,22 +430,22 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.3f",23.976]])
                {
                        [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
-                               [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
+                                             [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Film)"]];
                }
                else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%d",25]])
                {
                        [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
-                               [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
+                                             [NSString stringWithCString: hb_video_rates[i].string], @" (PAL Film/Video)"]];
                }
                else if ([[NSString stringWithCString: hb_video_rates[i].string] isEqualToString: [NSString stringWithFormat: @"%.2f",29.97]])
                {
                        [fVidRatePopUp addItemWithTitle:[NSString stringWithFormat: @"%@%@",
-                               [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
+                                             [NSString stringWithCString: hb_video_rates[i].string], @" (NTSC Video)"]];
                }
                else
                {
                        [fVidRatePopUp addItemWithTitle:
-                               [NSString stringWithCString: hb_video_rates[i].string]];
+             [NSString stringWithCString: hb_video_rates[i].string]];
                }
     }
     [fVidRatePopUp selectItemAtIndex: 0];
@@ -311,8 +458,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     for( int i = 0; i < hb_audio_bitrates_count; i++ )
     {
         [fAudTrack1BitratePopUp addItemWithTitle:
-                               [NSString stringWithCString: hb_audio_bitrates[i].string]];
-
+         [NSString stringWithCString: hb_audio_bitrates[i].string]];
+        
     }
     [fAudTrack1BitratePopUp selectItemAtIndex: hb_audio_bitrates_default];
        
@@ -321,39 +468,38 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     for( int i = 0; i < hb_audio_rates_count; i++ )
     {
         [fAudTrack1RatePopUp addItemWithTitle:
-            [NSString stringWithCString: hb_audio_rates[i].string]];
+         [NSString stringWithCString: hb_audio_rates[i].string]];
     }
     [fAudTrack1RatePopUp selectItemAtIndex: hb_audio_rates_default];
        
     /* Bottom */
     [fStatusField setStringValue: @""];
-
+    
     [self enableUI: NO];
        [self setupToolbar];
-
+    
        /* We disable the Turbo 1st pass checkbox since we are not x264 */
        [fVidTurboPassCheck setEnabled: NO];
        [fVidTurboPassCheck setState: NSOffState];
-
-
+    
+    
        /* lets get our default prefs here */
        [self getDefaultPresets:nil];
        /* lets initialize the current successful scancount here to 0 */
        currentSuccessfulScanCount = 0;
-
-
+    
+    
 }
 
 - (void) enableUI: (bool) b
 {
     NSControl * controls[] =
-      { fSrcTitleField, fSrcTitlePopUp,
+    { fSrcTitleField, fSrcTitlePopUp,
         fSrcChapterField, fSrcChapterStartPopUp, fSrcChapterToField,
         fSrcChapterEndPopUp, fSrcDuration1Field, fSrcDuration2Field,
         fDstFormatField, fDstFormatPopUp, fDstFile1Field, fDstFile2Field,
-        fDstBrowseButton, fVidRateField, fVidRatePopUp,
-        fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
-        fVidQualityMatrix, fVidGrayscaleCheck, fSubField, fSubPopUp,
+        fDstBrowseButton, fVidRateField, fVidRatePopUp,fVidEncoderField, fVidEncoderPopUp, fVidQualityField,
+        fPictureSizeField,fPictureCroppingField, fVideoFiltersField,fVidQualityMatrix, fSubField, fSubPopUp,
         fAudSourceLabel, fAudCodecLabel, fAudMixdownLabel, fAudSamplerateLabel, fAudBitrateLabel,
         fAudTrack1Label, fAudTrack2Label, fAudTrack3Label, fAudTrack4Label,
         fAudLang1PopUp, fAudLang2PopUp, fAudLang3PopUp, fAudLang4PopUp,
@@ -363,16 +509,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         fAudTrack1BitratePopUp, fAudTrack2BitratePopUp, fAudTrack3BitratePopUp, fAudTrack4BitratePopUp,
         fAudDrcLabel, fAudTrack1DrcSlider, fAudTrack1DrcField, fAudTrack2DrcSlider,
         fAudTrack2DrcField, fAudTrack3DrcSlider, fAudTrack3DrcField, fAudTrack4DrcSlider,fAudTrack4DrcField,
-        fPictureButton,fQueueStatus,fPicSettingARkeep, fPicSettingDeinterlace,fPicLabelSettings,fPicLabelSrc,
-        fPicLabelOutp,fPicSettingsSrc,fPicSettingsOutp,fPicSettingsAnamorphic,
-               fPicLabelAr,fPicLabelDeinterlace,fPicSettingPAR,fPicLabelAnamorphic,fPresetsAdd,fPresetsDelete,
-               fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fPicLabelAutoCrop,
-               fPicSettingAutoCrop,fPicSettingDetelecine,fPicLabelDetelecine,fPicLabelDenoise,fPicSettingDenoise,
-        fSubForcedCheck,fPicSettingDeblock,fPicLabelDeblock,fPicLabelDecomb,fPicSettingDecomb,fPresetsOutlineView,
-        fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck};
-
+        fQueueStatus,fPresetsAdd,fPresetsDelete,fSrcAngleLabel,fSrcAnglePopUp,
+               fCreateChapterMarkers,fVidTurboPassCheck,fDstMp4LargeFileCheck,fSubForcedCheck,fPresetsOutlineView,
+    fAudDrcLabel,fDstMp4HttpOptFileCheck,fDstMp4iPodFileCheck,fVidQualityRFField,fVidQualityRFLabel};
+    
     for( unsigned i = 0;
-         i < sizeof( controls ) / sizeof( NSControl * ); i++ )
+        i < sizeof( controls ) / sizeof( NSControl * ); i++ )
     {
         if( [[controls[i] className] isEqualToString: @"NSTextField"] )
         {
@@ -380,29 +522,28 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             if( ![tf isBezeled] )
             {
                 [tf setTextColor: b ? [NSColor controlTextColor] :
-                    [NSColor disabledControlTextColor]];
+                 [NSColor disabledControlTextColor]];
                 continue;
             }
         }
         [controls[i] setEnabled: b];
-
+        
     }
-
+    
        if (b) {
-
+        
         /* if we're enabling the interface, check if the audio mixdown controls need to be enabled or not */
         /* these will have been enabled by the mass control enablement above anyway, so we're sense-checking it here */
         [self setEnabledStateOfAudioMixdownControls:nil];
         /* we also call calculatePictureSizing here to sense check if we already have vfr selected */
         [self calculatePictureSizing:nil];
-        [self shouldEnableHttpMp4CheckBox: nil];
-
+        
        } else {
-
+        
                [fPresetsOutlineView setEnabled: NO];
-
+        
        }
-
+    
     [self videoMatrixChanged:nil];
     [fAdvancedOptions enableUI:b];
 }
@@ -526,7 +667,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                                             NSLocalizedString( @"Scanning title %d of %d...", @"" ),
                                             p.title_cur, p.title_count]];
             [fScanIndicator setHidden: NO];
-            [fScanIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
+            [fScanIndicator setDoubleValue: 100.0 * ((double)( p.title_cur - 1 ) / p.title_count)];
             break;
                }
 #undef p
@@ -598,8 +739,11 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             [fStatusField setStringValue: [NSString stringWithFormat:
                                            NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
                                            p.title_cur, p.title_count]];
-            [fRipIndicator setHidden: NO];
-            [fRipIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
+            
+            /* Set the status string in fQueueController as well */                               
+            [fQueueController setQueueStatusString: [NSString stringWithFormat:
+                                                     NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
+                                                     p.title_cur, p.title_count]];
             break;
                }
 #undef p
@@ -607,9 +751,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 #define p s.param.scandone
         case HB_STATE_SCANDONE:
         {
-            [fRipIndicator setIndeterminate: NO];
-            [fRipIndicator setDoubleValue: 0.0];
-            
                        [self writeToActivityLog:"ScanDone state received from fQueueEncodeLibhb"];
             [self processNewQueueEncode];
             [[fWindow toolbar] validateVisibleItems];
@@ -621,7 +762,6 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 #define p s.param.working
         case HB_STATE_WORKING:
         {
-            float progress_total;
             NSMutableString * string;
                        /* Update text field */
                        string = [NSMutableString stringWithFormat: NSLocalizedString( @"Encoding: pass %d of %d, %.2f %%", @"" ), p.job_cur, p.job_count, 100.0 * p.progress];
@@ -634,11 +774,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             
             [fStatusField setStringValue: string];
-            
+            /* Set the status string in fQueueController as well */
+            [fQueueController setQueueStatusString: string];
             /* Update slider */
-                       progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
+            CGFloat progress_total = ( p.progress + p.job_cur - 1 ) / p.job_count;
             [fRipIndicator setIndeterminate: NO];
-            [fRipIndicator setDoubleValue: 100.0 * progress_total];
+            [fRipIndicator setDoubleValue:100.0 * progress_total];
             
             // If progress bar hasn't been revealed at the bottom of the window, do
             // that now. This code used to be in doRip. I moved it to here to handle
@@ -653,14 +794,16 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 frame.origin.y -= 36;
                 [fWindow setFrame:frame display:YES animate:YES];
                 fRipIndicatorShown = YES;
-                /* We check to see if we need to warn the user that the computer will go to sleep
-                 or shut down when encoding is finished */
-                [self remindUserOfSleepOrShutdown];
+                
             }
-            
+
             /* Update dock icon */
-            [self UpdateDockIcon: progress_total];
-            
+            if( dockIconProgress < 100.0 * progress_total )
+            {
+                [self UpdateDockIcon: progress_total];
+                dockIconProgress += 5;
+            }
+
             break;
         }
 #undef p
@@ -670,7 +813,8 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         {
             /* Update text field */
             [fStatusField setStringValue: NSLocalizedString( @"Muxing...", @"" )];
-            
+            /* Set the status string in fQueueController as well */
+            [fQueueController setQueueStatusString: NSLocalizedString( @"Muxing...", @"" )];
             /* Update slider */
             [fRipIndicator setIndeterminate: YES];
             [fRipIndicator startAnimation: nil];
@@ -684,6 +828,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             
         case HB_STATE_PAUSED:
                    [fStatusField setStringValue: NSLocalizedString( @"Paused", @"" )];
+            [fQueueController setQueueStatusString: NSLocalizedString( @"Paused", @"" )];
             
                        break;
             
@@ -694,13 +839,17 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             // out the remaining passes/jobs in the queue. We'll do that here.
             
             // Delete all remaining jobs of this encode.
-            [fStatusField setStringValue: NSLocalizedString( @"Done.", @"" )];
+            [fStatusField setStringValue: NSLocalizedString( @"Encode Finished.", @"" )];
+            /* Set the status string in fQueueController as well */
+            [fQueueController setQueueStatusString: NSLocalizedString( @"Encode Finished.", @"" )];
             [fRipIndicator setIndeterminate: NO];
+            [fRipIndicator stopAnimation: nil];
             [fRipIndicator setDoubleValue: 0.0];
             [[fWindow toolbar] validateVisibleItems];
             
             /* Restore dock icon */
             [self UpdateDockIcon: -1.0];
+            dockIconProgress = 0;
             
             if( fRipIndicatorShown )
             {
@@ -712,44 +861,66 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 [fWindow setFrame:frame display:YES animate:YES];
                                fRipIndicatorShown = NO;
                        }
-            
-                       /* Check to see if the encode state has not been cancelled
+            /* Since we are done with this encode, tell output to stop writing to the
+             * individual encode log
+             */
+                       [outputPanel endEncodeLog];
+            /* Check to see if the encode state has not been cancelled
              to determine if we should check for encode done notifications */
                        if( fEncodeState != 2 )
             {
+                NSString *pathOfFinishedEncode;
+                /* Get the output file name for the finished encode */
+                pathOfFinishedEncode = [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"];
+                
+                /* Both the Growl Alert and Sending to MetaX can be done as encodes roll off the queue */
+                /* Growl alert */
+                [self showGrowlDoneNotification:pathOfFinishedEncode];
+                /* Send to MetaX */
+                [self sendToMetaX:pathOfFinishedEncode];
+                
                 /* since we have successfully completed an encode, we increment the queue counter */
-                [self incrementQueueItemDone:nil];
-                /* If Alert Window or Window and Growl has been selected */
-                               if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window"] ||
-                   [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"] )
-                {
-                                       /*On Screen Notification*/
-                                       int status;
-                                       NSBeep();
-                                       status = NSRunAlertPanel(@"Put down that cocktail...",@"Your HandBrake encode is done!", @"OK", nil, nil);
-                                       [NSApp requestUserAttention:NSCriticalRequest];
-                }
-                /* If sleep has been selected */
-                if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"] )
-                {
-                    /* Sleep */
-                    NSDictionary* errorDict;
-                    NSAppleEventDescriptor* returnDescriptor = nil;
-                    NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
-                                                   @"tell application \"Finder\" to sleep"];
-                    returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
-                    [scriptObject release];
-                }
-                /* If Shutdown has been selected */
-                if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"] )
+                [self incrementQueueItemDone:nil]; 
+                
+                /* all end of queue actions below need to be done after all queue encodes have finished 
+                 * and there are no pending jobs left to process
+                 */
+                if (fPendingCount == 0)
                 {
-                    /* Shut Down */
-                    NSDictionary* errorDict;
-                    NSAppleEventDescriptor* returnDescriptor = nil;
-                    NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
-                                                   @"tell application \"Finder\" to shut down"];
-                    returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
-                    [scriptObject release];
+                    /* If Alert Window or Window and Growl has been selected */
+                    if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window"] ||
+                       [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Alert Window And Growl"] )
+                    {
+                        /*On Screen Notification*/
+                        int status;
+                        NSBeep();
+                        status = NSRunAlertPanel(@"Put down that cocktail...",@"Your HandBrake queue is done!", @"OK", nil, nil);
+                        [NSApp requestUserAttention:NSCriticalRequest];
+                    }
+                    
+                    /* If sleep has been selected */
+                    if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Put Computer To Sleep"] )
+                    {
+                        /* Sleep */
+                        NSDictionary* errorDict;
+                        NSAppleEventDescriptor* returnDescriptor = nil;
+                        NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
+                                                       @"tell application \"Finder\" to sleep"];
+                        returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
+                        [scriptObject release];
+                    }
+                    /* If Shutdown has been selected */
+                    if( [[[NSUserDefaults standardUserDefaults] stringForKey:@"AlertWhenDone"] isEqualToString: @"Shut Down Computer"] )
+                    {
+                        /* Shut Down */
+                        NSDictionary* errorDict;
+                        NSAppleEventDescriptor* returnDescriptor = nil;
+                        NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
+                                                       @"tell application \"Finder\" to shut down"];
+                        returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
+                        [scriptObject release];
+                    }
+                    
                 }
                 
                 
@@ -762,7 +933,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 }
 
 /* We use this to write messages to stderr from the macgui which show up in the activity window and log*/
-- (void) writeToActivityLog:(char *) format, ...
+- (void) writeToActivityLog:(const char *) format, ...
 {
     va_list args;
     va_start(args, format);
@@ -847,7 +1018,27 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         [item setTarget: self];
         [item setAction: @selector(Pause:)];
     }
-    else if ([itemIdent isEqualToString: ShowActivityIdentifier]) {
+    else if ([itemIdent isEqualToString: ShowPictureIdentifier])
+    {
+        [item setLabel: @"Picture Settings"];
+        [item setPaletteLabel: @"Show Picture Settings"];
+        [item setToolTip: @"Show Picture Settings"];
+        [item setImage: [NSImage imageNamed: @"pref-picture"]];
+        [item setTarget: self];
+        [item setAction: @selector(showPicturePanel:)];
+    }
+    else if ([itemIdent isEqualToString: ShowPreviewIdentifier])
+    {
+        [item setLabel: @"Preview Window"];
+        [item setPaletteLabel: @"Show Preview"];
+        [item setToolTip: @"Show Preview"];
+        //[item setImage: [NSImage imageNamed: @"pref-picture"]];
+        [item setImage: [NSImage imageNamed: @"Brushed_Window"]];
+        [item setTarget: self];
+        [item setAction: @selector(showPreviewWindow:)];
+    }
+    else if ([itemIdent isEqualToString: ShowActivityIdentifier]) 
+    {
         [item setLabel: @"Activity Window"];
         [item setPaletteLabel: @"Show Activity Window"];
         [item setToolTip: @"Show Activity Window"];
@@ -877,13 +1068,13 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 {
     return [NSArray arrayWithObjects: ChooseSourceIdentifier, NSToolbarSeparatorItemIdentifier, StartEncodingIdentifier,
         PauseEncodingIdentifier, AddToQueueIdentifier, ShowQueueIdentifier, NSToolbarFlexibleSpaceItemIdentifier, 
-               NSToolbarSpaceItemIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
+               NSToolbarSpaceItemIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier, nil];
 }
 
 - (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
 {
     return [NSArray arrayWithObjects:  StartEncodingIdentifier, PauseEncodingIdentifier, AddToQueueIdentifier,
-        ChooseSourceIdentifier, ShowQueueIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
+        ChooseSourceIdentifier, ShowQueueIdentifier, ShowPictureIdentifier, ShowPreviewIdentifier, ShowActivityIdentifier, ToggleDrawerIdentifier,
         NSToolbarCustomizeToolbarItemIdentifier, NSToolbarFlexibleSpaceItemIdentifier,
         NSToolbarSpaceItemIdentifier, NSToolbarSeparatorItemIdentifier, nil];
 }
@@ -916,8 +1107,14 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 return YES;
             }
             if (SuccessfulScan)
+            {
                 if ([ident isEqualToString: AddToQueueIdentifier])
                     return YES;
+                if ([ident isEqualToString: ShowPictureIdentifier])
+                    return YES;
+                if ([ident isEqualToString: ShowPreviewIdentifier])
+                    return YES;
+            }
         }
         else if (s.state == HB_STATE_PAUSED)
         {
@@ -933,6 +1130,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
                 return YES;
             if ([ident isEqualToString: AddToQueueIdentifier])
                 return YES;
+            if ([ident isEqualToString: ShowPictureIdentifier])
+                return YES;
+            if ([ident isEqualToString: ShowPreviewIdentifier])
+                return YES;
         }
         else if (s.state == HB_STATE_SCANNING)
             return NO;
@@ -951,6 +1152,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             if ([ident isEqualToString: AddToQueueIdentifier])
                 return YES;
+            if ([ident isEqualToString: ShowPictureIdentifier])
+                return YES;
+            if ([ident isEqualToString: ShowPreviewIdentifier])
+                return YES;
         }
 
     }
@@ -1050,7 +1255,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 
 -(void)showGrowlDoneNotification:(NSString *) filePath
 {
-    /* This is called from HBQueueController as jobs roll off of the queue in currentJobChanged */
+    /* This end of encode action is called as each encode rolls off of the queue */
     NSString * finishedEncode = filePath;
     /* strip off the path to just show the file name */
     finishedEncode = [finishedEncode lastPathComponent];
@@ -1071,7 +1276,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 }
 -(void)sendToMetaX:(NSString *) filePath
 {
-    /* This is called from HBQueueController as jobs roll off of the queue in currentJobChanged */
+    /* This end of encode action is called as each encode rolls off of the queue */
     if([[NSUserDefaults standardUserDefaults] boolForKey: @"sendToMetaX"] == YES)
     {
         NSAppleScript *myScript = [[NSAppleScript alloc] initWithSource: [NSString stringWithFormat: @"%@%@%@", @"tell application \"MetaX\" to open (POSIX file \"", filePath, @"\")"]];
@@ -1236,6 +1441,16 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     }
 }
 
+- (IBAction)showAboutPanel:(id)sender
+{
+    //[NSApp orderFrontStandardAboutPanel:sender];
+    NSMutableDictionary* d = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
+        fApplicationIcon, @"ApplicationIcon",
+        nil ];
+    [NSApp orderFrontStandardAboutPanelWithOptions:d];
+    [d release];
+}
+
 /* Here we open the title selection sheet where we can specify an exact title to be scanned */
 - (IBAction) showSourceTitleScanPanel: (id) sender
 {
@@ -1276,22 +1491,49 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     BOOL cancelScanDecrypt = 0;
     NSString *path = scanPath;
     HBDVDDetector *detector = [HBDVDDetector detectorForPath:path];
-
+    
     // Notify ChapterTitles that there's no title
     [fChapterTitlesDelegate resetWithTitle:nil];
     [fChapterTable reloadData];
-
+    
+    // Notify Subtitles that there's no title
+    [fSubtitlesDelegate resetWithTitle:nil];
+    [fSubtitlesTable reloadData];
+    
     [self enableUI: NO];
-
+    
     if( [detector isVideoDVD] )
     {
         // The chosen path was actually on a DVD, so use the raw block
         // device path instead.
         path = [detector devicePath];
         [self writeToActivityLog: "trying to open a physical dvd at: %s", [scanPath UTF8String]];
+        
+#if defined( __LP64__ )
+        /* If we are 64 bit, we cannot read encrypted dvd's as vlc is 32 bit only */
+        cancelScanDecrypt = 1;
+        [self writeToActivityLog: "64 bit mode cannot read dvd's, scan cancelled"];
+        /*On Screen Notification*/
+        int status;
+        NSBeep();
+        status = NSRunAlertPanel(@"64-bit HandBrake cannot read encrypted dvds!",@"", @"Cancel Scan", @"Attempt Scan Anyway", nil);
+        [NSApp requestUserAttention:NSCriticalRequest];
+        
+        if (status == NSAlertDefaultReturn)
+        {
+            /* User chose to cancel the scan */
+            [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
+            cancelScanDecrypt = 1;
+        }
+        else
+        {
+            [self writeToActivityLog: "user overrode 64-bit warning trying to open physical dvd without decryption"];
+            cancelScanDecrypt = 0;
+        }
 
+#else
         /* lets check for vlc here to make sure we have a dylib available to use for decrypting */
-        NSString *vlcPath = @"/Applications/VLC.app";
+        NSString *vlcPath = @"/Applications/VLC.app/Contents/MacOS/lib/libdvdcss.2.dylib";
         NSFileManager * fileManager = [NSFileManager defaultManager];
            if ([fileManager fileExistsAtPath:vlcPath] == 0) 
            {
@@ -1299,7 +1541,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             cancelScanDecrypt = 1;
             [self writeToActivityLog: "VLC app not found for decrypting physical dvd"];
             int status;
-            status = NSRunAlertPanel(@"HandBrake could not find VLC.",@"Please download and install VLC media player in your /Applications folder if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
+            status = NSRunAlertPanel(@"HandBrake could not find VLC or your VLC is out of date.",@"Please download and install VLC media player in your /Applications folder if you wish to read encrypted DVDs.", @"Get VLC", @"Cancel Scan", @"Attempt Scan Anyway");
             [NSApp requestUserAttention:NSCriticalRequest];
             
             if (status == NSAlertDefaultReturn)
@@ -1309,24 +1551,25 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             }
             else if (status == NSAlertAlternateReturn)
             {
-            /* User chose to cancel the scan */
-            [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
+                /* User chose to cancel the scan */
+                [self writeToActivityLog: "cannot open physical dvd , scan cancelled"];
             }
             else
             {
-            /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
-            cancelScanDecrypt = 0;
-            [self writeToActivityLog: "user overrode vlc warning -trying to open physical dvd without decryption"];
+                /* User chose to override our warning and scan the physical dvd anyway, at their own peril. on an encrypted dvd this produces massive log files and fails */
+                cancelScanDecrypt = 0;
+                [self writeToActivityLog: "user overrode vlc warning -trying to open physical dvd without decryption"];
             }
-
+            
         }
         else
         {
             /* VLC was found in /Applications so all is well, we can carry on using vlc's libdvdcss.dylib for decrypting if needed */
             [self writeToActivityLog: "VLC app found for decrypting physical dvd"];
         }
+#endif 
     }
-
+    
     if (cancelScanDecrypt == 0)
     {
         /* we actually pass the scan off to libhb here */
@@ -1341,8 +1584,11 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
         {
             [self writeToActivityLog: "scanning specifically for title: %d", scanTitleNum];
         }
-
-        hb_scan( fHandle, [path UTF8String], scanTitleNum );
+        /* We use our advance pref to determine how many previews to scan */
+        int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue];
+        /* set title to NULL */
+        //fTitle = NULL;
+        hb_scan( fHandle, [path UTF8String], scanTitleNum, hb_num_previews, 1 );
         [fSrcDVD2Field setStringValue:@"Scanning new source ..."];
     }
 }
@@ -1364,6 +1610,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             SuccessfulScan = NO;
             
             // Notify ChapterTitles that there's no title
+            [fSubtitlesDelegate resetWithTitle:nil];
+            [fSubtitlesTable reloadData];
+            
+            // Notify Subtitles that there's no title
             [fChapterTitlesDelegate resetWithTitle:nil];
             [fChapterTable reloadData];
         }
@@ -1421,18 +1671,20 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             SuccessfulScan = YES;
             [self enableUI: YES];
 
-                /* if its the initial successful scan after awakeFromNib */
-                if (currentSuccessfulScanCount == 1)
-                {
-                    [self selectDefaultPreset:nil];
-                    /* initially set deinterlace to 0, will be overridden reset by the default preset anyway */
-                    //[fPictureController setDeinterlace:0];
-                    
-                    /* lets set Denoise to index 0 or "None" since this is the first scan */
-                    //[fPictureController setDenoise:0];
-                    
-                    [fPictureController setInitialPictureFilters];
-                }
+            /* if its the initial successful scan after awakeFromNib */
+            if (currentSuccessfulScanCount == 1)
+            {
+                [self selectDefaultPreset:nil];
+                
+                // Open preview window now if it was visible when HB was closed
+                if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PreviewWindowIsOpen"])
+                    [self showPreviewWindow:nil];
+                
+                // Open picture sizing window now if it was visible when HB was closed
+                if ([[NSUserDefaults standardUserDefaults] boolForKey:@"PictureSizeWindowIsOpen"])
+                    [self showPicturePanel:nil];
+                
+            }
 
             
         }
@@ -1455,11 +1707,14 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 }
 
 - (void) browseFileDone: (NSSavePanel *) sheet
-    returnCode: (int) returnCode contextInfo: (void *) contextInfo
+             returnCode: (int) returnCode contextInfo: (void *) contextInfo
 {
     if( returnCode == NSOKButton )
     {
         [fDstFile2Field setStringValue: [sheet filename]];
+        /* Save this path to the prefs so that on next browse destination window it opens there */
+        NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
+        [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];   
     }
 }
 
@@ -1488,6 +1743,10 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     return NO;
 }
 
+- (NSSize) drawerWillResizeContents:(NSDrawer *) drawer toSize:(NSSize) contentSize {
+       [[NSUserDefaults standardUserDefaults] setObject:NSStringFromSize( contentSize ) forKey:@"Drawer Size"];
+       return contentSize;
+}
 
 #pragma mark -
 #pragma mark Queue File
@@ -1536,8 +1795,15 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
 - (void) removeQueueFileItem:(int) queueItemToRemove
 {
    
-   // FIX ME: WE NEED TO IDENTIFY AN ENCODING ITEM AND CALL 
-   
+   /* Find out if the item we are removing is a cancelled (3) or a finished (0) item*/
+   if ([[[QueueFileArray objectAtIndex:queueItemToRemove] objectForKey:@"Status"] intValue] == 3 || [[[QueueFileArray objectAtIndex:queueItemToRemove] objectForKey:@"Status"] intValue] == 0)
+    {
+    /* Since we are removing a cancelled or finished item, WE need to decrement the currentQueueEncodeIndex
+     * by one to keep in sync with the queue array
+     */
+    currentQueueEncodeIndex--;
+    [self writeToActivityLog: "removeQueueFileItem: Removing a cancelled/finished encode, decrement currentQueueEncodeIndex to %d", currentQueueEncodeIndex];
+    }
     [QueueFileArray removeObjectAtIndex:queueItemToRemove];
     [self saveQueueFileItem];
 
@@ -1607,6 +1873,33 @@ fWorkingCount = 0;
     [fQueueStatus setStringValue:string];
 }
 
+/* This method will set any item marked as encoding back to pending
+ * currently used right after a queue reload
+ */
+- (void) setQueueEncodingItemsAsPending
+{
+    NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+       id tempObject;
+    NSMutableArray *tempArray;
+    tempArray = [NSMutableArray array];
+    /* we look here to see if the preset is we move on to the next one */
+    while ( tempObject = [enumerator nextObject] )  
+    {
+        /* If the queue item is marked as "encoding" (1)
+         * then change its status back to pending (2) which effectively
+         * puts it back into the queue to be encoded
+         */
+        if ([[tempObject objectForKey:@"Status"] intValue] == 1)
+        {
+            [tempObject setObject:[NSNumber numberWithInt: 2] forKey:@"Status"];
+        }
+        [tempArray addObject:tempObject];
+    }
+    
+    [QueueFileArray setArray:tempArray];
+    [self saveQueueFileItem];
+}
+
 
 /* This method will clear the queue of any encodes that are not still pending
  * this includes both successfully completed encodes as well as cancelled encodes */
@@ -1619,9 +1912,14 @@ fWorkingCount = 0;
     /* we look here to see if the preset is we move on to the next one */
     while ( tempObject = [enumerator nextObject] )  
     {
-        /* If the queue item is not still pending (finished successfully or it was cancelled
-         * during the last session, then we put it in tempArray to be deleted from QueueFileArray*/
-        if ([[tempObject objectForKey:@"Status"] intValue] != 2)
+        /* If the queue item is either completed (0) or cancelled (3) from the
+         * last session, then we put it in tempArray to be deleted from QueueFileArray.
+         * NOTE: this means we retain pending (2) and also an item that is marked as
+         * still encoding (1). If the queue has an item that is still marked as encoding
+         * from a previous session, we can conlude that HB was either shutdown, or crashed
+         * during the encodes so we keep it and tell the user in the "Load Queue Alert"
+         */
+        if ([[tempObject objectForKey:@"Status"] intValue] == 0 || [[tempObject objectForKey:@"Status"] intValue] == 3)
         {
             [tempArray addObject:tempObject];
         }
@@ -1629,11 +1927,9 @@ fWorkingCount = 0;
     
     [QueueFileArray removeObjectsInArray:tempArray];
     [self saveQueueFileItem];
-    
 }
 
-/* This method will clear the queue of any encodes that are not still pending
- * this includes both successfully completed encodes as well as cancelled encodes */
+/* This method will clear the queue of all encodes. effectively creating an empty queue */
 - (void) clearQueueAllItems
 {
     NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
@@ -1648,7 +1944,6 @@ fWorkingCount = 0;
     
     [QueueFileArray removeObjectsInArray:tempArray];
     [self saveQueueFileItem];
-    
 }
 
 /* This method will duplicate prepareJob however into the
@@ -1662,10 +1957,8 @@ fWorkingCount = 0;
     hb_title_t * title = (hb_title_t *) hb_list_item( list,
             [fSrcTitlePopUp indexOfSelectedItem] );
     hb_job_t * job = title->job;
-    //hb_audio_config_t * audio;
     
-      // For picture filters
-      //hb_job_t * job = fTitle->job;
+    
     
     /* We use a number system to set the encode status of the queue item
      * 0 == already encoded
@@ -1679,6 +1972,7 @@ fWorkingCount = 0;
     [queueFileJob setObject:[NSString stringWithUTF8String: title->dvd] forKey:@"SourcePath"];
     [queueFileJob setObject:[fSrcDVD2Field stringValue] forKey:@"SourceName"];
     [queueFileJob setObject:[NSNumber numberWithInt:title->index] forKey:@"TitleNumber"];
+    [queueFileJob setObject:[NSNumber numberWithInt:[fSrcAnglePopUp indexOfSelectedItem] + 1] forKey:@"TitleAngle"];
     [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"ChapterStart"];
     
     [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterEndPopUp indexOfSelectedItem] + 1] forKey:@"ChapterEnd"];
@@ -1690,9 +1984,36 @@ fWorkingCount = 0;
     [queueFileJob setObject:[NSNumber numberWithInt:[fPresetsOutlineView selectedRow]] forKey:@"PresetIndexNum"];
     
     [queueFileJob setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
-       /* Chapter Markers fCreateChapterMarkers*/
-       [queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
-       /* Allow Mpeg4 64 bit formatting +4GB file sizes */
+    /* Chapter Markers*/
+    /* If we have only one chapter or a title without chapters, set chapter markers to off */
+    if ([fSrcChapterStartPopUp indexOfSelectedItem] ==  [fSrcChapterEndPopUp indexOfSelectedItem])
+    {
+        [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"ChapterMarkers"];
+    }
+    else
+    {
+        [queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+    }
+       
+    /* We need to get the list of chapter names to put into an array and store 
+     * in our queue, so they can be reapplied in prepareJob when this queue
+     * item comes up if Chapter Markers is set to on.
+     */
+     int i;
+     NSMutableArray *ChapterNamesArray = [[NSMutableArray alloc] init];
+     int chaptercount = hb_list_count( fTitle->list_chapter );
+     for( i = 0; i < chaptercount; i++ )
+    {
+        hb_chapter_t *chapter = (hb_chapter_t *) hb_list_item( fTitle->list_chapter, i );
+        if( chapter != NULL )
+        {
+          [ChapterNamesArray addObject:[NSString stringWithCString:chapter->title encoding:NSUTF8StringEncoding]];
+        }
+    }
+    [queueFileJob setObject:[NSMutableArray arrayWithArray: ChapterNamesArray] forKey:@"ChapterNames"];
+    [ChapterNamesArray autorelease];
+    
+    /* Allow Mpeg4 64 bit formatting +4GB file sizes */
        [queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
     /* Mux mp4 with http optimization */
     [queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
@@ -1708,12 +2029,10 @@ fWorkingCount = 0;
        [queueFileJob setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
        [queueFileJob setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
        [queueFileJob setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
-       [queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+       [queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualityRFField floatValue]] forKey:@"VideoQualitySlider"];
     /* Framerate */
     [queueFileJob setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
     
-    /* GrayScale */
-       [queueFileJob setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
        /* 2 Pass Encoding */
        [queueFileJob setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
        /* Turbo 2 pass Encoding fVidTurboPassCheck*/
@@ -1725,12 +2044,22 @@ fWorkingCount = 0;
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
-       [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+       [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
+    /* if we are custom anamorphic, store the exact storage, par and display dims */
+    if (fTitle->job->anamorphic.mode == 3)
+    {
+        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PicturePARStorageWidth"];
+        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PicturePARStorageHeight"];
+        
+        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.par_width] forKey:@"PicturePARPixelWidth"];
+        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.par_height] forKey:@"PicturePARPixelHeight"];
+        
+        [queueFileJob setObject:[NSNumber numberWithFloat:fTitle->job->anamorphic.dar_width] forKey:@"PicturePARDisplayWidth"];
+        [queueFileJob setObject:[NSNumber numberWithFloat:fTitle->job->anamorphic.dar_height] forKey:@"PicturePARDisplayHeight"];
+
+    }
     NSString * pictureSummary;
-    pictureSummary = [NSString stringWithFormat:@"Source: %@ Output: %@ Anamorphic: %@", 
-                     [fPicSettingsSrc stringValue], 
-                     [fPicSettingsOutp stringValue], 
-                     [fPicSettingsAnamorphic stringValue]];
+    pictureSummary = [fPictureSizeField stringValue];
     [queueFileJob setObject:pictureSummary forKey:@"PictureSizingSummary"];                 
     /* Set crop settings here */
        [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
@@ -1740,12 +2069,22 @@ fWorkingCount = 0;
        [queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
     
     /* Picture Filters */
-    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
-       [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
-    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController vfr]] forKey:@"VFR"];
-       [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
-    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"]; 
+    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
+    [queueFileJob setObject:[fPictureController detelecineCustomString] forKey:@"PictureDetelecineCustom"];
+    
+    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController useDecomb]] forKey:@"PictureDecombDeinterlace"];
     [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
+    [queueFileJob setObject:[fPictureController decombCustomString] forKey:@"PictureDecombCustom"];
+    
+    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
+    [queueFileJob setObject:[fPictureController deinterlaceCustomString] forKey:@"PictureDeinterlaceCustom"];
+    
+    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
+    [queueFileJob setObject:[fPictureController denoiseCustomString] forKey:@"PictureDenoiseCustom"];
+    
+    [queueFileJob setObject:[NSString stringWithFormat:@"%d",[fPictureController deblock]] forKey:@"PictureDeblock"];
+    
+    [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
     
     /*Audio*/
     if ([fAudLang1PopUp indexOfSelectedItem] > 0)
@@ -1790,13 +2129,10 @@ fWorkingCount = 0;
     }
     
        /* Subtitles*/
-       [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
-    [queueFileJob setObject:[NSNumber numberWithInt:[fSubPopUp indexOfSelectedItem]] forKey:@"JobSubtitlesIndex"];
-    /* Forced Subtitles */
-       [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
-    
-    
-    
+    NSMutableArray *subtitlesArray = [[NSMutableArray alloc] init];
+    [queueFileJob setObject:[NSArray arrayWithArray: [fSubtitlesDelegate getSubtitleArray: subtitlesArray]] forKey:@"SubtitleList"];
+    [subtitlesArray autorelease];
+
     /* Now we go ahead and set the "job->values in the plist for passing right to fQueueEncodeLibhb */
      
     [queueFileJob setObject:[NSNumber numberWithInt:[fSrcChapterStartPopUp indexOfSelectedItem] + 1] forKey:@"JobChapterStart"];
@@ -1805,36 +2141,23 @@ fWorkingCount = 0;
     
     
     [queueFileJob setObject:[NSNumber numberWithInt:[[fDstFormatPopUp selectedItem] tag]] forKey:@"JobFileFormatMux"];
-       /* Chapter Markers fCreateChapterMarkers*/
-       //[queueFileJob setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
-       /* Allow Mpeg4 64 bit formatting +4GB file sizes */
-       //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
-    /* Mux mp4 with http optimization */
-    //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
-    /* Add iPod uuid atom */
-    //[queueFileJob setObject:[NSNumber numberWithInt:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
     
     /* Codecs */
        /* Video encoder */
        [queueFileJob setObject:[NSNumber numberWithInt:[[fVidEncoderPopUp selectedItem] tag]] forKey:@"JobVideoEncoderVcodec"];
-       /* x264 Option String */
-       //[queueFileJob setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
-
-       //[queueFileJob setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
-       //[queueFileJob setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
-       //[queueFileJob setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
-       //[queueFileJob setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
+       
     /* Framerate */
     [queueFileJob setObject:[NSNumber numberWithInt:[fVidRatePopUp indexOfSelectedItem]] forKey:@"JobIndexVideoFramerate"];
     [queueFileJob setObject:[NSNumber numberWithInt:title->rate] forKey:@"JobVrate"];
     [queueFileJob setObject:[NSNumber numberWithInt:title->rate_base] forKey:@"JobVrateBase"];
-       /* Picture Sizing */
+       
+    /* Picture Sizing */
        /* Use Max Picture settings for whatever the dvd is.*/
        [queueFileJob setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
        [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
-       [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
+       [queueFileJob setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
     
     /* Set crop settings here */
        [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
@@ -1843,8 +2166,6 @@ fWorkingCount = 0;
        [queueFileJob setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
        [queueFileJob setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
     
-    /* Picture Filters */
-    [queueFileJob setObject:[fPicSettingDecomb stringValue] forKey:@"JobPictureDecomb"];
     
     /*Audio*/
     if ([fAudLang1PopUp indexOfSelectedItem] > 0)
@@ -1879,10 +2200,7 @@ fWorkingCount = 0;
         [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4RatePopUp selectedItem] tag]] forKey:@"JobAudio4Samplerate"];
         [queueFileJob setObject:[NSNumber numberWithInt:[[fAudTrack4BitratePopUp selectedItem] tag]] forKey:@"JobAudio4Bitrate"];
     }
-       /* Subtitles*/
-       [queueFileJob setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
-    /* Forced Subtitles */
-       [queueFileJob setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
+
  
     /* we need to auto relase the queueFileJob and return it */
     [queueFileJob autorelease];
@@ -1891,33 +2209,32 @@ fWorkingCount = 0;
 }
 
 /* this is actually called from the queue controller to modify the queue array and return it back to the queue controller */
-- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
+- (void)moveObjectsInQueueArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
 {
-    unsigned index = [indexSet lastIndex];
-    unsigned aboveInsertIndexCount = 0;
+    NSUInteger index = [indexSet lastIndex];
+    NSUInteger aboveInsertIndexCount = 0;
     
-    while (index != NSNotFound)
-    {
-        unsigned removeIndex;
-        
-        if (index >= insertIndex)
-        {
-            removeIndex = index + aboveInsertIndexCount;
-            aboveInsertIndexCount++;
-        }
-        else
-        {
-            removeIndex = index;
-            insertIndex--;
-        }
-        
-        id object = [[QueueFileArray objectAtIndex:removeIndex] retain];
-        [QueueFileArray removeObjectAtIndex:removeIndex];
-        [QueueFileArray insertObject:object atIndex:insertIndex];
-        [object release];
+    
+    NSUInteger removeIndex;
         
-        index = [indexSet indexLessThanIndex:index];
+    if (index >= insertIndex)
+    {
+        removeIndex = index + aboveInsertIndexCount;
+        aboveInsertIndexCount++;
     }
+    else
+    {
+        removeIndex = index;
+        insertIndex--;
+    }
+
+    id object = [[QueueFileArray objectAtIndex:removeIndex] retain];
+    [QueueFileArray removeObjectAtIndex:removeIndex];
+    [QueueFileArray insertObject:object atIndex:insertIndex];
+    [object release];
+        
+    index = [indexSet indexLessThanIndex:index];
+
    /* We save all of the Queue data here 
     * and it also gets sent back to the queue controller*/
     [self saveQueueFileItem]; 
@@ -1960,8 +2277,10 @@ fWorkingCount = 0;
 /* Here we actually tell hb_scan to perform the source scan, using the path to source and title number*/
 - (void) performNewQueueScan:(NSString *) scanPath scanTitleNum: (int) scanTitleNum
 {
-   //NSRunAlertPanel(@"Hello!", @"We are now performing a new queue scan!", @"OK", nil, nil);
-
+   /* Tell HB to output a new activity log file for this encode */
+    [outputPanel startEncodeLog:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"DestinationPath"]];
+    
+    
      /* use a bool to determine whether or not we can decrypt using vlc */
     BOOL cancelScanDecrypt = 0;
     /* set the bool so that showNewScan knows to apply the appropriate queue
@@ -1976,12 +2295,6 @@ fWorkingCount = 0;
         //status = NSRunAlertPanel(@"HandBrake is now loading up a new queue item...",@"Would You Like to wait until you add another encode?", @"Cancel", @"Okay", nil);
         //[NSApp requestUserAttention:NSCriticalRequest];
 
-    // Notify ChapterTitles that there's no title
-    [fChapterTitlesDelegate resetWithTitle:nil];
-    [fChapterTable reloadData];
-
-    //[self enableUI: NO];
-
     if( [detector isVideoDVD] )
     {
         // The chosen path was actually on a DVD, so use the raw block
@@ -2040,8 +2353,11 @@ fWorkingCount = 0;
         {
             [self writeToActivityLog: "scanning specifically for title: %d", scanTitleNum];
         }
+        
         [self writeToActivityLog: "performNewQueueScan currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
-        hb_scan( fQueueEncodeLibhb, [path UTF8String], scanTitleNum );
+        /* We use our advance pref to determine how many previews to scan */
+        int hb_num_previews = [[[NSUserDefaults standardUserDefaults] objectForKey:@"PreviewsNumber"] intValue];
+        hb_scan( fQueueEncodeLibhb, [path UTF8String], scanTitleNum, hb_num_previews, 0 );
     }
 }
 
@@ -2108,9 +2424,6 @@ fWorkingCount = 0;
         [fVidRatePopUp selectItemWithTitle:[queueToApply objectForKey:@"VideoFramerate"]];
     }
     
-    /* GrayScale */
-    [fVidGrayscaleCheck setState:[[queueToApply objectForKey:@"VideoGrayScale"] intValue]];
-    
     /* 2 Pass Encoding */
     [fVidTwoPassCheck setState:[[queueToApply objectForKey:@"VideoTwoPass"] intValue]];
     [self twoPassCheckboxChanged:nil];
@@ -2249,7 +2562,7 @@ fWorkingCount = 0;
             hb_fix_aspect( job, HB_KEEP_HEIGHT );
         }
     }
-    job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
+    job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
     
     
     /* If Cropping is set to custom, then recall all four crop values from
@@ -2279,8 +2592,7 @@ fWorkingCount = 0;
     /* Filters */
     /* Deinterlace */
     [fPictureController setDeinterlace:[[queueToApply objectForKey:@"PictureDeinterlace"] intValue]];
-    /* VFR */
-    [fPictureController setVFR:[[queueToApply objectForKey:@"VFR"] intValue]];
+    
     /* Detelecine */
     [fPictureController setDetelecine:[[queueToApply objectForKey:@"PictureDetelecine"] intValue]];
     /* Denoise */
@@ -2289,6 +2601,8 @@ fWorkingCount = 0;
     [fPictureController setDeblock:[[queueToApply objectForKey:@"PictureDeblock"] intValue]];
     /* Decomb */
     [fPictureController setDecomb:[[queueToApply objectForKey:@"PictureDecomb"] intValue]];
+    /* Grayscale */
+    [fPictureController setGrayscale:[[queueToApply objectForKey:@"VideoGrayScale"] intValue]];
     
     [self calculatePictureSizing:nil];
     
@@ -2338,26 +2652,18 @@ fWorkingCount = 0;
     {
         [self writeToActivityLog: "processNewQueueEncode WARNING nothing found in the title list"];
     }
-    else
-    {
-        [self writeToActivityLog: "processNewQueueEncode title list is: %d", hb_list_count( list )];
-    }
     
     NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
-    [self writeToActivityLog: "processNewQueueEncode currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
+    [self writeToActivityLog: "Preset: %s", [[queueToApply objectForKey:@"PresetName"] UTF8String]];
+    [self writeToActivityLog: "processNewQueueEncode number of passes expected is: %d", ([[queueToApply objectForKey:@"VideoTwoPass"] intValue] + 1)];
     job->file = [[queueToApply objectForKey:@"DestinationPath"] UTF8String];
-    
+    //[self writeToActivityLog: "processNewQueueEncode sending to prepareJob"];
     [self prepareJob];
     
-    if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 )
-        job->subtitle_force = 1;
-    else
-        job->subtitle_force = 0;
-    
     /*
-     * subtitle of -1 is a scan
+     * If scanning we need to do some extra setup of the job.
      */
-    if( job->subtitle == -1 )
+    if( job->indepth_scan == 1 )
     {
         char *x264opts_tmp;
         
@@ -2367,14 +2673,11 @@ fWorkingCount = 0;
          */
         job->pass = -1;
         x264opts_tmp = job->x264opts;
-        job->subtitle = -1;
         
         job->x264opts = NULL;
         
         job->indepth_scan = 1;  
-        
-        job->select_subtitle = (hb_subtitle_t**)malloc(sizeof(hb_subtitle_t*));
-        *(job->select_subtitle) = NULL;
+
         
         /*
          * Add the pre-scan job
@@ -2382,24 +2685,13 @@ fWorkingCount = 0;
         hb_add( fQueueEncodeLibhb, job );
         job->x264opts = x264opts_tmp;
     }
-    else
-        job->select_subtitle = NULL;
-    
-    /* No subtitle were selected, so reset the subtitle to -1 (which before
-     * this point meant we were scanning
-     */
-    if( job->subtitle == -2 )
-        job->subtitle = -1;
+
     
     if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 )
     {
-        hb_subtitle_t **subtitle_tmp = job->select_subtitle;
         job->indepth_scan = 0;
         
-        /*
-         * Do not autoselect subtitles on the first pass of a two pass
-         */
-        job->select_subtitle = NULL;
+
         
         job->pass = 1;
         
@@ -2410,8 +2702,6 @@ fWorkingCount = 0;
         job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */  
         strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]);
         
-        job->select_subtitle = subtitle_tmp;
-        
         hb_add( fQueueEncodeLibhb, job );
         
     }
@@ -2428,126 +2718,78 @@ fWorkingCount = 0;
        /* Lets mark our new encode as 1 or "Encoding" */
     [queueToApply setObject:[NSNumber numberWithInt:1] forKey:@"Status"];
     [self saveQueueFileItem];
+    
+    /* we need to clean up the subtitle tracks after the job(s) have been set  */
+    int num_subtitle_tracks = hb_list_count(job->list_subtitle);
+    int ii;
+    for(ii = 0; ii < num_subtitle_tracks; ii++)
+    {
+        hb_subtitle_t * subtitle;
+        subtitle = (hb_subtitle_t *)hb_list_item(job->list_subtitle, 0);
+        
+
+        hb_list_rem(job->list_subtitle, subtitle);
+        free(subtitle);
+    }
+    
+    
     /* We should be all setup so let 'er rip */   
     [self doRip];
 }
 
-
 #pragma mark -
-#pragma mark Job Handling
-
-
-- (void) prepareJob
+#pragma mark Live Preview
+/* Note,this is much like prepareJob, but directly sets the job vars so Picture Preview
+ * can encode to its temp preview directory and playback. This is *not* used for any actual user
+ * encodes
+ */
+- (void) prepareJobForPreview
 {
-    
-    NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
-    hb_list_t  * list  = hb_get_titles( fQueueEncodeLibhb );
-    hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan
+    hb_list_t  * list  = hb_get_titles( fHandle );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,
+            [fSrcTitlePopUp indexOfSelectedItem] );
     hb_job_t * job = title->job;
     hb_audio_config_t * audio;
-    
+    /* set job->angle for libdvdnav */
+    job->angle = [fSrcAnglePopUp indexOfSelectedItem] + 1;
     /* Chapter selection */
-    job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
-    job->chapter_end   = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
+    job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
+    job->chapter_end   = [fSrcChapterEndPopUp   indexOfSelectedItem] + 1;
        
     /* Format (Muxer) and Video Encoder */
-    job->mux = [[queueToApply objectForKey:@"JobFileFormatMux"] intValue];
-    job->vcodec = [[queueToApply objectForKey:@"JobVideoEncoderVcodec"] intValue];
-    
-    
-    /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
-       //if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
-       //{
-    /* We set the largeFileSize (64 bit formatting) variable here to allow for > 4gb files based on the format being
-     mpeg4 and the checkbox being checked 
-     *Note: this will break compatibility with some target devices like iPod, etc.!!!!*/
-    if( [[queueToApply objectForKey:@"Mp4LargeFile"] intValue] == 1)
-    {
-        job->largeFileSize = 1;
-    }
-    else
-    {
-        job->largeFileSize = 0;
-    }
-    /* We set http optimized mp4 here */
-    if( [[queueToApply objectForKey:@"Mp4HttpOptimize"] intValue] == 1 )
-    {
-        job->mp4_optimize = 1;
-    }
-    else
-    {
-        job->mp4_optimize = 0;
-    }
-    //}
-       
-    /* We set the chapter marker extraction here based on the format being
-     mpeg4 or mkv and the checkbox being checked */
-    if ([[queueToApply objectForKey:@"ChapterMarkers"] intValue] == 1)
-    {
-        job->chapter_markers = 1;
-    }
-    else
-    {
-        job->chapter_markers = 0;
-    }
+    job->mux = [[fDstFormatPopUp selectedItem] tag];
+    job->vcodec = [[fVidEncoderPopUp selectedItem] tag];
+
+    job->chapter_markers = 0;
     
-       
-    if( job->vcodec & HB_VCODEC_X264 )
+       if( job->vcodec & HB_VCODEC_X264 )
     {
-               if ([[queueToApply objectForKey:@"Mp4iPodCompatible"] intValue] == 1)
-           {
-            job->ipod_atom = 1;
-               }
-        else
-        {
-            job->ipod_atom = 0;
-        }
-               
                /* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
          Currently only used with Constant Quality setting*/
-               if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2)
+               if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [fVidQualityMatrix selectedRow] == 2)
                {
                job->crf = 1;
                }
+               
                /* Below Sends x264 options to the core library if x264 is selected*/
                /* Lets use this as per Nyx, Thanks Nyx!*/
                job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
-               /* Turbo first pass if two pass and Turbo First pass is selected */
-               if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 && [[queueToApply objectForKey:@"VideoTurboTwoPass"] intValue] == 1 )
-               {
-                       /* pass the "Turbo" string to be appended to the existing x264 opts string into a variable for the first pass */
-                       NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";
-                       /* append the "Turbo" string variable to the existing opts string.
-             Note: the "Turbo" string must be appended, not prepended to work properly*/
-                       NSString *firstPassOptStringCombined = [[[queueToApply objectForKey:@"x264Option"] stringValue] stringByAppendingString:firstPassOptStringTurbo];
-                       strcpy(job->x264opts, [firstPassOptStringCombined UTF8String]);
-               }
-               else
-               {
-                       strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]);
-               }
+               /* For previews we ignore the turbo option for the first pass of two since we only use 1 pass */
+               strcpy(job->x264opts, [[fAdvancedOptions optionsString] UTF8String]);
+
         
     }
-    
-    /* Picture Size Settings */
-    job->width = [[queueToApply objectForKey:@"PictureWidth"]  intValue];
-    job->height = [[queueToApply objectForKey:@"PictureHeight"]  intValue];
-    
-    job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"]  intValue];
-    job->pixel_ratio = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
-    
-    
-    /* Here we use the crop values saved at the time the preset was saved */
-    job->crop[0] = [[queueToApply objectForKey:@"PictureTopCrop"]  intValue];
-    job->crop[1] = [[queueToApply objectForKey:@"PictureBottomCrop"]  intValue];
-    job->crop[2] = [[queueToApply objectForKey:@"PictureLeftCrop"]  intValue];
-    job->crop[3] = [[queueToApply objectForKey:@"PictureRightCrop"]  intValue];
-    
+
     /* Video settings */
-    if( [[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue] > 0 )
+   /* Set vfr to 0 as it's only on if using same as source in the framerate popup
+     * and detelecine is on, so we handle that in the logic below
+     */
+    job->vfr = 0;
+    if( [fVidRatePopUp indexOfSelectedItem] > 0 )
     {
+        /* a specific framerate has been chosen */
         job->vrate      = 27000000;
-        job->vrate_base = hb_video_rates[[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue]-1].rate;
+        job->vrate_base = hb_video_rates[[fVidRatePopUp indexOfSelectedItem]-1].rate;
         /* We are not same as source so we set job->cfr to 1 
          * to enable constant frame rate since user has specified
          * a specific framerate*/
@@ -2555,76 +2797,712 @@ fWorkingCount = 0;
     }
     else
     {
-        job->vrate      = [[queueToApply objectForKey:@"JobVrate"] intValue];
-        job->vrate_base = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
+        /* We are same as source (variable) */
+        job->vrate      = title->rate;
+        job->vrate_base = title->rate_base;
         /* We are same as source so we set job->cfr to 0 
          * to enable true same as source framerate */
         job->cfr = 0;
+        /* If we are same as source and we have detelecine on, we need to turn on
+         * job->vfr
+         */
+        if ([fPictureController detelecine] == 1)
+        {
+            job->vfr = 1;
+        }
     }
-    
-    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 0 )
-    {
-        /* Target size.
-         Bitrate should already have been calculated and displayed
-         in fVidBitrateField, so let's just use it */
-    }
-    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 1 )
-    {
-        job->vquality = -1.0;
-        job->vbitrate = [[queueToApply objectForKey:@"VideoAvgBitrate"] intValue];
-    }
-    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2 )
+
+    switch( [fVidQualityMatrix selectedRow] )
     {
-        job->vquality = [[queueToApply objectForKey:@"VideoQualitySlider"] floatValue];
-        job->vbitrate = 0;
-        
+        case 0:
+            /* Target size.
+               Bitrate should already have been calculated and displayed
+               in fVidBitrateField, so let's just use it */
+        case 1:
+            job->vquality = -1.0;
+            job->vbitrate = [fVidBitrateField intValue];
+            break;
+        case 2:
+            job->vquality = [fVidQualityRFField floatValue];
+            job->vbitrate = 0;
+            break;
     }
-    
-    job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue];
+
     /* Subtitle settings */
-    job->subtitle = [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2;
+    NSMutableArray *subtitlesArray = nil;
+    subtitlesArray = [[NSMutableArray alloc] initWithArray:[fSubtitlesDelegate getSubtitleArray: subtitlesArray]];
     
-    /* Audio tracks and mixdowns */
-    /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
-    int audiotrack_count = hb_list_count(job->list_audio);
-    for( int i = 0; i < audiotrack_count;i++)
-    {
-        hb_audio_t * temp_audio = (hb_audio_t*) hb_list_item( job->list_audio, 0 );
-        hb_list_rem(job->list_audio, temp_audio);
-    }
-    /* Now lets add our new tracks to the audio list here */
-    if ([[queueToApply objectForKey:@"Audio1Track"] intValue] > 0)
-    {
-        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
-        hb_audio_config_init(audio);
-        audio->in.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
-        /* We go ahead and assign values to our audio->out.<properties> */
-        audio->out.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
-        audio->out.codec = [[queueToApply objectForKey:@"JobAudio1Encoder"] intValue];
-        audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio1Mixdown"] intValue];
-        audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio1Bitrate"] intValue];
-        audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio1Samplerate"] intValue];
-        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio1TrackDRCSlider"] floatValue];
-        
-        hb_audio_add( job, audio );
-        free(audio);
-    }  
-    if ([[queueToApply objectForKey:@"Audio2Track"] intValue] > 0)
+    
+    
+ int subtitle = nil;
+int force;
+int burned;
+int def;
+bool one_burned = FALSE;
+
+    int i = 0;
+    NSEnumerator *enumerator = [subtitlesArray objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
     {
         
-        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
-        hb_audio_config_init(audio);
-        audio->in.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
-        [self writeToActivityLog: "prepareJob audiotrack 2 is: %d", audio->in.track];
-        /* We go ahead and assign values to our audio->out.<properties> */
-        audio->out.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
-        audio->out.codec = [[queueToApply objectForKey:@"JobAudio2Encoder"] intValue];
-        audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio2Mixdown"] intValue];
-        audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio2Bitrate"] intValue];
-        audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio2Samplerate"] intValue];
-        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio2TrackDRCSlider"] floatValue];
+        subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue];
+        force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue];
+        burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue];
+        def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue];
         
-        hb_audio_add( job, audio );
+        /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups,
+         * we want to ignore it for display as well as encoding.
+         */
+        if (subtitle > 0)
+        {
+            /* if i is 0, then we are in the first item of the subtitles which we need to 
+             * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1
+             * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None.
+             */
+            
+            /* if we are on the first track and using "Foreign Audio Search" */ 
+            if (i == 0 && subtitle == 1)
+            {
+                /* NOTE: Currently foreign language search is borked for preview.
+                 * Commented out but left in for initial commit. */
+                
+                /*
+                [self writeToActivityLog: "Foreign Language Search: %d", 1];
+                
+                job->indepth_scan = 1;
+                if (burned == 1 || job->mux != HB_MUX_MP4)
+                {
+                    if (burned != 1 && job->mux == HB_MUX_MKV)
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    
+                    job->select_subtitle_config.force = force;
+                    job->select_subtitle_config.default_track = def;
+                    
+                }
+               */ 
+                
+            }
+            else
+            {
+                
+                /* for the actual source tracks, we must subtract the non source entries so 
+                 * that the menu index matches the source subtitle_list index for convenience */
+                if (i == 0)
+                {
+                    /* for the first track, the source tracks start at menu index 2 ( None is 0,
+                     * Foreign Language Search is 1) so subtract 2 */
+                    subtitle = subtitle - 2;
+                }
+                else
+                {
+                    /* for all other tracks, the source tracks start at menu index 1 (None is 0)
+                     * so subtract 1. */
+                    
+                    subtitle = subtitle - 1;
+                }
+                
+                /* We are setting a source subtitle so access the source subtitle info */  
+                hb_subtitle_t * subt;
+                
+                subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+                
+                if (subt != NULL)
+                {
+                    [self writeToActivityLog: "Setting Subtitle: %s", subt];
+
+                    hb_subtitle_config_t sub_config = subt->config;
+                    
+                    if (!burned && job->mux == HB_MUX_MKV && 
+                        subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else if (!burned && job->mux == HB_MUX_MP4 && 
+                             subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        // Skip any non-burned vobsubs when output is mp4
+                        continue;
+                    }
+                    else if ( burned && subt->format == hb_subtitle_s::PICTURESUB )
+                    {
+                        // Only allow one subtitle to be burned into the video
+                        if (one_burned)
+                            continue;
+                        one_burned = TRUE;
+                    }
+                    sub_config.force = force;
+                    sub_config.default_track = def;
+                    hb_subtitle_add( job, &sub_config, subtitle );
+                }   
+                
+            }
+        }
+        i++;
+    }
+   
+    
+    
+[subtitlesArray autorelease];    
+    
+    
+    /* Audio tracks and mixdowns */
+    /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
+    int audiotrack_count = hb_list_count(job->list_audio);
+    for( int i = 0; i < audiotrack_count;i++)
+    {
+        hb_audio_t * temp_audio = (hb_audio_t*) hb_list_item( job->list_audio, 0 );
+        hb_list_rem(job->list_audio, temp_audio);
+    }
+    /* Now lets add our new tracks to the audio list here */
+    if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack1CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack1BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack1RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack1DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+    }  
+    if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack2CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack2BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack2RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack2DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
+    
+    if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack3CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack3MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack3BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack3RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack3DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
+
+    if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack4CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack4MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack4BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack4RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack4DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
+
+    
+    
+    /* Filters */
+    
+    /* Though Grayscale is not really a filter, per se
+     * we put it here since its in the filters panel
+     */
+     
+    if ([fPictureController grayscale])
+    {
+        job->grayscale = 1;
+    }
+    else
+    {
+        job->grayscale = 0;
+    }
+    
+    /* Initialize the filters list */
+    job->filters = hb_list_init();
+    
+    /* Now lets call the filters if applicable.
+    * The order of the filters is critical
+    */
+    
+       /* Detelecine */
+    if ([fPictureController detelecine] == 1)
+    {
+        hb_list_add( job->filters, &hb_filter_detelecine );
+    }
+    if ([fPictureController detelecine] == 2)
+    {
+        /* use a custom detelecine string */
+        hb_filter_detelecine.settings = (char *) [[fPictureController detelecineCustomString] UTF8String];
+        hb_list_add( job->filters, &hb_filter_detelecine );
+    }
+    if ([fPictureController useDecomb] == 1)
+    {
+        /* Decomb */
+        if ([fPictureController decomb] == 1)
+        {
+            /* Run old deinterlacer fd by default */
+            //hb_filter_decomb.settings = (char *) [[fPicSettingDecomb stringValue] UTF8String];
+            hb_list_add( job->filters, &hb_filter_decomb );
+        }
+        /* we add the custom string if present */
+        if ([fPictureController decomb] == 2)
+        {
+            /* use a custom decomb string */
+            hb_filter_decomb.settings = (char *) [[fPictureController decombCustomString] UTF8String];
+            hb_list_add( job->filters, &hb_filter_decomb );
+        }
+    }
+    else
+    {
+        
+        /* Deinterlace */
+        if ([fPictureController deinterlace] == 1)
+        {
+            /* Run old deinterlacer fd by default */
+            hb_filter_deinterlace.settings = "-1"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );
+        }
+        else if ([fPictureController deinterlace] == 2)
+        {
+            /* Yadif mode 0 (without spatial deinterlacing.) */
+            hb_filter_deinterlace.settings = "2"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+        else if ([fPictureController deinterlace] == 3)
+        {
+            /* Yadif (with spatial deinterlacing) */
+            hb_filter_deinterlace.settings = "0"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+        else if ([fPictureController deinterlace] == 4)
+        {
+            /* we add the custom string if present */
+            hb_filter_deinterlace.settings = (char *) [[fPictureController deinterlaceCustomString] UTF8String];
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+       }
+    
+    /* Denoise */
+       if ([fPictureController denoise] == 1) // Weak in popup
+       {
+               hb_filter_denoise.settings = "2:1:2:3"; 
+        hb_list_add( job->filters, &hb_filter_denoise );       
+       }
+       else if ([fPictureController denoise] == 2) // Medium in popup
+       {
+               hb_filter_denoise.settings = "3:2:2:3"; 
+        hb_list_add( job->filters, &hb_filter_denoise );       
+       }
+       else if ([fPictureController denoise] == 3) // Strong in popup
+       {
+               hb_filter_denoise.settings = "7:7:5:5"; 
+        hb_list_add( job->filters, &hb_filter_denoise );       
+       }
+    else if ([fPictureController denoise] == 4) // custom in popup
+       {
+               /* we add the custom string if present */
+        hb_filter_denoise.settings = (char *) [[fPictureController denoiseCustomString] UTF8String]; 
+        hb_list_add( job->filters, &hb_filter_denoise );       
+       }
+    
+    /* Deblock  (uses pp7 default) */
+    /* NOTE: even though there is a valid deblock setting of 0 for the filter, for 
+     * the macgui's purposes a value of 0 actually means to not even use the filter
+     * current hb_filter_deblock.settings valid ranges are from 5 - 15 
+     */
+    if ([fPictureController deblock] != 0)
+    {
+        NSString *deblockStringValue = [NSString stringWithFormat: @"%d",[fPictureController deblock]];
+        hb_filter_deblock.settings = (char *) [deblockStringValue UTF8String];
+        hb_list_add( job->filters, &hb_filter_deblock );
+    }
+
+}
+
+
+#pragma mark -
+#pragma mark Job Handling
+
+
+- (void) prepareJob
+{
+    
+    NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
+    hb_list_t  * list  = hb_get_titles( fQueueEncodeLibhb );
+    hb_title_t * title = (hb_title_t *) hb_list_item( list,0 ); // is always zero since now its a single title scan
+    hb_job_t * job = title->job;
+    hb_audio_config_t * audio;
+    /* Title Angle for dvdnav */
+    job->angle = [[queueToApply objectForKey:@"TitleAngle"] intValue];
+    /* Chapter selection */
+    job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
+    job->chapter_end   = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
+       
+    /* Format (Muxer) and Video Encoder */
+    job->mux = [[queueToApply objectForKey:@"JobFileFormatMux"] intValue];
+    job->vcodec = [[queueToApply objectForKey:@"JobVideoEncoderVcodec"] intValue];
+    
+    
+    /* If mpeg-4, then set mpeg-4 specific options like chapters and > 4gb file sizes */
+    if( [[queueToApply objectForKey:@"Mp4LargeFile"] intValue] == 1)
+    {
+        job->largeFileSize = 1;
+    }
+    else
+    {
+        job->largeFileSize = 0;
+    }
+    /* We set http optimized mp4 here */
+    if( [[queueToApply objectForKey:@"Mp4HttpOptimize"] intValue] == 1 )
+    {
+        job->mp4_optimize = 1;
+    }
+    else
+    {
+        job->mp4_optimize = 0;
+    }
+
+       
+    /* We set the chapter marker extraction here based on the format being
+     mpeg4 or mkv and the checkbox being checked */
+    if ([[queueToApply objectForKey:@"ChapterMarkers"] intValue] == 1)
+    {
+        job->chapter_markers = 1;
+        
+        /* now lets get our saved chapter names out the array in the queue file
+         * and insert them back into the title chapter list. We have it here,
+         * because unless we are inserting chapter markers there is no need to
+         * spend the overhead of iterating through the chapter names array imo
+         * Also, note that if for some reason we don't apply chapter names, the
+         * chapters just come out 001, 002, etc. etc.
+         */
+         
+        NSMutableArray *ChapterNamesArray = [queueToApply objectForKey:@"ChapterNames"];
+        int i = 0;
+        NSEnumerator *enumerator = [ChapterNamesArray objectEnumerator];
+        id tempObject;
+        while (tempObject = [enumerator nextObject])
+        {
+            hb_chapter_t *chapter = (hb_chapter_t *) hb_list_item( title->list_chapter, i );
+            if( chapter != NULL )
+            {
+                strncpy( chapter->title, [tempObject UTF8String], 1023);
+                chapter->title[1023] = '\0';
+            }
+            i++;
+        }
+    }
+    else
+    {
+        job->chapter_markers = 0;
+    }
+    
+    if( job->vcodec & HB_VCODEC_X264 )
+    {
+               if ([[queueToApply objectForKey:@"Mp4iPodCompatible"] intValue] == 1)
+           {
+            job->ipod_atom = 1;
+               }
+        else
+        {
+            job->ipod_atom = 0;
+        }
+               
+               /* Set this flag to switch from Constant Quantizer(default) to Constant Rate Factor Thanks jbrjake
+         Currently only used with Constant Quality setting*/
+               if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0 && [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2)
+               {
+               job->crf = 1;
+               }
+               /* Below Sends x264 options to the core library if x264 is selected*/
+               /* Lets use this as per Nyx, Thanks Nyx!*/
+               job->x264opts = (char *)calloc(1024, 1); /* Fixme, this just leaks */
+               /* Turbo first pass if two pass and Turbo First pass is selected */
+               if( [[queueToApply objectForKey:@"VideoTwoPass"] intValue] == 1 && [[queueToApply objectForKey:@"VideoTurboTwoPass"] intValue] == 1 )
+               {
+                       /* pass the "Turbo" string to be appended to the existing x264 opts string into a variable for the first pass */
+                       NSString *firstPassOptStringTurbo = @":ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0";
+                       /* append the "Turbo" string variable to the existing opts string.
+             Note: the "Turbo" string must be appended, not prepended to work properly*/
+                       NSString *firstPassOptStringCombined = [[queueToApply objectForKey:@"x264Option"] stringByAppendingString:firstPassOptStringTurbo];
+                       strcpy(job->x264opts, [firstPassOptStringCombined UTF8String]);
+               }
+               else
+               {
+                       strcpy(job->x264opts, [[queueToApply objectForKey:@"x264Option"] UTF8String]);
+               }
+        
+    }
+    
+    
+    /* Picture Size Settings */
+    job->width = [[queueToApply objectForKey:@"PictureWidth"]  intValue];
+    job->height = [[queueToApply objectForKey:@"PictureHeight"]  intValue];
+    
+    job->keep_ratio = [[queueToApply objectForKey:@"PictureKeepRatio"]  intValue];
+    job->anamorphic.mode = [[queueToApply objectForKey:@"PicturePAR"]  intValue];
+    if ([[queueToApply objectForKey:@"PicturePAR"]  intValue] == 3)
+    {
+        /* insert our custom values here for capuj */
+        job->width = [[queueToApply objectForKey:@"PicturePARStorageWidth"]  intValue];
+        job->height = [[queueToApply objectForKey:@"PicturePARStorageHeight"]  intValue];
+        
+        job->anamorphic.par_width = [[queueToApply objectForKey:@"PicturePARPixelWidth"]  intValue];
+        job->anamorphic.par_height = [[queueToApply objectForKey:@"PicturePARPixelHeight"]  intValue];
+        
+        job->anamorphic.dar_width = [[queueToApply objectForKey:@"PicturePARDisplayWidth"]  floatValue];
+        job->anamorphic.dar_height = [[queueToApply objectForKey:@"PicturePARDisplayHeight"]  floatValue];
+    }
+    
+    /* Here we use the crop values saved at the time the preset was saved */
+    job->crop[0] = [[queueToApply objectForKey:@"PictureTopCrop"]  intValue];
+    job->crop[1] = [[queueToApply objectForKey:@"PictureBottomCrop"]  intValue];
+    job->crop[2] = [[queueToApply objectForKey:@"PictureLeftCrop"]  intValue];
+    job->crop[3] = [[queueToApply objectForKey:@"PictureRightCrop"]  intValue];
+    
+    /* Video settings */
+    /* Framerate */
+    
+    /* Set vfr to 0 as it's only on if using same as source in the framerate popup
+     * and detelecine is on, so we handle that in the logic below
+     */
+    job->vfr = 0;
+    if( [[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue] > 0 )
+    {
+        /* a specific framerate has been chosen */
+        job->vrate      = 27000000;
+        job->vrate_base = hb_video_rates[[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue]-1].rate;
+        /* We are not same as source so we set job->cfr to 1 
+         * to enable constant frame rate since user has specified
+         * a specific framerate*/
+        job->cfr = 1;
+    }
+    else
+    {
+        /* We are same as source (variable) */
+        job->vrate      = [[queueToApply objectForKey:@"JobVrate"] intValue];
+        job->vrate_base = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
+        /* We are same as source so we set job->cfr to 0 
+         * to enable true same as source framerate */
+        job->cfr = 0;
+        /* If we are same as source and we have detelecine on, we need to turn on
+         * job->vfr
+         */
+        if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
+        {
+            job->vfr = 1;
+        }
+    }
+    
+    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] != 2 )
+    {
+        /* Target size.
+         Bitrate should already have been calculated and displayed
+         in fVidBitrateField, so let's just use it same as abr*/
+        job->vquality = -1.0;
+        job->vbitrate = [[queueToApply objectForKey:@"VideoAvgBitrate"] intValue];
+    }
+    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 2 )
+    {
+        job->vquality = [[queueToApply objectForKey:@"VideoQualitySlider"] floatValue];
+        job->vbitrate = 0;
+        
+    }
+    
+    job->grayscale = [[queueToApply objectForKey:@"VideoGrayScale"] intValue];
+    
+
+
+#pragma mark -
+#pragma mark Process Subtitles to libhb
+
+/* Map the settings in the dictionaries for the SubtitleList array to match title->list_subtitle
+ * which means that we need to account for the offset of non source language settings in from
+ * the NSPopUpCell menu. For all of the objects in the SubtitleList array this means 0 is "None"
+ * from the popup menu, additionally the first track has "Foreign Audio Search" at 1. So we use
+ * an int to offset the index number for the objectForKey:@"subtitleSourceTrackNum" to map that
+ * to the source tracks position in title->list_subtitle.
+ */
+
+int subtitle = nil;
+int force;
+int burned;
+int def;
+bool one_burned = FALSE;
+
+    int i = 0;
+    NSEnumerator *enumerator = [[queueToApply objectForKey:@"SubtitleList"] objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
+    {
+        
+        subtitle = [[tempObject objectForKey:@"subtitleSourceTrackNum"] intValue];
+        force = [[tempObject objectForKey:@"subtitleTrackForced"] intValue];
+        burned = [[tempObject objectForKey:@"subtitleTrackBurned"] intValue];
+        def = [[tempObject objectForKey:@"subtitleTrackDefault"] intValue];
+        
+        /* since the subtitleSourceTrackNum 0 is "None" in our array of the subtitle popups,
+         * we want to ignore it for display as well as encoding.
+         */
+        if (subtitle > 0)
+        {
+            /* if i is 0, then we are in the first item of the subtitles which we need to 
+             * check for the "Foreign Audio Search" which would be subtitleSourceTrackNum of 1
+             * bearing in mind that for all tracks subtitleSourceTrackNum of 0 is None.
+             */
+            
+            /* if we are on the first track and using "Foreign Audio Search" */ 
+            if (i == 0 && subtitle == 1)
+            {
+                [self writeToActivityLog: "Foreign Language Search: %d", 1];
+                
+                job->indepth_scan = 1;
+                if (burned == 1 || job->mux != HB_MUX_MP4)
+                {
+                    if (burned != 1 && job->mux == HB_MUX_MKV)
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else
+                    {
+                        job->select_subtitle_config.dest = hb_subtitle_config_s::RENDERSUB;
+                    }
+                    
+                    job->select_subtitle_config.force = force;
+                    job->select_subtitle_config.default_track = def;
+                }
+                
+                
+            }
+            else
+            {
+                
+                /* for the actual source tracks, we must subtract the non source entries so 
+                 * that the menu index matches the source subtitle_list index for convenience */
+                if (i == 0)
+                {
+                    /* for the first track, the source tracks start at menu index 2 ( None is 0,
+                     * Foreign Language Search is 1) so subtract 2 */
+                    subtitle = subtitle - 2;
+                }
+                else
+                {
+                    /* for all other tracks, the source tracks start at menu index 1 (None is 0)
+                     * so subtract 1. */
+                    
+                    subtitle = subtitle - 1;
+                }
+                
+                /* We are setting a source subtitle so access the source subtitle info */  
+                hb_subtitle_t * subt;
+                
+                subt = (hb_subtitle_t *)hb_list_item(title->list_subtitle, subtitle);
+                
+                if (subt != NULL)
+                {
+                    [self writeToActivityLog: "Setting Subtitle: %s", subt];
+
+                    hb_subtitle_config_t sub_config = subt->config;
+                    
+                    if (!burned && job->mux == HB_MUX_MKV && 
+                        subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        sub_config.dest = hb_subtitle_config_s::PASSTHRUSUB;
+                    }
+                    else if (!burned && job->mux == HB_MUX_MP4 && 
+                             subt->format == hb_subtitle_s::PICTURESUB)
+                    {
+                        // Skip any non-burned vobsubs when output is mp4
+                        continue;
+                    }
+                    else if ( burned && subt->format == hb_subtitle_s::PICTURESUB )
+                    {
+                        // Only allow one subtitle to be burned into the video
+                        if (one_burned)
+                            continue;
+                        one_burned = TRUE;
+                    }
+                    sub_config.force = force;
+                    sub_config.default_track = def;
+                    hb_subtitle_add( job, &sub_config, subtitle );
+                }   
+                
+            }
+        }
+        i++;
+    }
+
+#pragma mark -
+
+   
+    /* Audio tracks and mixdowns */
+    /* Lets make sure there arent any erroneous audio tracks in the job list, so lets make sure its empty*/
+    int audiotrack_count = hb_list_count(job->list_audio);
+    for( int i = 0; i < audiotrack_count;i++)
+    {
+        hb_audio_t * temp_audio = (hb_audio_t*) hb_list_item( job->list_audio, 0 );
+        hb_list_rem(job->list_audio, temp_audio);
+    }
+    /* Now lets add our new tracks to the audio list here */
+    if ([[queueToApply objectForKey:@"Audio1Track"] intValue] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [[queueToApply objectForKey:@"Audio1Track"] intValue] - 1;
+        audio->out.codec = [[queueToApply objectForKey:@"JobAudio1Encoder"] intValue];
+        audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio1Mixdown"] intValue];
+        audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio1Bitrate"] intValue];
+        audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio1Samplerate"] intValue];
+        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio1TrackDRCSlider"] floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+    }  
+    if ([[queueToApply objectForKey:@"Audio2Track"] intValue] > 0)
+    {
+        
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
+        [self writeToActivityLog: "prepareJob audiotrack 2 is: %d", audio->in.track];
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [[queueToApply objectForKey:@"Audio2Track"] intValue] - 1;
+        audio->out.codec = [[queueToApply objectForKey:@"JobAudio2Encoder"] intValue];
+        audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio2Mixdown"] intValue];
+        audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio2Bitrate"] intValue];
+        audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio2Samplerate"] intValue];
+        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio2TrackDRCSlider"] floatValue];
+        
+        hb_audio_add( job, audio );
         free(audio);
     }
     
@@ -2656,20 +3534,11 @@ fWorkingCount = 0;
         audio->out.mixdown = [[queueToApply objectForKey:@"JobAudio4Mixdown"] intValue];
         audio->out.bitrate = [[queueToApply objectForKey:@"JobAudio4Bitrate"] intValue];
         audio->out.samplerate = [[queueToApply objectForKey:@"JobAudio4Samplerate"] intValue];
-        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio3TrackDRCSlider"] floatValue];
+        audio->out.dynamic_range_compression = [[queueToApply objectForKey:@"Audio4TrackDRCSlider"] floatValue];
         
         hb_audio_add( job, audio );
-        free(audio);
-    }
-    
-    /* set vfr according to the Picture Window */
-    if ([[queueToApply objectForKey:@"VFR"] intValue] == 1)
-    {
-        job->vfr = 1;
-    }
-    else
-    {
-        job->vfr = 0;
+        
+
     }
     
     /* Filters */ 
@@ -2681,37 +3550,64 @@ fWorkingCount = 0;
     /* Detelecine */
     if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 1)
     {
+        //if ([queueToApply objectForKey:@"PictureDetelecineCustom"])
         hb_list_add( job->filters, &hb_filter_detelecine );
     }
-    
-    /* Decomb */
-    if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
+    if ([[queueToApply objectForKey:@"PictureDetelecine"] intValue] == 2)
     {
-        /* Run old deinterlacer fd by default */
-        hb_filter_decomb.settings = (char *) [[queueToApply objectForKey:@"JobPictureDecomb"] UTF8String];
-        hb_list_add( job->filters, &hb_filter_decomb );
+        /* use a custom detelecine string */
+        hb_filter_detelecine.settings = (char *) [[queueToApply objectForKey:@"PictureDetelecineCustom"] UTF8String];
+        hb_list_add( job->filters, &hb_filter_detelecine );
     }
     
-    /* Deinterlace */
-    if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
+    if ([[queueToApply objectForKey:@"PictureDecombDeinterlace"] intValue] == 1)
     {
-        /* Run old deinterlacer fd by default */
-        hb_filter_deinterlace.settings = "-1"; 
-        hb_list_add( job->filters, &hb_filter_deinterlace );
-    }
-    else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
-    {
-        /* Yadif mode 0 (without spatial deinterlacing.) */
-        hb_filter_deinterlace.settings = "2"; 
-        hb_list_add( job->filters, &hb_filter_deinterlace );            
+        /* Decomb */
+        if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 1)
+        {
+            /* Run old deinterlacer fd by default */
+            hb_list_add( job->filters, &hb_filter_decomb );
+        }
+        /* we add the custom string if present */
+        if ([[queueToApply objectForKey:@"PictureDecomb"] intValue] == 2)
+        {
+            /* use a custom decomb string */
+            hb_filter_decomb.settings = (char *) [[queueToApply objectForKey:@"PictureDecombCustom"] UTF8String];
+            hb_list_add( job->filters, &hb_filter_decomb );
+        }
+        
     }
-    else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
+    else
     {
-        /* Yadif (with spatial deinterlacing) */
-        hb_filter_deinterlace.settings = "0"; 
-        hb_list_add( job->filters, &hb_filter_deinterlace );            
+        
+        /* Deinterlace */
+        if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 1)
+        {
+            /* Run old deinterlacer fd by default */
+            hb_filter_deinterlace.settings = "-1"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );
+        }
+        else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 2)
+        {
+            /* Yadif mode 0 (without spatial deinterlacing.) */
+            hb_filter_deinterlace.settings = "2"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+        else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 3)
+        {
+            /* Yadif (with spatial deinterlacing) */
+            hb_filter_deinterlace.settings = "0"; 
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+        else if ([[queueToApply objectForKey:@"PictureDeinterlace"] intValue] == 4)
+        {
+            /* we add the custom string if present */
+            hb_filter_deinterlace.settings = (char *) [[queueToApply objectForKey:@"PictureDeinterlaceCustom"] UTF8String];
+            hb_list_add( job->filters, &hb_filter_deinterlace );            
+        }
+        
+        
     }
-       
     /* Denoise */
        if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 1) // Weak in popup
        {
@@ -2728,13 +3624,24 @@ fWorkingCount = 0;
                hb_filter_denoise.settings = "7:7:5:5"; 
         hb_list_add( job->filters, &hb_filter_denoise );       
        }
+    else if ([[queueToApply objectForKey:@"PictureDenoise"] intValue] == 4) // Custom in popup
+       {
+               /* we add the custom string if present */
+        hb_filter_denoise.settings = (char *) [[queueToApply objectForKey:@"PictureDenoiseCustom"] UTF8String];
+        hb_list_add( job->filters, &hb_filter_denoise );       
+       }
     
     /* Deblock  (uses pp7 default) */
-    if ([[queueToApply objectForKey:@"PictureDeblock"] intValue] == 1)
+    /* NOTE: even though there is a valid deblock setting of 0 for the filter, for 
+     * the macgui's purposes a value of 0 actually means to not even use the filter
+     * current hb_filter_deblock.settings valid ranges are from 5 - 15 
+     */
+    if ([[queueToApply objectForKey:@"PictureDeblock"] intValue] != 0)
     {
+        hb_filter_deblock.settings = (char *) [[queueToApply objectForKey:@"PictureDeblock"] UTF8String];
         hb_list_add( job->filters, &hb_filter_deblock );
     }
-    
+[self writeToActivityLog: "prepareJob exiting"];    
 }
 
 
@@ -2751,18 +3658,51 @@ fWorkingCount = 0;
                NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
         return;
        }
-
-    /* We check for duplicate name here */
-       if( [[NSFileManager defaultManager] fileExistsAtPath:
-            [fDstFile2Field stringValue]] )
+    
+    BOOL fileExists;
+    fileExists = NO;
+    
+    BOOL fileExistsInQueue;
+    fileExistsInQueue = NO;
+    
+    /* We check for and existing file here */
+    if([[NSFileManager defaultManager] fileExistsAtPath: [fDstFile2Field stringValue]])
     {
-        NSBeginCriticalAlertSheet( NSLocalizedString( @"File already exists", @"" ),
-            NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
-            @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
-            NULL, NULL, [NSString stringWithFormat:
-            NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
-            [fDstFile2Field stringValue]] );
-        // overwriteAddToQueueAlertDone: will be called when the alert is dismissed.
+        fileExists = YES;
+    }
+    
+    /* We now run through the queue and make sure we are not overwriting an exisiting queue item */
+    int i = 0;
+    NSEnumerator *enumerator = [QueueFileArray objectEnumerator];
+       id tempObject;
+       while (tempObject = [enumerator nextObject])
+       {
+               NSDictionary *thisQueueDict = tempObject;
+               if ([[thisQueueDict objectForKey:@"DestinationPath"] isEqualToString: [fDstFile2Field stringValue]])
+               {
+                       fileExistsInQueue = YES;        
+               }
+        i++;
+       }
+    
+    
+       if(fileExists == YES)
+    {
+        NSBeginCriticalAlertSheet( NSLocalizedString( @"File already exists.", @"" ),
+                                  NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
+                                  @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
+                                  NULL, NULL, [NSString stringWithFormat:
+                                               NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
+                                               [fDstFile2Field stringValue]] );
+    }
+    else if (fileExistsInQueue == YES)
+    {
+    NSBeginCriticalAlertSheet( NSLocalizedString( @"There is already a queue item for this destination.", @"" ),
+                                  NSLocalizedString( @"Cancel", @"" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
+                                  @selector( overwriteAddToQueueAlertDone:returnCode:contextInfo: ),
+                                  NULL, NULL, [NSString stringWithFormat:
+                                               NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
+                                               [fDstFile2Field stringValue]] );
     }
     else
     {
@@ -2791,59 +3731,63 @@ fWorkingCount = 0;
 */
 - (IBAction) Rip: (id) sender
 {
+    [self writeToActivityLog: "Rip: Pending queue count is %d", fPendingCount];
     /* Rip or Cancel ? */
     hb_state_t s;
     hb_get_state2( fQueueEncodeLibhb, &s );
-
+    
     if(s.state == HB_STATE_WORKING || s.state == HB_STATE_PAUSED)
        {
         [self Cancel: sender];
         return;
     }
     
-    // If there are jobs in the queue, then this is a rip the queue
+    /* We check to see if we need to warn the user that the computer will go to sleep
+                 or shut down when encoding is finished */
+                [self remindUserOfSleepOrShutdown];
     
-    if ([QueueFileArray count] > 0)
+    // If there are pending jobs in the queue, then this is a rip the queue
+    if (fPendingCount > 0)
     {
-       /* here lets start the queue with the first item */
-      [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]]; 
-      
+        /* here lets start the queue with the first pending item */
+        [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]]; 
+        
         return;
     }
-
+    
     // Before adding jobs to the queue, check for a valid destination.
-
+    
     NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
     if ([[NSFileManager defaultManager] fileExistsAtPath:destinationDirectory] == 0) 
     {
         NSRunAlertPanel(@"Warning!", @"This is not a valid destination directory!", @"OK", nil, nil);
         return;
     }
-
+    
     /* We check for duplicate name here */
     if( [[NSFileManager defaultManager] fileExistsAtPath:[fDstFile2Field stringValue]] )
     {
         NSBeginCriticalAlertSheet( NSLocalizedString( @"File already exists", @"" ),
-            NSLocalizedString( @"Cancel", "" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
-            @selector( overWriteAlertDone:returnCode:contextInfo: ),
-            NULL, NULL, [NSString stringWithFormat:
-            NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
-            [fDstFile2Field stringValue]] );
-
+                                  NSLocalizedString( @"Cancel", "" ), NSLocalizedString( @"Overwrite", @"" ), nil, fWindow, self,
+                                  @selector( overWriteAlertDone:returnCode:contextInfo: ),
+                                  NULL, NULL, [NSString stringWithFormat:
+                                               NSLocalizedString( @"Do you want to overwrite %@?", @"" ),
+                                               [fDstFile2Field stringValue]] );
+        
         // overWriteAlertDone: will be called when the alert is dismissed. It will call doRip.
     }
     else
     {
-        /* if there are no jobs in the queue, then add this one to the queue and rip
-        otherwise, just rip the queue */
-        if([QueueFileArray count] == 0)
+        /* if there are no pending jobs in the queue, then add this one to the queue and rip
+         otherwise, just rip the queue */
+        if(fPendingCount == 0)
         {
+            [self writeToActivityLog: "Rip: No pending jobs, so sending this one to doAddToQueue"];
             [self doAddToQueue];
         }
-
-        NSString *destinationDirectory = [[fDstFile2Field stringValue] stringByDeletingLastPathComponent];
-        [[NSUserDefaults standardUserDefaults] setObject:destinationDirectory forKey:@"LastDestinationDirectory"];
+        
         /* go right to processing the new queue encode */
+        [self writeToActivityLog: "Rip: Going right to performNewQueueScan"];
         [self performNewQueueScan:[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"SourcePath"] scanTitleNum:[[[QueueFileArray objectAtIndex:currentQueueEncodeIndex] objectForKey:@"TitleNumber"]intValue]]; 
         
     }
@@ -2859,7 +3803,7 @@ fWorkingCount = 0;
     {
         /* if there are no jobs in the queue, then add this one to the queue and rip 
         otherwise, just rip the queue */
-        if( [QueueFileArray count] == 0 )
+        if( fPendingCount == 0 )
         {
             [self doAddToQueue];
         }
@@ -2911,6 +3855,50 @@ fWorkingCount = 0;
 
 
 //------------------------------------------------------------------------------------
+// Displays an alert asking user if the want to cancel encoding of current job.
+// Cancel: returns immediately after posting the alert. Later, when the user
+// acknowledges the alert, doCancelCurrentJob is called.
+//------------------------------------------------------------------------------------
+- (IBAction)Cancel: (id)sender
+{
+    if (!fQueueController) return;
+    
+  hb_pause( fQueueEncodeLibhb );
+    NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"You are currently encoding. What would you like to do ?", nil)];
+   
+    // Which window to attach the sheet to?
+    NSWindow * docWindow;
+    if ([sender respondsToSelector: @selector(window)])
+        docWindow = [sender window];
+    else
+        docWindow = fWindow;
+        
+    NSBeginCriticalAlertSheet(
+            alertTitle,
+            NSLocalizedString(@"Continue Encoding", nil),
+            NSLocalizedString(@"Cancel Current and Stop", nil),
+            NSLocalizedString(@"Cancel Current and Continue", nil),
+            docWindow, self,
+            nil, @selector(didDimissCancel:returnCode:contextInfo:), nil,
+            NSLocalizedString(@"Your encode will be cancelled if you don't continue encoding.", nil));
+    
+    // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed
+}
+
+- (void) didDimissCancel: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
+{
+   hb_resume( fQueueEncodeLibhb );
+     if (returnCode == NSAlertOtherReturn)
+    {
+        [self doCancelCurrentJob];  // <- this also stops libhb
+    }
+    if (returnCode == NSAlertAlternateReturn)
+    {
+    [self doCancelCurrentJobAndStop];
+    }
+}
+
+//------------------------------------------------------------------------------------
 // Cancels and deletes the current job and stops libhb from processing the remaining
 // encodes.
 //------------------------------------------------------------------------------------
@@ -2924,6 +3912,12 @@ fWorkingCount = 0;
      
     
     hb_stop( fQueueEncodeLibhb );
+    
+    // Delete all remaining jobs since libhb doesn't do this on its own.
+            hb_job_t * job;
+            while( ( job = hb_job(fQueueEncodeLibhb, 0) ) )
+                hb_rem( fQueueEncodeLibhb, job );
+                
     fEncodeState = 2;   // don't alert at end of processing since this was a cancel
     
     // now that we've stopped the currently encoding job, lets mark it as cancelled
@@ -2950,55 +3944,39 @@ fWorkingCount = 0;
 
 }
 
-//------------------------------------------------------------------------------------
-// Displays an alert asking user if the want to cancel encoding of current job.
-// Cancel: returns immediately after posting the alert. Later, when the user
-// acknowledges the alert, doCancelCurrentJob is called.
-//------------------------------------------------------------------------------------
-- (IBAction)Cancel: (id)sender
+- (void) doCancelCurrentJobAndStop
 {
-    if (!fQueueController) return;
+    hb_stop( fQueueEncodeLibhb );
     
-  
-    NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop encoding ?", nil)];
-   
-    // Which window to attach the sheet to?
-    NSWindow * docWindow;
-    if ([sender respondsToSelector: @selector(window)])
-        docWindow = [sender window];
-    else
-        docWindow = fWindow;
-        
-    NSBeginCriticalAlertSheet(
-            alertTitle,
-            NSLocalizedString(@"Keep Encoding", nil),
-            nil,
-            NSLocalizedString(@"Stop Encoding", nil),
-            docWindow, self,
-            nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil,
-            NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil));
+    // Delete all remaining jobs since libhb doesn't do this on its own.
+            hb_job_t * job;
+            while( ( job = hb_job(fQueueEncodeLibhb, 0) ) )
+                hb_rem( fQueueEncodeLibhb, job );
+                
+                
+    fEncodeState = 2;   // don't alert at end of processing since this was a cancel
     
-    // didDimissCancelCurrentJob:returnCode:contextInfo: will be called when the dialog is dismissed
-}
-
-- (void) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
-{
-    if (returnCode == NSAlertOtherReturn)
-        [self doCancelCurrentJob];  // <- this also stops libhb
+    // now that we've stopped the currently encoding job, lets mark it as cancelled
+    [[QueueFileArray objectAtIndex:currentQueueEncodeIndex] setObject:[NSNumber numberWithInt:3] forKey:@"Status"];
+    // and as always, save it in the queue .plist...
+    /* We save all of the Queue data here */
+    [self saveQueueFileItem];
+    // so now lets move to 
+    currentQueueEncodeIndex++ ;
+    [self writeToActivityLog: "cancelling current job and stopping the queue"];
 }
-
 - (IBAction) Pause: (id) sender
 {
     hb_state_t s;
-    hb_get_state2( fHandle, &s );
+    hb_get_state2( fQueueEncodeLibhb, &s );
 
     if( s.state == HB_STATE_PAUSED )
     {
-        hb_resume( fHandle );
+        hb_resume( fQueueEncodeLibhb );
     }
     else
     {
-        hb_pause( fHandle );
+        hb_pause( fQueueEncodeLibhb );
     }
 }
 
@@ -3036,15 +4014,31 @@ fWorkingCount = 0;
     [fSrcChapterEndPopUp   selectItemAtIndex:
         hb_list_count( title->list_chapter ) - 1];
     [self chapterPopUpChanged:nil];
-
+    
+    /* if using dvd nav, show the angle widget */
+    if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"UseDvdNav"] boolValue])
+    {
+        [fSrcAngleLabel setHidden:NO];
+        [fSrcAnglePopUp setHidden:NO];
+        
+        [fSrcAnglePopUp removeAllItems];
+        for( int i = 0; i < title->angle_count; i++ )
+        {
+            [fSrcAnglePopUp addItemWithTitle: [NSString stringWithFormat: @"%d", i + 1]];
+        }
+        [fSrcAnglePopUp selectItemAtIndex: 0];
+    }
+    else
+    {
+        [fSrcAngleLabel setHidden:YES];
+        [fSrcAnglePopUp setHidden:YES];
+    }
+    
     /* Start Get and set the initial pic size for display */
        hb_job_t * job = title->job;
        fTitle = title;
-
-       /*Set Source Size Field Here */
-    [fPicSettingsSrc setStringValue: [NSString stringWithFormat: @"%d x %d", fTitle->width, fTitle->height]];
-       
-       /* Set Auto Crop to on upon selecting a new title */
+    
+    /* Set Auto Crop to on upon selecting a new title  */
     [fPictureController setAutoCrop:YES];
     
        /* We get the originial output picture width and height and put them
@@ -3056,28 +4050,14 @@ fWorkingCount = 0;
        AutoCropLeft = job->crop[2];
        AutoCropRight = job->crop[3];
 
-       /* Run Through encoderPopUpChanged to see if there
-               needs to be any pic value modifications based on encoder settings */
-       //[self encoderPopUpChanged: NULL];
-       /* END Get and set the initial pic size for display */ 
+       /* Reset the new title in fPictureController &&  fPreviewController*/
+    [fPictureController SetTitle:title];
 
-    /* Update subtitle popups */
-    hb_subtitle_t * subtitle;
-    [fSubPopUp removeAllItems];
-    [fSubPopUp addItemWithTitle: @"None"];
-    [fSubPopUp addItemWithTitle: @"Autoselect"];
-    for( int i = 0; i < hb_list_count( title->list_subtitle ); i++ )
-    {
-        subtitle = (hb_subtitle_t *) hb_list_item( title->list_subtitle, i );
-
-        /* We cannot use NSPopUpButton's addItemWithTitle because
-           it checks for duplicate entries */
-        [[fSubPopUp menu] addItemWithTitle: [NSString stringWithCString:
-            subtitle->lang] action: NULL keyEquivalent: @""];
-    }
-    [fSubPopUp selectItemAtIndex: 0];
-
-       [self subtitleSelectionChanged:nil];
+        
+    /* Update Subtitle Table */
+    [fSubtitlesDelegate resetWithTitle:title];
+    [fSubtitlesTable reloadData];
+    
 
     /* Update chapter table */
     [fChapterTitlesDelegate resetWithTitle:title];
@@ -3116,7 +4096,7 @@ fWorkingCount = 0;
        [self calculatePictureSizing:nil];
 
    /* lets call tableViewSelected to make sure that any preset we have selected is enforced after a title change */
-       [self selectPreset:nil];
+    [self selectPreset:nil];
 }
 
 - (IBAction) chapterPopUpChanged: (id) sender
@@ -3149,6 +4129,17 @@ fWorkingCount = 0;
         duration % 60]];
 
     [self calculateBitrate: sender];
+    
+    if ( [fSrcChapterStartPopUp indexOfSelectedItem] ==  [fSrcChapterEndPopUp indexOfSelectedItem] )
+    {
+    /* Disable chapter markers for any source with less than two chapters as it makes no sense. */
+    [fCreateChapterMarkers setEnabled: NO];
+    [fCreateChapterMarkers setState: NSOffState];
+    }
+    else
+    {
+    [fCreateChapterMarkers setEnabled: YES];
+    }
 }
 
 - (IBAction) formatPopUpChanged: (id) sender
@@ -3162,6 +4153,10 @@ fWorkingCount = 0;
     [fDstMp4iPodFileCheck setHidden: YES];
     
     /* Update the Video Codec PopUp */
+    /* lets get the tag of the currently selected item first so we might reset it later */
+    int selectedVidEncoderTag;
+    selectedVidEncoderTag = [[fVidEncoderPopUp selectedItem] tag];
+    
     /* Note: we now store the video encoder int values from common.c in the tags of each popup for easy retrieval later */
     [fVidEncoderPopUp removeAllItems];
     NSMenuItem *menuItem;
@@ -3169,8 +4164,6 @@ fWorkingCount = 0;
     menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"MPEG-4 (FFmpeg)" action: NULL keyEquivalent: @""];
     [menuItem setTag: HB_VCODEC_FFMPEG];
     
-    menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"MPEG-4 (XviD)" action: NULL keyEquivalent: @""];
-    [menuItem setTag: HB_VCODEC_XVID];
     switch( format )
     {
         case 0:
@@ -3204,27 +4197,21 @@ fWorkingCount = 0;
                        [fCreateChapterMarkers setEnabled: YES];
                        break;
             
-            case 2: 
-            ext = "avi";
-            /* Add additional video encoders here */
-            menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"H.264 (x264)" action: NULL keyEquivalent: @""];
-            [menuItem setTag: HB_VCODEC_X264];
-            /* We disable the create chapters checkbox here and make sure it is unchecked*/
-                       [fCreateChapterMarkers setEnabled: NO];
-                       [fCreateChapterMarkers setState: NSOffState];
-                       break;
-            
-            case 3:
-            ext = "ogm";
-            /* Add additional video encoders here */
-            menuItem = [[fVidEncoderPopUp menu] addItemWithTitle:@"VP3 (Theora)" action: NULL keyEquivalent: @""];
-            [menuItem setTag: HB_VCODEC_THEORA];
-            /* We disable the create chapters checkbox here and make sure it is unchecked*/
-                       [fCreateChapterMarkers setEnabled: NO];
-                       [fCreateChapterMarkers setState: NSOffState];
-                       break;
+
+    }
+    /* tell fSubtitlesDelegate we have a new video container */
+    
+    [fSubtitlesDelegate containerChanged:[[fDstFormatPopUp selectedItem] tag]];
+    [fSubtitlesTable reloadData];
+    /* if we have a previously selected vid encoder tag, then try to select it */
+    if (selectedVidEncoderTag)
+    {
+        [fVidEncoderPopUp selectItemWithTag: selectedVidEncoderTag];
+    }
+    else
+    {
+        [fVidEncoderPopUp selectItemAtIndex: 0];
     }
-    [fVidEncoderPopUp selectItemAtIndex: 0];
 
     [self audioAddAudioTrackCodecs: fAudTrack1CodecPopUp];
     [self audioAddAudioTrackCodecs: fAudTrack2CodecPopUp];
@@ -3284,16 +4271,6 @@ fWorkingCount = 0;
                                     [[fDstFile2Field stringValue] stringByDeletingPathExtension], extension]];
 }
 
-- (void) shouldEnableHttpMp4CheckBox: (id) sender
-{
-    if( [[fAudTrack1CodecPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack2CodecPopUp selectedItem] tag] == HB_ACODEC_AC3 ||
-                                                        [[fAudTrack3CodecPopUp selectedItem] tag] == HB_ACODEC_AC3 ||
-                                                        [[fAudTrack4CodecPopUp selectedItem] tag] == HB_ACODEC_AC3 )
-        [fDstMp4HttpOptFileCheck setEnabled: NO];
-    else
-        [fDstMp4HttpOptFileCheck setEnabled: YES];
-}
-        
 /* Method to determine if we should change the UI
 To reflect whether or not a Preset is being used or if
 the user is using "Custom" settings by determining the sender*/
@@ -3308,6 +4285,7 @@ the user is using "Custom" settings by determining the sender*/
 
                curUserPresetChosenNum = nil;
        }
+[self calculateBitrate:nil];
 }
 
 
@@ -3333,9 +4311,9 @@ the user is using "Custom" settings by determining the sender*/
     to use the index itself but this is easier */
     if (videoEncoder == HB_VCODEC_FFMPEG)
     {
-        if (job->pixel_ratio == 2)
+        if (job->anamorphic.mode == 2)
         {
-            job->pixel_ratio = 0;
+            job->anamorphic.mode = 0;
         }
         [fPictureController setAllowLooseAnamorphic:NO];
         /* We set the iPod atom checkbox to disabled and uncheck it as its only for x264 in the mp4
@@ -3350,7 +4328,7 @@ the user is using "Custom" settings by determining the sender*/
         [fPictureController setAllowLooseAnamorphic:YES];
         [fDstMp4iPodFileCheck setEnabled: YES];
     }
-    
+    [self setupQualitySlider];
        [self calculatePictureSizing: sender];
        [self twoPassCheckboxChanged: sender];
 }
@@ -3417,6 +4395,8 @@ the user is using "Custom" settings by determining the sender*/
     [fVidTargetSizeField  setEnabled: target];
     [fVidBitrateField     setEnabled: bitrate];
     [fVidQualitySlider    setEnabled: quality];
+    [fVidQualityRFField   setEnabled: quality];
+    [fVidQualityRFLabel    setEnabled: quality];
     [fVidTwoPassCheck     setEnabled: !quality &&
         [fVidQualityMatrix isEnabled]];
     if( quality )
@@ -3431,12 +4411,88 @@ the user is using "Custom" settings by determining the sender*/
        [self customSettingUsed: sender];
 }
 
+/* Use this method to setup the quality slider for cq/rf values depending on
+ * the video encoder selected.
+ */
+- (void) setupQualitySlider
+{
+    /* Get the current slider maxValue to check for a change in slider scale later
+     * so that we can choose a new similar value on the new slider scale */
+    float previousMaxValue = [fVidQualitySlider maxValue];
+    float previousPercentOfSliderScale = [fVidQualitySlider floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1);
+    NSString * qpRFLabelString = @"QP:";
+    /* x264 0-51 */
+    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_X264)
+    {
+        [fVidQualitySlider setMinValue:0.0];
+        [fVidQualitySlider setMaxValue:51.0];
+        /* As x264 allows for qp/rf values that are fractional, we get the value from the preferences */
+        int fractionalGranularity = 1 / [[NSUserDefaults standardUserDefaults] floatForKey:@"x264CqSliderFractional"];
+        [fVidQualitySlider setNumberOfTickMarks:(([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) * fractionalGranularity) + 1];
+        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"DefaultCrf"] > 0)
+        {
+            qpRFLabelString = @"RF:";
+        }
+    }
+    /* ffmpeg  1-31 */
+    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_FFMPEG )
+    {
+        [fVidQualitySlider setMinValue:1.0];
+        [fVidQualitySlider setMaxValue:31.0];
+        [fVidQualitySlider setNumberOfTickMarks:31];
+    }
+    /* Theora 0-63 */
+    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+    {
+        [fVidQualitySlider setMinValue:0.0];
+        [fVidQualitySlider setMaxValue:63.0];
+        [fVidQualitySlider setNumberOfTickMarks:64];
+    }
+    [fVidQualityRFLabel setStringValue:qpRFLabelString];
+    
+    /* check to see if we have changed slider scales */
+    if (previousMaxValue != [fVidQualitySlider maxValue])
+    {
+        /* if so, convert the old setting to the new scale as close as possible based on percentages */
+        float rf =  ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue] + 1) * previousPercentOfSliderScale;
+        [fVidQualitySlider setFloatValue:rf];
+    }
+    
+    [self qualitySliderChanged:nil];
+}
+
 - (IBAction) qualitySliderChanged: (id) sender
 {
+    /* Our constant quality slider is in a range based
+     * on each encoders qp/rf values. The range depends
+     * on the encoder. Also, the range is inverse of quality
+     * for all of the encoders *except* for theora
+     * (ie. as the "quality" goes up, the cq or rf value
+     * actually goes down). Since the IB sliders always set
+     * their max value at the right end of the slider, we
+     * will calculate the inverse, so as the slider floatValue
+     * goes up, we will show the inverse in the rf field
+     * so, the floatValue at the right for x264 would be 51
+     * and our rf field needs to show 0 and vice versa.
+     */
+    
+    float sliderRfInverse = ([fVidQualitySlider maxValue] - [fVidQualitySlider floatValue]) + [fVidQualitySlider minValue];
+    /* If the encoder is theora, use the float, otherwise use the inverse float*/
+    float sliderRfToPercent;
+    if ([[fVidEncoderPopUp selectedItem] tag] == HB_VCODEC_THEORA)
+    {
+        [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", [fVidQualitySlider floatValue]]];
+        sliderRfToPercent = [fVidQualityRFField floatValue] / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);   
+    }
+    else
+    {
+        [fVidQualityRFField setStringValue: [NSString stringWithFormat: @"%.2f", sliderRfInverse]];
+        sliderRfToPercent = ( ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue])  - ([fVidQualityRFField floatValue] - [fVidQualitySlider minValue])) / ([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]);
+    }
     [fVidConstantCell setTitle: [NSString stringWithFormat:
-        NSLocalizedString( @"Constant quality: %.0f %%", @"" ), 100.0 *
-        [fVidQualitySlider floatValue]]];
-               [self customSettingUsed: sender];
+                                 NSLocalizedString( @"Constant quality: %.2f %%", @"" ), 100 * sliderRfToPercent]];
+    
+    [self customSettingUsed: sender];
 }
 
 - (void) controlTextDidChange: (NSNotification *) notification
@@ -3455,11 +4511,98 @@ the user is using "Custom" settings by determining the sender*/
     hb_title_t * title = (hb_title_t *) hb_list_item( list,
             [fSrcTitlePopUp indexOfSelectedItem] );
     hb_job_t * job = title->job;
+    hb_audio_config_t * audio;
+    /* For  hb_calc_bitrate in addition to the Target Size in MB out of the
+     * Target Size Field, we also need the job info for the Muxer, the Chapters
+     * as well as all of the audio track info.
+     * This used to be accomplished by simply calling prepareJob here, however
+     * since the resilient queue sets the queue array values instead of the job
+     * values directly, we duplicate the old prepareJob code here for the variables
+     * needed
+     */
+    job->chapter_start = [fSrcChapterStartPopUp indexOfSelectedItem] + 1;
+    job->chapter_end = [fSrcChapterEndPopUp indexOfSelectedItem] + 1; 
+    job->mux = [[fDstFormatPopUp selectedItem] tag];
+    
+    /* Audio goes here */
+    int audiotrack_count = hb_list_count(job->list_audio);
+    for( int i = 0; i < audiotrack_count;i++)
+    {
+        hb_audio_t * temp_audio = (hb_audio_t*) hb_list_item( job->list_audio, 0 );
+        hb_list_rem(job->list_audio, temp_audio);
+    }
+    /* Now we need our audio info here for each track if applicable */
+    if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang1PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack1CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack1MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack1BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack1RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack1DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+    }  
+    if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang2PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack2CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack2MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack2BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack2RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack2DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
+    
+    if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang3PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack3CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack3MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack3BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack3RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack3DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
 
-    [self prepareJob];
-
-    [fVidBitrateField setIntValue: hb_calc_bitrate( job,
-            [fVidTargetSizeField intValue] )];
+    if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+    {
+        audio = (hb_audio_config_t *) calloc(1, sizeof(*audio));
+        hb_audio_config_init(audio);
+        audio->in.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
+        /* We go ahead and assign values to our audio->out.<properties> */
+        audio->out.track = [fAudLang4PopUp indexOfSelectedItem] - 1;
+        audio->out.codec = [[fAudTrack4CodecPopUp selectedItem] tag];
+        audio->out.mixdown = [[fAudTrack4MixPopUp selectedItem] tag];
+        audio->out.bitrate = [[fAudTrack4BitratePopUp selectedItem] tag];
+        audio->out.samplerate = [[fAudTrack4RatePopUp selectedItem] tag];
+        audio->out.dynamic_range_compression = [fAudTrack4DrcField floatValue];
+        
+        hb_audio_add( job, audio );
+        free(audio);
+        
+    }
+       
+[fVidBitrateField setIntValue: hb_calc_bitrate( job, [fVidTargetSizeField intValue] )];
 }
 
 #pragma mark -
@@ -3472,18 +4615,9 @@ the user is using "Custom" settings by determining the sender*/
 - (IBAction) revertPictureSizeToMax: (id) sender
 {
        hb_job_t * job = fTitle->job;
-       /* We use the output picture width and height
-     as calculated from libhb right after title is set
-     in TitlePopUpChanged */
-       job->width = PicOrigOutputWidth;
-       job->height = PicOrigOutputHeight;
-    [fPictureController setAutoCrop:YES];
-       /* Here we use the auto crop values determined right after scan */
-       job->crop[0] = AutoCropTop;
-       job->crop[1] = AutoCropBottom;
-       job->crop[2] = AutoCropLeft;
-       job->crop[3] = AutoCropRight;
-    
+       /* Here we apply the title source and height */
+    job->width = fTitle->width;
+    job->height = fTitle->height;
     
     [self calculatePictureSizing: sender];
     /* We call method to change UI to reflect whether a preset is used or not*/    
@@ -3494,156 +4628,123 @@ the user is using "Custom" settings by determining the sender*/
  * Registers changes made in the Picture Settings Window.
  */
 
-- (void)pictureSettingsDidChange {
+- (void)pictureSettingsDidChange 
+{
        [self calculatePictureSizing:nil];
 }
 
 /* Get and Display Current Pic Settings in main window */
 - (IBAction) calculatePictureSizing: (id) sender
 {
-       [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", fTitle->job->width, fTitle->job->height]];
-       
-    if (fTitle->job->pixel_ratio == 1)
+       if (fTitle->job->anamorphic.mode > 0)
        {
-        int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
-        int arpwidth = fTitle->job->pixel_aspect_width;
-        int arpheight = fTitle->job->pixel_aspect_height;
-        int displayparwidth = titlewidth * arpwidth / arpheight;
-        int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
-        [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", titlewidth, displayparheight]];
-        [fPicSettingsAnamorphic setStringValue: [NSString stringWithFormat:@"%d x %d Strict", displayparwidth, displayparheight]];
-        fTitle->job->keep_ratio = 0;
-       }
-    else if (fTitle->job->pixel_ratio == 2)
-    {
-        hb_job_t * job = fTitle->job;
-        int output_width, output_height, output_par_width, output_par_height;
-        hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
-        int display_width;
-        display_width = output_width * output_par_width / output_par_height;
-
-        [fPicSettingsOutp setStringValue: [NSString stringWithFormat:@"%d x %d", output_width, output_height]];
-        [fPicSettingsAnamorphic setStringValue: [NSString stringWithFormat:@"%d x %d Loose", display_width, output_height]];
-
         fTitle->job->keep_ratio = 0;
-    }
-       else
-       {
-        [fPicSettingsAnamorphic setStringValue:@"Off"];
        }
-
-       /* Set ON/Off values for the deinterlace/keep aspect ratio according to boolean */
-       if (fTitle->job->keep_ratio > 0)
-       {
-               [fPicSettingARkeep setStringValue: @"On"];
-       }
-       else
-       {
-               [fPicSettingARkeep setStringValue: @"Off"];
-       }       
-    
-    /* Detelecine */
-    if ([fPictureController detelecine]) {
-        [fPicSettingDetelecine setStringValue: @"Yes"];
-    }
-    else {
-        [fPicSettingDetelecine setStringValue: @"No"];
-    }
     
-    /* Decomb */
-       if ([fPictureController decomb] == 0)
-       {
-               [fPicSettingDecomb setStringValue: @"Off"];
-       }
-       else if ([fPictureController decomb] == 1)
-       {
-               [fPicSettingDecomb setStringValue: @"1:2:6:9:80:16:16"];
-       }
-    else if ([fPictureController decomb] == 2)
-    {
-        [fPicSettingDecomb setStringValue:[[NSUserDefaults standardUserDefaults] stringForKey:@"DecombCustomString"]];
-    }
-
-    /* VFR (Variable Frame Rate) */
-    if ([fPictureController vfr]) {
-        /* We change the string of the fps popup to warn that vfr is on Framerate (FPS): */
-        [fVidRateField setStringValue: @"Framerate (VFR On):"]; 
-        /* for VFR we select same as source (or title framerate) and disable the popup.
-        * We know its index 0 as that is determined in titlePopUpChanged */
-        [fVidRatePopUp selectItemAtIndex: 0];
-        [fVidRatePopUp setEnabled: NO];  
-        
-    }
-    else {
-        /* make sure the label for framerate is set to its default */  
-        [fVidRateField setStringValue: @"Framerate (FPS):"];
-        [fVidRatePopUp setEnabled: YES];
-    }
+    [fPictureSizeField setStringValue: [NSString stringWithFormat:@"Picture Size: %@", [fPictureController getPictureSizeInfoString]]];
     
-       /* Deinterlace */
-       if ([fPictureController deinterlace] == 0)
-       {
-               [fPicSettingDeinterlace setStringValue: @"Off"];
-       }
-       else if ([fPictureController deinterlace] == 1)
+    NSString *picCropping;
+    /* Set the display field for crop as per boolean */
+       if (![fPictureController autoCrop])
        {
-               [fPicSettingDeinterlace setStringValue: @"Fast"];
+        picCropping =  @"Custom";
        }
-       else if ([fPictureController deinterlace] == 2)
+       else
        {
-               [fPicSettingDeinterlace setStringValue: @"Slow"];
+               picCropping =  @"Auto";
        }
-       else if ([fPictureController deinterlace] == 3)
-       {
-               [fPicSettingDeinterlace setStringValue: @"Slower"];
+    picCropping = [picCropping stringByAppendingString:[NSString stringWithFormat:@" %d/%d/%d/%d",fTitle->job->crop[0],fTitle->job->crop[1],fTitle->job->crop[2],fTitle->job->crop[3]]];
+    
+    [fPictureCroppingField setStringValue: [NSString stringWithFormat:@"Picture Cropping: %@",picCropping]];
+    
+    NSString *videoFilters;
+    videoFilters = @"";
+    /* Detelecine */
+    if ([fPictureController detelecine] == 1) 
+    {
+        videoFilters = [videoFilters stringByAppendingString:@" - Detelecine (Default)"];
+    }
+    else if ([fPictureController detelecine] == 2) 
+    {
+        videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Detelecine (%@)",[fPictureController detelecineCustomString]]];
+    }
+    
+    
+    if ([fPictureController useDecomb] == 1)
+    {
+        /* Decomb */
+        if ([fPictureController decomb] == 1)
+        {
+            videoFilters = [videoFilters stringByAppendingString:@" - Decomb (Default)"];
+        }
+        else if ([fPictureController decomb] == 2)
+        {
+            videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Decomb (%@)",[fPictureController decombCustomString]]];
+        }
+    }
+    else
+    {
+        /* Deinterlace */
+        if ([fPictureController deinterlace] > 0)
+        {
+            fTitle->job->deinterlace  = 1;
+        }
+        else
+        {
+            fTitle->job->deinterlace  = 0;
+        }
+        
+        if ([fPictureController deinterlace] == 1)
+        {
+            videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Fast)"];
+        }
+        else if ([fPictureController deinterlace] == 2)
+        {
+            videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Slow)"];
+        }
+        else if ([fPictureController deinterlace] == 3)
+        {
+            videoFilters = [videoFilters stringByAppendingString:@" - Deinterlace (Slower)"];
+        }
+        else if ([fPictureController deinterlace] == 4)
+        {
+            videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Deinterlace (%@)",[fPictureController deinterlaceCustomString]]];
+        }
        }
-               
+    
+    
     /* Denoise */
-       if ([fPictureController denoise] == 0)
-       {
-               [fPicSettingDenoise setStringValue: @"Off"];
-       }
-       else if ([fPictureController denoise] == 1)
+       if ([fPictureController denoise] == 1)
        {
-               [fPicSettingDenoise setStringValue: @"Weak"];
-       }
+               videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Weak)"];
+    }
        else if ([fPictureController denoise] == 2)
        {
-               [fPicSettingDenoise setStringValue: @"Medium"];
-       }
+               videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Medium)"];
+    }
        else if ([fPictureController denoise] == 3)
        {
-               [fPicSettingDenoise setStringValue: @"Strong"];
+               videoFilters = [videoFilters stringByAppendingString:@" - Denoise (Strong)"];
+       }
+    else if ([fPictureController denoise] == 4)
+       {
+               videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Denoise (%@)",[fPictureController denoiseCustomString]]];
        }
     
     /* Deblock */
-    if ([fPictureController deblock]) {
-        [fPicSettingDeblock setStringValue: @"Yes"];
-    }
-    else {
-        [fPicSettingDeblock setStringValue: @"No"];
+    if ([fPictureController deblock] > 0) 
+    {
+        videoFilters = [videoFilters stringByAppendingString:[NSString stringWithFormat:@" - Deblock (%d)",[fPictureController deblock]]];
     }
        
-       if (fTitle->job->pixel_ratio > 0)
-       {
-               [fPicSettingPAR setStringValue: @""];
-       }
-       else
-       {
-               [fPicSettingPAR setStringValue: @"Off"];
-       }
-       
-    /* Set the display field for crop as per boolean */
-       if (![fPictureController autoCrop])
-       {
-           [fPicSettingAutoCrop setStringValue: @"Custom"];
-       }
-       else
-       {
-               [fPicSettingAutoCrop setStringValue: @"Auto"];
-       }       
-       
+    /* Grayscale */
+    if ([fPictureController grayscale]) 
+    {
+        videoFilters = [videoFilters stringByAppendingString:@" - Grayscale"];
+    }
+    [fVideoFiltersField setStringValue: [NSString stringWithFormat:@"Video Filters: %@", videoFilters]];
     
+    //[fPictureController reloadStillPreview]; 
 }
 
 
@@ -3745,7 +4846,7 @@ the user is using "Custom" settings by determining the sender*/
         [fAudTrack1DrcSlider setFloatValue: 1.00];
         [self audioDRCSliderChanged: fAudTrack1DrcSlider];
     }
-    else if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+    else if ([[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack1MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
     {
         [fAudTrack1RatePopUp setEnabled: NO];
         [fAudTrack1BitratePopUp setEnabled: NO];
@@ -3769,7 +4870,7 @@ the user is using "Custom" settings by determining the sender*/
         [fAudTrack2DrcSlider setFloatValue: 1.00];
         [self audioDRCSliderChanged: fAudTrack2DrcSlider];
     }
-    else if ([[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+    else if ([[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack2MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
     {
         [fAudTrack2RatePopUp setEnabled: NO];
         [fAudTrack2BitratePopUp setEnabled: NO];
@@ -3793,7 +4894,7 @@ the user is using "Custom" settings by determining the sender*/
         [fAudTrack3DrcSlider setFloatValue: 1.00];
         [self audioDRCSliderChanged: fAudTrack3DrcSlider];
     }
-    else if ([[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+    else if ([[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack3MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
     {
         [fAudTrack3RatePopUp setEnabled: NO];
         [fAudTrack3BitratePopUp setEnabled: NO];
@@ -3817,7 +4918,7 @@ the user is using "Custom" settings by determining the sender*/
         [fAudTrack4DrcSlider setFloatValue: 1.00];
         [self audioDRCSliderChanged: fAudTrack4DrcSlider];
     }
-    else if ([[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_AC3)
+    else if ([[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[fAudTrack4MixPopUp selectedItem] tag] == HB_ACODEC_DCA)
     {
         [fAudTrack4RatePopUp setEnabled: NO];
         [fAudTrack4BitratePopUp setEnabled: NO];
@@ -3920,10 +5021,14 @@ the user is using "Custom" settings by determining the sender*/
         {
             case 0:
                 /* MP4 */
-                // AAC
+                // FAAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_FAAC];
-                
+
+                // CA_AAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_CA_AAC];
+
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
@@ -3931,12 +5036,18 @@ the user is using "Custom" settings by determining the sender*/
                 
             case 1:
                 /* MKV */
-                // AAC
+                // FAAC
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (faac)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_FAAC];
+                // CA_AAC
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AAC (CoreAudio)" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_CA_AAC];
                 // AC3 Passthru
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"AC3 Passthru" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_AC3];
+                // DTS Passthru
+                menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"DTS Passthru" action: NULL keyEquivalent: @""];
+                [menuItem setTag: HB_ACODEC_DCA];
                 // MP3
                 menuItem = [[audiocodecPopUp menu] addItemWithTitle:@"MP3 (lame)" action: NULL keyEquivalent: @""];
                 [menuItem setTag: HB_ACODEC_LAME];
@@ -4102,6 +5213,13 @@ the user is using "Custom" settings by determining the sender*/
                                                action: NULL keyEquivalent: @""];
              [menuItem setTag: HB_ACODEC_AC3];   
             }
+            else if (audio->in.codec == HB_ACODEC_DCA && acodec == HB_ACODEC_DCA)
+            {
+            NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                 [NSString stringWithCString: "DTS Passthru"]
+                                               action: NULL keyEquivalent: @""];
+             [menuItem setTag: HB_ACODEC_DCA]; 
+            }
             else
             {
                 
@@ -4184,6 +5302,17 @@ the user is using "Custom" settings by determining the sender*/
                     maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
                 }
                 
+                /* do we want to add a DTS Passthru option ? HB_ACODEC_DCA*/
+                if (audio->in.codec == HB_ACODEC_DCA && acodec == HB_ACODEC_DCA) 
+                {
+                    NSMenuItem *menuItem = [[mixdownPopUp menu] addItemWithTitle:
+                                            [NSString stringWithCString: hb_audio_mixdowns[5].human_readable_name]
+                                                                          action: NULL keyEquivalent: @""];
+                    [menuItem setTag: HB_ACODEC_DCA];
+                    if (minMixdownUsed == 0) minMixdownUsed = hb_audio_mixdowns[5].amixdown;
+                    maxMixdownUsed = MAX(maxMixdownUsed, hb_audio_mixdowns[5].amixdown);
+                }
+                
                 /* auto-select the best mixdown based on our saved mixdown preference */
                 
                 /* for now, this is hard-coded to a "best" mixdown of HB_AMIXDOWN_DOLBYPLII */
@@ -4232,6 +5361,24 @@ the user is using "Custom" settings by determining the sender*/
                     [audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
                 }
             }
+            
+            /* In the case of a source track that is not DTS and the user tries to use DTS Passthru (which does not work)
+             * we force the Audio Codec choice back to a workable codec. We use MP3 for avi and aac for all
+             * other containers.
+             */
+            if (audio->in.codec != HB_ACODEC_DCA && [[audiocodecPopUp selectedItem] tag] == HB_ACODEC_DCA)
+            {
+                /* If we are using the avi container, we select MP3 as there is no aac available*/
+                if ([[fDstFormatPopUp selectedItem] tag] == HB_MUX_AVI)
+                {
+                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_LAME];
+                }
+                else
+                {
+                    [audiocodecPopUp selectItemWithTag: HB_ACODEC_FAAC];
+                }
+            }
+            
             /* Setup our samplerate and bitrate popups we will need based on mixdown */
             [self audioTrackMixdownChanged: mixdownPopUp];            
         }
@@ -4240,7 +5387,6 @@ the user is using "Custom" settings by determining the sender*/
     if( [fDstFormatPopUp indexOfSelectedItem] == 0 )
     {
         [self autoSetM4vExtension: sender];
-        [self shouldEnableHttpMp4CheckBox: sender];
     }
 }
 
@@ -4324,7 +5470,22 @@ the user is using "Custom" settings by determining the sender*/
                 maxbitrate = 160;
                 break;
             }
-            
+
+        case HB_ACODEC_CA_AAC:
+            /* check if we have a 6ch discrete conversion in either audio track */
+            if ([[mixdownPopUp selectedItem] tag] == HB_AMIXDOWN_6CH)
+            {
+                minbitrate = 128;
+                maxbitrate = 768;
+                break;
+            }
+            else
+            {
+                minbitrate = 64;
+                maxbitrate = 320;
+                break;
+            }
+
             case HB_ACODEC_LAME:
             /* Lame is happy using our min bitrate of 32 kbps */
             minbitrate = 32;
@@ -4365,7 +5526,7 @@ the user is using "Custom" settings by determining the sender*/
     int inputbitrate = audio->in.bitrate / 1000;
     int inputsamplerate = audio->in.samplerate;
     
-    if ([[mixdownPopUp selectedItem] tag] != HB_ACODEC_AC3)
+    if ([[mixdownPopUp selectedItem] tag] != HB_ACODEC_AC3 && [[mixdownPopUp selectedItem] tag] != HB_ACODEC_DCA)
     {
         [bitratePopUp removeAllItems];
         
@@ -4413,11 +5574,11 @@ the user is using "Custom" settings by determining the sender*/
     [sampleratePopUp selectItemWithTag: inputsamplerate];
     
     
-    /* Since AC3 Pass Thru uses the input ac3 bitrate and sample rate, we get the input tracks
-    * bitrate and dispay it in the bitrate popup even though libhb happily ignores any bitrate input from
+    /* Since AC3 Pass Thru and DTS Pass Thru uses the input bitrate and sample rate, we get the input tracks
+    * bitrate and display it in the bitrate popup even though libhb happily ignores any bitrate input from
     * the gui. We do this for better user feedback in the audio tab as well as the queue for the most part
     */
-    if ([[mixdownPopUp selectedItem] tag] == HB_ACODEC_AC3)
+    if ([[mixdownPopUp selectedItem] tag] == HB_ACODEC_AC3 || [[mixdownPopUp selectedItem] tag] == HB_ACODEC_DCA)
     {
         
         /* lets also set the bitrate popup to the input bitrate as thats what passthru will use */
@@ -4442,7 +5603,7 @@ the user is using "Custom" settings by determining the sender*/
         [drcSlider setEnabled: YES];
         [drcField setEnabled: YES];
     }
-    
+[self calculateBitrate:nil];    
 }
 
 - (IBAction) audioDRCSliderChanged: (id) sender
@@ -4469,6 +5630,14 @@ the user is using "Custom" settings by determining the sender*/
         drcSlider = fAudTrack4DrcSlider;
         drcField = fAudTrack4DrcField;
     }
+    
+    /* If we are between 0.0 and 1.0 on the slider, snap it to 1.0 */
+    if ([drcSlider floatValue] > 0.0 && [drcSlider floatValue] < 1.0)
+    {
+        [drcSlider setFloatValue:1.0];
+    }
+    
+    
     [drcField setStringValue: [NSString stringWithFormat: @"%.2f", [drcSlider floatValue]]];
     /* For now, do not call this until we have an intelligent way to determine audio track selections
     * compared to presets
@@ -4476,22 +5645,6 @@ the user is using "Custom" settings by determining the sender*/
     //[self customSettingUsed: sender];
 }
 
-- (IBAction) subtitleSelectionChanged: (id) sender
-{
-       if ([fSubPopUp indexOfSelectedItem] == 0)
-       {
-        [fSubForcedCheck setState: NSOffState];
-        [fSubForcedCheck setEnabled: NO];      
-       }
-       else
-       {
-        [fSubForcedCheck setEnabled: YES];     
-       }
-       
-}
-
-
-
 
 #pragma mark -
 #pragma mark Open New Windows
@@ -4552,45 +5705,134 @@ the user is using "Custom" settings by determining the sender*/
 
 - (IBAction) showPicturePanel: (id) sender
 {
-       hb_list_t  * list  = hb_get_titles( fHandle );
-    hb_title_t * title = (hb_title_t *) hb_list_item( list,
-            [fSrcTitlePopUp indexOfSelectedItem] );
-    [fPictureController showPanelInWindow:fWindow forTitle:title];
+       [fPictureController showPictureWindow:sender];
+}
+
+- (void) picturePanelFullScreen
+{
+       [fPictureController setToFullScreenMode];
+}
+
+- (void) picturePanelWindowed
+{
+       [fPictureController setToWindowedMode];
+}
+
+- (IBAction) showPreviewWindow: (id) sender
+{
+       [fPictureController showPreviewWindow:sender];
 }
 
 #pragma mark -
 #pragma mark Preset Outline View Methods
 #pragma mark - Required
 /* These are required by the NSOutlineView Datasource Delegate */
+
+
+/* used to specify the number of levels to show for each item */
+- (int)outlineView:(NSOutlineView *)fPresetsOutlineView numberOfChildrenOfItem:(id)item
+{
+    /* currently use no levels to test outline view viability */
+    if (item == nil) // for an outline view the root level of the hierarchy is always nil
+    {
+        return [UserPresets count];
+    }
+    else
+    {
+        /* we need to return the count of the array in ChildrenArray for this folder */
+        NSArray *children = nil;
+        children = [item objectForKey:@"ChildrenArray"];
+        if ([children count] > 0)
+        {
+            return [children count];
+        }
+        else
+        {
+            return 0;
+        }
+    }
+}
+
 /* We use this to deterimine children of an item */
 - (id)outlineView:(NSOutlineView *)fPresetsOutlineView child:(NSInteger)index ofItem:(id)item
 {
-if (item == nil)
-        return [UserPresets objectAtIndex:index];
+    
+    /* we need to return the count of the array in ChildrenArray for this folder */
+    NSArray *children = nil;
+    if (item == nil)
+    {
+        children = UserPresets;
+    }
+    else
+    {
+        if ([item objectForKey:@"ChildrenArray"])
+        {
+            children = [item objectForKey:@"ChildrenArray"];
+        }
+    }   
+    if ((children == nil) || ( [children count] <= (NSUInteger) index))
+    {
+        return nil;
+    }
+    else
+    {
+        return [children objectAtIndex:index];
+    }
+    
     
     // We are only one level deep, so we can't be asked about children
-    NSAssert (NO, @"Presets View outlineView:child:ofItem: currently can't handle nested items.");
-    return nil;
+    //NSAssert (NO, @"Presets View outlineView:child:ofItem: currently can't handle nested items.");
+    //return nil;
 }
+
 /* We use this to determine if an item should be expandable */
 - (BOOL)outlineView:(NSOutlineView *)fPresetsOutlineView isItemExpandable:(id)item
 {
-
-    /* For now, we maintain one level, so set to no
-    * when nested, we set to yes for any preset "folders"
-    */
-    return NO;
-
-}
-/* used to specify the number of levels to show for each item */
-- (int)outlineView:(NSOutlineView *)fPresetsOutlineView numberOfChildrenOfItem:(id)item
-{
-    /* currently use no levels to test outline view viability */
+    
+    /* we need to return the count of the array in ChildrenArray for this folder */
+    NSArray *children= nil;
     if (item == nil)
-        return [UserPresets count];
+    {
+        children = UserPresets;
+    }
+    else
+    {
+        if ([item objectForKey:@"ChildrenArray"])
+        {
+            children = [item objectForKey:@"ChildrenArray"];
+        }
+    }   
+    
+    /* To deterimine if an item should show a disclosure triangle
+     * we could do it by the children count as so:
+     * if ([children count] < 1)
+     * However, lets leave the triangle show even if there are no
+     * children to help indicate a folder, just like folder in the
+     * finder can show a disclosure triangle even when empty
+     */
+    
+    /* We need to determine if the item is a folder */
+   if ([[item objectForKey:@"Folder"] intValue] == 1)
+   {
+        return YES;
+    }
     else
-        return 0;
+    {
+        return NO;
+    }
+    
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item
+{
+    // Our outline view has no levels, but we can still expand every item. Doing so
+    // just makes the row taller. See heightOfRowByItem below.
+//return ![(HBQueueOutlineView*)outlineView isDragging];
+
+return YES;
 }
+
+
 /* Used to tell the outline view which information is to be displayed per item */
 - (id)outlineView:(NSOutlineView *)fPresetsOutlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
 {
@@ -4602,17 +5844,26 @@ if (item == nil)
     }
     else
     {
-        return @"something";
+        //return @"";
+        return nil;
     }
 }
 
+- (id)outlineView:(NSOutlineView *)outlineView itemForPersistentObject:(id)object
+{
+    return [NSKeyedUnarchiver unarchiveObjectWithData:object];
+}
+- (id)outlineView:(NSOutlineView *)outlineView persistentObjectForItem:(id)item
+{
+    return [NSKeyedArchiver archivedDataWithRootObject:item];
+}
+
 #pragma mark - Added Functionality (optional)
 /* Use to customize the font and display characteristics of the title cell */
 - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
 {
     if ([[tableColumn identifier] isEqualToString:@"PresetName"])
     {
-        NSDictionary *userPresetDict = item;
         NSFont *txtFont;
         NSColor *fontColor;
         NSColor *shadowColor;
@@ -4626,7 +5877,7 @@ if (item == nil)
         }
         else
         {
-            if ([[userPresetDict objectForKey:@"Type"] intValue] == 0)
+            if ([[item objectForKey:@"Type"] intValue] == 0)
             {
                 fontColor = [NSColor blueColor];
             }
@@ -4634,15 +5885,21 @@ if (item == nil)
             {
                 fontColor = [NSColor blackColor];
             }
-            shadowColor = nil;
+            /* check to see if its a folder */
+            //if ([[item objectForKey:@"Folder"] intValue] == 1)
+            //{
+            //fontColor = [NSColor greenColor];
+            //}
+            
+            
         }
         /* We use Bold Text for the HB Default */
-        if ([[userPresetDict objectForKey:@"Default"] intValue] == 1)// 1 is HB default
+        if ([[item objectForKey:@"Default"] intValue] == 1)// 1 is HB default
         {
             txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]];
         }
         /* We use Bold Text for the User Specified Default */
-        if ([[userPresetDict objectForKey:@"Default"] intValue] == 2)// 2 is User default
+        if ([[item objectForKey:@"Default"] intValue] == 2)// 2 is User default
         {
             txtFont = [NSFont boldSystemFontOfSize: [NSFont smallSystemFontSize]];
         }
@@ -4699,7 +5956,8 @@ if (item == nil)
 - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard
 {
        // Dragging is only allowed for custom presets.
-       if ([[[UserPresets objectAtIndex:[fPresetsOutlineView selectedRow]] objectForKey:@"Type"] intValue] == 0) // 0 is built in preset
+    //[[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Default"] intValue] != 1
+       if ([[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Type"] intValue] == 0) // 0 is built in preset
     {
         return NO;
     }
@@ -4715,18 +5973,17 @@ if (item == nil)
     return YES;
 }
 
-- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index
+- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
 {
+       
        // Don't allow dropping ONTO an item since they can't really contain any children.
     
     BOOL isOnDropTypeProposal = index == NSOutlineViewDropOnItemIndex;
     if (isOnDropTypeProposal)
         return NSDragOperationNone;
     
-    
-       // Don't allow dropping INTO an item since they can't really contain any children as of yet.
-       
-    if (item != nil)
+    // Don't allow dropping INTO an item since they can't really contain any children as of yet.
+       if (item != nil)
        {
                index = [fPresetsOutlineView rowForItem: item] + 1;
                item = nil;
@@ -4737,7 +5994,7 @@ if (item == nil)
     {
         return NSDragOperationNone;
         index = MAX (index, presetCurrentBuiltInCount);
-       }
+       }    
        
     [outlineView setDropItem:item dropChildIndex:index];
     return NSDragOperationGeneric;
@@ -4745,50 +6002,58 @@ if (item == nil)
 
 
 
-- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index
+- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
 {
-    NSMutableIndexSet *moveItems = [NSMutableIndexSet indexSet];
-    
-    id obj;
-    NSEnumerator *enumerator = [fDraggedNodes objectEnumerator];
-    while (obj = [enumerator nextObject])
-    {
-        [moveItems addIndex:[UserPresets indexOfObject:obj]];
+    /* first, lets see if we are dropping into a folder */
+    if ([[fPresetsOutlineView itemAtRow:index] objectForKey:@"Folder"] && [[[fPresetsOutlineView itemAtRow:index] objectForKey:@"Folder"] intValue] == 1) // if its a folder
+       {
+    NSMutableArray *childrenArray = [[NSMutableArray alloc] init];
+    childrenArray = [[fPresetsOutlineView itemAtRow:index] objectForKey:@"ChildrenArray"];
+    [childrenArray addObject:item];
+    [[fPresetsOutlineView itemAtRow:index] setObject:[NSMutableArray arrayWithArray: childrenArray] forKey:@"ChildrenArray"];
+    [childrenArray autorelease];
+    }
+    else // We are not, so we just move the preset into the existing array 
+    {
+        NSMutableIndexSet *moveItems = [NSMutableIndexSet indexSet];
+        id obj;
+        NSEnumerator *enumerator = [fDraggedNodes objectEnumerator];
+        while (obj = [enumerator nextObject])
+        {
+            [moveItems addIndex:[UserPresets indexOfObject:obj]];
+        }
+        // Successful drop, lets rearrange the view and save it all
+        [self moveObjectsInPresetsArray:UserPresets fromIndexes:moveItems toIndex: index];
     }
-    // Successful drop, lets rearrange the view and save it all
-    [self moveObjectsInPresetsArray:UserPresets fromIndexes:moveItems toIndex: index];
     [fPresetsOutlineView reloadData];
     [self savePreset];
     return YES;
 }
 
-- (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(unsigned)insertIndex
+- (void)moveObjectsInPresetsArray:(NSMutableArray *)array fromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
 {
-    unsigned index = [indexSet lastIndex];
-    unsigned aboveInsertIndexCount = 0;
+    NSUInteger index = [indexSet lastIndex];
+    NSUInteger aboveInsertIndexCount = 0;
     
-    while (index != NSNotFound)
+    NSUInteger removeIndex;
+
+    if (index >= insertIndex)
     {
-        unsigned removeIndex;
-        
-        if (index >= insertIndex)
-        {
-            removeIndex = index + aboveInsertIndexCount;
-            aboveInsertIndexCount++;
-        }
-        else
-        {
-            removeIndex = index;
-            insertIndex--;
-        }
-        
-        id object = [[array objectAtIndex:removeIndex] retain];
-        [array removeObjectAtIndex:removeIndex];
-        [array insertObject:object atIndex:insertIndex];
-        [object release];
-        
-        index = [indexSet indexLessThanIndex:index];
+        removeIndex = index + aboveInsertIndexCount;
+        aboveInsertIndexCount++;
+    }
+    else
+    {
+        removeIndex = index;
+        insertIndex--;
     }
+
+    id object = [[array objectAtIndex:removeIndex] retain];
+    [array removeObjectAtIndex:removeIndex];
+    [array insertObject:object atIndex:insertIndex];
+    [object release];
+
+    index = [indexSet indexLessThanIndex:index];
 }
 
 
@@ -4797,12 +6062,12 @@ if (item == nil)
 
 - (IBAction)selectPreset:(id)sender
 {
-
-    if ([fPresetsOutlineView selectedRow] >= 0)
+    
+    if ([fPresetsOutlineView selectedRow] >= 0 && [[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Folder"] intValue] != 1)
     {
         chosenPreset = [fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]];
-        /* we set the preset display field in main window here */
         [fPresetSelectedDisplay setStringValue:[chosenPreset objectForKey:@"PresetName"]];
+        
         if ([[chosenPreset objectForKey:@"Default"] intValue] == 1)
         {
             [fPresetSelectedDisplay setStringValue:[NSString stringWithFormat:@"%@ (Default)", [chosenPreset objectForKey:@"PresetName"]]];
@@ -4811,67 +6076,57 @@ if (item == nil)
         {
             [fPresetSelectedDisplay setStringValue:[chosenPreset objectForKey:@"PresetName"]];
         }
+        
         /* File Format */
         [fDstFormatPopUp selectItemWithTitle:[chosenPreset objectForKey:@"FileFormat"]];
         [self formatPopUpChanged:nil];
-
+        
         /* Chapter Markers*/
         [fCreateChapterMarkers setState:[[chosenPreset objectForKey:@"ChapterMarkers"] intValue]];
+        /* check to see if we have only one chapter */
+        [self chapterPopUpChanged:nil];
+        
         /* Allow Mpeg4 64 bit formatting +4GB file sizes */
         [fDstMp4LargeFileCheck setState:[[chosenPreset objectForKey:@"Mp4LargeFile"] intValue]];
         /* Mux mp4 with http optimization */
         [fDstMp4HttpOptFileCheck setState:[[chosenPreset objectForKey:@"Mp4HttpOptimize"] intValue]];
-
+        
         /* Video encoder */
-        /* We set the advanced opt string here if applicable*/
-        [fAdvancedOptions setOptions:[chosenPreset objectForKey:@"x264Option"]];
-        /* We use a conditional to account for the new x264 encoder dropdown as well as presets made using legacy x264 settings*/
-        if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 Main)"] ||
-            [[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 iPod)"] ||
-            [[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264"])
-        {
-            [fVidEncoderPopUp selectItemWithTitle:@"H.264 (x264)"];
-            /* special case for legacy preset to check the new fDstMp4HttpOptFileCheck checkbox to set the ipod atom */
-            if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"x264 (h.264 iPod)"])
-            {
-                [fDstMp4iPodFileCheck setState:NSOnState];
-                /* We also need to add "level=30:" to the advanced opts string to set the correct level for the iPod when
-                 encountering a legacy preset as it used to be handled separately from the opt string*/
-                [fAdvancedOptions setOptions:[@"level=30:" stringByAppendingString:[fAdvancedOptions optionsString]]];
-            }
-            else
-            {
-                [fDstMp4iPodFileCheck setState:NSOffState];
-            }
-        }
-        else if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"FFmpeg"])
-        {
-            [fVidEncoderPopUp selectItemWithTitle:@"MPEG-4 (FFmpeg)"];
-        }
-        else if ([[chosenPreset objectForKey:@"VideoEncoder"] isEqualToString:@"XviD"])
-        {
-            [fVidEncoderPopUp selectItemWithTitle:@"MPEG-4 (XviD)"];
-        }
-        else
-        {
-            [fVidEncoderPopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoEncoder"]];
-        }
-
+        [fVidEncoderPopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoEncoder"]];
+        /* We set the advanced opt string here if applicable*/
+        [fAdvancedOptions setOptions:[chosenPreset objectForKey:@"x264Option"]];
+        
         /* Lets run through the following functions to get variables set there */
         [self videoEncoderPopUpChanged:nil];
         /* Set the state of ipod compatible with Mp4iPodCompatible. Only for x264*/
         [fDstMp4iPodFileCheck setState:[[chosenPreset objectForKey:@"Mp4iPodCompatible"] intValue]];
         [self calculateBitrate:nil];
-
+        
         /* Video quality */
         [fVidQualityMatrix selectCellAtRow:[[chosenPreset objectForKey:@"VideoQualityType"] intValue] column:0];
-
+        
         [fVidTargetSizeField setStringValue:[chosenPreset objectForKey:@"VideoTargetSize"]];
         [fVidBitrateField setStringValue:[chosenPreset objectForKey:@"VideoAvgBitrate"]];
-        [fVidQualitySlider setFloatValue:[[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
-
+        
+        /* Since we are now using RF Values for the slider, we detect if the preset uses an old quality float.
+         * So, check to see if the quality value is less than 1.0 which should indicate the old ".062" type
+         * quality preset. Caveat: in the case of x264, where the RF scale starts at 0, it would misinterpret
+         * a preset that uses 0.0 - 0.99 for RF as an old style preset. Not sure how to get around that one yet,
+         * though it should be a corner case since it would pretty much be a preset for lossless encoding. */
+        if ([[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue] < 1.0)
+        {
+            /* For the quality slider we need to convert the old percent's to the new rf scales */
+            float rf =  (([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) * [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]);
+            [fVidQualitySlider setFloatValue:rf];
+            
+        }
+        else
+        {
+            [fVidQualitySlider setFloatValue:([fVidQualitySlider maxValue] - [fVidQualitySlider minValue]) - [[chosenPreset objectForKey:@"VideoQualitySlider"] floatValue]];
+        }
+        
         [self videoMatrixChanged:nil];
-
+        
         /* Video framerate */
         /* For video preset video framerate, we want to make sure that Same as source does not conflict with the
          detected framerate in the fVidRatePopUp so we use index 0*/
@@ -4883,184 +6138,117 @@ if (item == nil)
         {
             [fVidRatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoFramerate"]];
         }
-
-        /* GrayScale */
-        [fVidGrayscaleCheck setState:[[chosenPreset objectForKey:@"VideoGrayScale"] intValue]];
-
+        
+        
         /* 2 Pass Encoding */
         [fVidTwoPassCheck setState:[[chosenPreset objectForKey:@"VideoTwoPass"] intValue]];
         [self twoPassCheckboxChanged:nil];
+        
         /* Turbo 1st pass for 2 Pass Encoding */
         [fVidTurboPassCheck setState:[[chosenPreset objectForKey:@"VideoTurboTwoPass"] intValue]];
-
+        
         /*Audio*/
-        if ([chosenPreset objectForKey:@"FileCodecs"])
+        /* First we check to see if we are using the current audio track layout based on AudioList array */
+        if ([chosenPreset objectForKey:@"AudioList"])
         {
-            /* We need to handle the audio codec popup by determining what was chosen from the deprecated Codecs PopUp for past presets*/
-            if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString: @"AVC/H.264 Video / AAC + AC3 Audio"])
+            /* Populate the audio widgets based on the contents of the AudioList array */
+            int i = 0;
+            NSEnumerator *enumerator = [[chosenPreset objectForKey:@"AudioList"] objectEnumerator];
+            id tempObject;
+            while (tempObject = [enumerator nextObject])
             {
-                /* We need to address setting languages etc. here in the new multi track audio panel */
-                /* Track One set here */
-                /*for track one though a track should be selected but lets check here anyway and use track one if its not.*/
-                if ([fAudLang1PopUp indexOfSelectedItem] == 0)
+                i++;
+                if( i == 1 )
                 {
-                    [fAudLang1PopUp selectItemAtIndex: 1];
+                    if ([fAudLang1PopUp indexOfSelectedItem] == 0)
+                    {
+                        [fAudLang1PopUp selectItemAtIndex: 1];
+                    }
                     [self audioTrackPopUpChanged: fAudLang1PopUp];
-                }
-                [fAudTrack1CodecPopUp selectItemWithTitle: @"AAC (faac)"];
-                [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
-                /* Track Two, set source same as track one */
-                [fAudLang2PopUp selectItemAtIndex: [fAudLang1PopUp indexOfSelectedItem]];
-                [self audioTrackPopUpChanged: fAudLang2PopUp];
-                [fAudTrack2CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
-                [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
-            }
-            else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / AAC Audio"] ||
-                     [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AAC Audio"])
-            {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack1CodecPopUp selectItemWithTitle: @"AAC (faac)"];
-                    [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
-                }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack2CodecPopUp selectItemWithTitle: @"AAC (faac)"];
-                    [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
-                }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack3CodecPopUp selectItemWithTitle: @"AAC (faac)"];
-                    [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack4CodecPopUp selectItemWithTitle: @"AAC (faac)"];
-                    [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
-                }
-            }
-            else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / AC-3 Audio"] ||
-                     [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AC-3 Audio"])
-            {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack1CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
-                    [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
-                }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack2CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
-                    [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
-                }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack3CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
-                    [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack4CodecPopUp selectItemWithTitle: @"AC3 Passthru"];
-                    [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
-                }
-            }
-            else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / MP3 Audio"] ||
-                     [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / MP3 Audio"])
-            {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack1CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
-                    [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
-                }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack2CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
-                    [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
-                }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack3CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
-                    [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack4CodecPopUp selectItemWithTitle: @"MP3 (lame)"];
-                    [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
-                }
-            }
-            else if ([[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"MPEG-4 Video / Vorbis Audio"])
-            {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack1CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
+                    [fAudTrack1CodecPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioEncoder"]];
+                    /* check our pref for core audio and use it in place of faac if applicable */
+                    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                        [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+                    {
+                        [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                    }                    
+                    
                     [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+                    [fAudTrack1MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
+                    /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+                     * mixdown*/
+                    if  ([fAudTrack1MixPopUp selectedItem] == nil)
+                    {
+                        [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
+                    }
+                    [fAudTrack1RatePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioSamplerate"]];
+                    /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+                    if (![[tempObject objectForKey:@"AudioEncoder"] isEqualToString:@"AC3 Passthru"])
+                    {
+                        [fAudTrack1BitratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioBitrate"]];
+                    }
+                    [fAudTrack1DrcSlider setFloatValue:[[tempObject objectForKey:@"AudioTrackDRCSlider"] floatValue]];
+                    [self audioDRCSliderChanged: fAudTrack1DrcSlider];
                 }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+                
+                if( i == 2 )
                 {
-                    [fAudTrack2CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
+                    
+                    if ([fAudLang2PopUp indexOfSelectedItem] == 0)
+                    {
+                        [fAudLang2PopUp selectItemAtIndex: 1];
+                    }
+                    [self audioTrackPopUpChanged: fAudLang2PopUp];
+                    [fAudTrack2CodecPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioEncoder"]];
+                    /* check our pref for core audio and use it in place of faac if applicable */
+                    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                        [[tempObject objectForKey:@"AudioEncoder"] isEqualToString: @"AAC (faac)"])
+                    {
+                        [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                    }
                     [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+                    [fAudTrack2MixPopUp selectItemWithTitle:[tempObject objectForKey:@"AudioMixdown"]];
+                    /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
+                     * mixdown*/
+                    if  ([fAudTrack2MixPopUp selectedItem] == nil)
+                    {
+                        [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
+                    }
+                    [fAudTrack2RatePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioSamplerate"]];
+                    /* We set the presets bitrate if it is *not* an AC3 track since that uses the input bitrate */
+                    if (![[tempObject objectForKey:@"AudioEncoder"] isEqualToString:@"AC3 Passthru"])
+                    {
+                        [fAudTrack2BitratePopUp selectItemWithTitle:[tempObject objectForKey:@"AudioBitrate"]];
+                    }
+                    [fAudTrack2DrcSlider setFloatValue:[[tempObject objectForKey:@"AudioTrackDRCSlider"] floatValue]];
+                    [self audioDRCSliderChanged: fAudTrack2DrcSlider];
+                    
                 }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack3CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
-                    [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack4CodecPopUp selectItemWithTitle: @"Vorbis (vorbis)"];
-                    [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
-                }
-            }
-            /* We detect here if we have the old audio sample rate and if so we apply samplerate and bitrate to the existing four tracks if chosen
-            * UNLESS the CodecPopUp is AC3 in which case the preset values are ignored in favor of rates set in audioTrackMixdownChanged*/
-            if ([chosenPreset objectForKey:@"AudioSampleRate"])
-            {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0 && [fAudTrack1CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
-                {
-                    [fAudTrack1RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
-                    [fAudTrack1BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
-                }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0 && [fAudTrack2CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
-                {
-                    [fAudTrack2RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
-                    [fAudTrack2BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
-                }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0 && [fAudTrack3CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
-                {
-                    [fAudTrack3RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
-                    [fAudTrack3BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0 && [fAudTrack4CodecPopUp titleOfSelectedItem] != @"AC3 Passthru")
-                {
-                    [fAudTrack4RatePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioSampleRate"]];
-                    [fAudTrack4BitratePopUp selectItemWithTitle:[chosenPreset objectForKey:@"AudioBitRate"]];
-                }
+                
             }
-            /* We detect here if we have the old DRC Slider and if so we apply it to the existing four tracks if chosen */
-            if ([chosenPreset objectForKey:@"AudioDRCSlider"])
+            
+             /* We now cleanup any extra audio tracks that may have been previously set if we need to */
+            
+            if (i < 4)
             {
-                if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack1DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
-                    [self audioDRCSliderChanged: fAudTrack1DrcSlider];
-                }
-                if ([fAudLang2PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack2DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
-                    [self audioDRCSliderChanged: fAudTrack2DrcSlider];
-                }
-                if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-                {
-                    [fAudTrack3DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
-                    [self audioDRCSliderChanged: fAudTrack3DrcSlider];
-                }
-                if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+                [fAudLang4PopUp selectItemAtIndex: 0];
+                [self audioTrackPopUpChanged: fAudLang4PopUp];
+                
+                if (i < 3)
                 {
-                    [fAudTrack4DrcSlider setFloatValue:[[chosenPreset objectForKey:@"AudioDRCSlider"] floatValue]];
-                    [self audioDRCSliderChanged: fAudTrack4DrcSlider];
+                    [fAudLang3PopUp selectItemAtIndex: 0];
+                    [self audioTrackPopUpChanged: fAudLang3PopUp];
+                    
+                    if (i < 2)
+                    {
+                        [fAudLang2PopUp selectItemAtIndex: 0];
+                        [self audioTrackPopUpChanged: fAudLang2PopUp];
+                    }
                 }
             }
+            
         }
-        else // since there was no codecs key in the preset we know we can use new multi-audio track presets
+        else
         {
             if ([chosenPreset objectForKey:@"Audio1Track"] > 0)
             {
@@ -5070,6 +6258,12 @@ if (item == nil)
                 }
                 [self audioTrackPopUpChanged: fAudLang1PopUp];
                 [fAudTrack1CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Encoder"]];
+                /* check our pref for core audio and use it in place of faac if applicable */
+                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                    [[chosenPreset objectForKey:@"Audio1Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack1CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack1CodecPopUp];
                 [fAudTrack1MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio1Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -5095,6 +6289,12 @@ if (item == nil)
                 }
                 [self audioTrackPopUpChanged: fAudLang2PopUp];
                 [fAudTrack2CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Encoder"]];
+                /* check our pref for core audio and use it in place of faac if applicable */
+                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                    [[chosenPreset objectForKey:@"Audio2Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack2CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack2CodecPopUp];
                 [fAudTrack2MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio2Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -5120,6 +6320,12 @@ if (item == nil)
                 }
                 [self audioTrackPopUpChanged: fAudLang3PopUp];
                 [fAudTrack3CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Encoder"]];
+                /* check our pref for core audio and use it in place of faac if applicable */
+                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                    [[chosenPreset objectForKey:@"Audio3Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack3CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack3CodecPopUp];
                 [fAudTrack3MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio3Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -5145,6 +6351,12 @@ if (item == nil)
                 }
                 [self audioTrackPopUpChanged: fAudLang4PopUp];
                 [fAudTrack4CodecPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Encoder"]];
+                /* check our pref for core audio and use it in place of faac if applicable */
+                if ([[NSUserDefaults standardUserDefaults] boolForKey: @"UseCoreAudio"] == YES && 
+                    [[chosenPreset objectForKey:@"Audio4Encoder"] isEqualToString: @"AAC (faac)"])
+                {
+                    [fAudTrack4CodecPopUp selectItemWithTitle:@"AAC (CoreAudio)"];
+                }
                 [self audioTrackPopUpChanged: fAudTrack4CodecPopUp];
                 [fAudTrack4MixPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Audio4Mixdown"]];
                 /* check to see if the selections was available, if not, rerun audioTrackPopUpChanged using the codec to just set the default
@@ -5162,22 +6374,9 @@ if (item == nil)
                 [fAudTrack4DrcSlider setFloatValue:[[chosenPreset objectForKey:@"Audio4TrackDRCSlider"] floatValue]];
                 [self audioDRCSliderChanged: fAudTrack4DrcSlider];
             }
-
-
-        }
-
-        /* We now cleanup any extra audio tracks that may be previously set if we need to, we do it here so we don't have to
-         * duplicate any code for legacy presets.*/
-        /* First we handle the legacy Codecs crazy AVC/H.264 Video / AAC + AC3 Audio atv hybrid */
-        if ([chosenPreset objectForKey:@"FileCodecs"] && [[chosenPreset objectForKey:@"FileCodecs"] isEqualToString:@"AVC/H.264 Video / AAC + AC3 Audio"])
-        {
-            [fAudLang3PopUp selectItemAtIndex: 0];
-            [self audioTrackPopUpChanged: fAudLang3PopUp];
-            [fAudLang4PopUp selectItemAtIndex: 0];
-            [self audioTrackPopUpChanged: fAudLang4PopUp];
-        }
-        else
-        {
+            
+            /* We now cleanup any extra audio tracks that may have been previously set if we need to */
+            
             if (![chosenPreset objectForKey:@"Audio2Track"] || [chosenPreset objectForKey:@"Audio2Track"] == 0)
             {
                 [fAudLang2PopUp selectItemAtIndex: 0];
@@ -5194,25 +6393,50 @@ if (item == nil)
                 [self audioTrackPopUpChanged: fAudLang4PopUp];
             }
         }
-
+        
         /*Subtitles*/
         [fSubPopUp selectItemWithTitle:[chosenPreset objectForKey:@"Subtitles"]];
         /* Forced Subtitles */
         [fSubForcedCheck setState:[[chosenPreset objectForKey:@"SubtitlesForced"] intValue]];
-
+        
         /* Picture Settings */
-        /* Note: objectForKey:@"UsesPictureSettings" now refers to picture size, this encompasses:
+        /* Note: objectForKey:@"UsesPictureSettings" refers to picture size, which encompasses:
          * height, width, keep ar, anamorphic and crop settings.
-         * picture filters are now handled separately.
-         * We will be able to actually change the key names for legacy preset keys when preset file
-         * update code is done. But for now, lets hang onto the old legacy key name for backwards compatibility.
+         * picture filters are handled separately below.
          */
         /* Check to see if the objectForKey:@"UsesPictureSettings is greater than 0, as 0 means use picture sizing "None" 
-         * and the preset completely ignores any picture sizing values in the preset.
+         * ( 2 is use max for source and 1 is use exact size when the preset was created ) and the 
+         * preset completely ignores any picture sizing values in the preset.
          */
         if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] > 0)
         {
             hb_job_t * job = fTitle->job;
+            
+            /* If Cropping is set to custom, then recall all four crop values from
+             when the preset was created and apply them */
+            if ([[chosenPreset objectForKey:@"PictureAutoCrop"]  intValue] == 0)
+            {
+                [fPictureController setAutoCrop:NO];
+                
+                /* Here we use the custom crop values saved at the time the preset was saved */
+                job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"]  intValue];
+                job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"]  intValue];
+                job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"]  intValue];
+                job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"]  intValue];
+                
+            }
+            else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
+            {
+                [fPictureController setAutoCrop:YES];
+                /* Here we use the auto crop values determined right after scan */
+                job->crop[0] = AutoCropTop;
+                job->crop[1] = AutoCropBottom;
+                job->crop[2] = AutoCropLeft;
+                job->crop[3] = AutoCropRight;
+                
+            }
+            
+            
             /* Check to see if the objectForKey:@"UsesPictureSettings is 2 which is "Use Max for the source */
             if ([[chosenPreset objectForKey:@"UsesPictureSettings"]  intValue] == 2 || [[chosenPreset objectForKey:@"UsesMaxPictureSettings"]  intValue] == 1)
             {
@@ -5228,7 +6452,7 @@ if (item == nil)
                         hb_fix_aspect( job, HB_KEEP_HEIGHT );
                     }
                 }
-                job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
+                job->anamorphic.mode = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
             }
             else // /* If not 0 or 2 we assume objectForKey:@"UsesPictureSettings is 1 which is "Use picture sizing from when the preset was set" */
             {
@@ -5236,8 +6460,9 @@ if (item == nil)
                 if (fTitle->width < [[chosenPreset objectForKey:@"PictureWidth"]  intValue] || fTitle->height < [[chosenPreset objectForKey:@"PictureHeight"]  intValue])
                 {
                     /* if so, then we use the sources height and width to avoid scaling up */
-                    job->width = fTitle->width;
-                    job->height = fTitle->height;
+                    //job->width = fTitle->width;
+                    //job->height = fTitle->height;
+                    [self revertPictureSizeToMax:nil];
                 }
                 else // source width/height is >= the preset height/width
                 {
@@ -5255,175 +6480,111 @@ if (item == nil)
                         hb_fix_aspect( job, HB_KEEP_HEIGHT );
                     }
                 }
-                job->pixel_ratio = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
+                job->anamorphic.mode = [[chosenPreset objectForKey:@"PicturePAR"]  intValue];
                 
-                
-                /* If Cropping is set to custom, then recall all four crop values from
-                 when the preset was created and apply them */
-                if ([[chosenPreset objectForKey:@"PictureAutoCrop"]  intValue] == 0)
-                {
-                    [fPictureController setAutoCrop:NO];
-                    
-                    /* Here we use the custom crop values saved at the time the preset was saved */
-                    job->crop[0] = [[chosenPreset objectForKey:@"PictureTopCrop"]  intValue];
-                    job->crop[1] = [[chosenPreset objectForKey:@"PictureBottomCrop"]  intValue];
-                    job->crop[2] = [[chosenPreset objectForKey:@"PictureLeftCrop"]  intValue];
-                    job->crop[3] = [[chosenPreset objectForKey:@"PictureRightCrop"]  intValue];
-                    
-                }
-                else /* if auto crop has been saved in preset, set to auto and use post scan auto crop */
-                {
-                    [fPictureController setAutoCrop:YES];
-                    /* Here we use the auto crop values determined right after scan */
-                    job->crop[0] = AutoCropTop;
-                    job->crop[1] = AutoCropBottom;
-                    job->crop[2] = AutoCropLeft;
-                    job->crop[3] = AutoCropRight;
-                    
-                }
-                /* If the preset has no objectForKey:@"UsesPictureFilters", then we know it is a legacy preset
-                 * and handle the filters here as before.
-                 * NOTE: This should be removed when the update presets code is done as we can be assured that legacy
-                 * presets are updated to work properly with new keys.
-                 */
-                if (![chosenPreset objectForKey:@"UsesPictureFilters"])
-                {
-                    /* Filters */
-                    /* Deinterlace */
-                    if ([chosenPreset objectForKey:@"PictureDeinterlace"])
-                    {
-                        /* We check to see if the preset used the past fourth "Slowest" deinterlaceing and set that to "Slower
-                         * since we no longer have a fourth "Slowest" deinterlacing due to the mcdeint bug */
-                        if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
-                        {
-                            [fPictureController setDeinterlace:3];
-                        }
-                        else
-                        {
-                            
-                            [fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]];
-                        }
-                    }
-                    else
-                    {
-                        [fPictureController setDeinterlace:0];
-                    }
-                    /* VFR */
-                    if ([[chosenPreset objectForKey:@"VFR"] intValue] == 1)
-                    {
-                        [fPictureController setVFR:[[chosenPreset objectForKey:@"VFR"] intValue]];
-                    }
-                    else
-                    {
-                        [fPictureController setVFR:0];
-                    }
-                    /* Detelecine */
-                    if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 1)
-                    {
-                        [fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]];
-                    }
-                    else
-                    {
-                        [fPictureController setDetelecine:0];
-                    }
-                    /* Denoise */
-                    if ([chosenPreset objectForKey:@"PictureDenoise"])
-                    {
-                        [fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]];
-                    }
-                    else
-                    {
-                        [fPictureController setDenoise:0];
-                    }   
-                    /* Deblock */
-                    if ([[chosenPreset objectForKey:@"PictureDeblock"] intValue] == 1)
-                    {
-                        [fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]];
-                    }
-                    else
-                    {
-                        [fPictureController setDeblock:0];
-                    }
-
-                   [self calculatePictureSizing:nil];
-                }
-
             }
-
-
+            
+            
         }
-        /* If the preset has an objectForKey:@"UsesPictureFilters", then we know it is a newer style filters preset
-         * and handle the filters here depending on whether or not the preset specifies applying the filter.
-         */
+        /* If the preset has an objectForKey:@"UsesPictureFilters", and handle the filters here */
         if ([chosenPreset objectForKey:@"UsesPictureFilters"] && [[chosenPreset objectForKey:@"UsesPictureFilters"]  intValue] > 0)
         {
             /* Filters */
-            /* Deinterlace */
-            if ([chosenPreset objectForKey:@"PictureDeinterlace"])
+            
+            /* We only allow *either* Decomb or Deinterlace. So check for the PictureDecombDeinterlace key.
+             * also, older presets may not have this key, in which case we also check to see if that preset had  PictureDecomb
+             * specified, in which case we use decomb and ignore any possible Deinterlace settings as using both was less than
+             * sane.
+             */
+            [fPictureController setUseDecomb:1];
+            [fPictureController setDecomb:0];
+            [fPictureController setDeinterlace:0];
+            if ([[chosenPreset objectForKey:@"PictureDecombDeinterlace"] intValue] == 1 || [[chosenPreset objectForKey:@"PictureDecomb"] intValue] > 0)
             {
-                /* We check to see if the preset used the past fourth "Slowest" deinterlaceing and set that to "Slower
-                 * since we no longer have a fourth "Slowest" deinterlacing due to the mcdeint bug */
-                if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
+                /* we are using decomb */
+                /* Decomb */
+                if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] > 0)
                 {
-                    [fPictureController setDeinterlace:3];
+                    [fPictureController setDecomb:[[chosenPreset objectForKey:@"PictureDecomb"] intValue]];
+                    
+                    /* if we are using "Custom" in the decomb setting, also set the custom string*/
+                    if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] == 2)
+                    {
+                        [fPictureController setDecombCustomString:[chosenPreset objectForKey:@"PictureDecombCustom"]];    
+                    }
                 }
-                else
+             }
+            else
+            {
+                /* We are using Deinterlace */
+                /* Deinterlace */
+                if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] > 0)
                 {
+                    [fPictureController setUseDecomb:0];
                     [fPictureController setDeinterlace:[[chosenPreset objectForKey:@"PictureDeinterlace"] intValue]];
+                    /* if we are using "Custom" in the deinterlace setting, also set the custom string*/
+                    if ([[chosenPreset objectForKey:@"PictureDeinterlace"] intValue] == 4)
+                    {
+                        [fPictureController setDeinterlaceCustomString:[chosenPreset objectForKey:@"PictureDeinterlaceCustom"]];    
+                    }
                 }
             }
-            else
-            {
-                [fPictureController setDeinterlace:0];
-            }
-            /* VFR */
-            if ([[chosenPreset objectForKey:@"VFR"] intValue] == 1)
-            {
-                [fPictureController setVFR:[[chosenPreset objectForKey:@"VFR"] intValue]];
-            }
-            else
-            {
-                [fPictureController setVFR:0];
-            }
+            
+            
             /* Detelecine */
-            if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 1)
+            if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] > 0)
             {
                 [fPictureController setDetelecine:[[chosenPreset objectForKey:@"PictureDetelecine"] intValue]];
+                /* if we are using "Custom" in the detelecine setting, also set the custom string*/
+                if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 2)
+                {
+                    [fPictureController setDetelecineCustomString:[chosenPreset objectForKey:@"PictureDetelecineCustom"]];    
+                }
             }
             else
             {
                 [fPictureController setDetelecine:0];
             }
+            
             /* Denoise */
-            if ([chosenPreset objectForKey:@"PictureDenoise"])
+            if ([[chosenPreset objectForKey:@"PictureDenoise"] intValue] > 0)
             {
                 [fPictureController setDenoise:[[chosenPreset objectForKey:@"PictureDenoise"] intValue]];
+                /* if we are using "Custom" in the denoise setting, also set the custom string*/
+                if ([[chosenPreset objectForKey:@"PictureDenoise"] intValue] == 4)
+                {
+                    [fPictureController setDenoiseCustomString:[chosenPreset objectForKey:@"PictureDenoiseCustom"]];    
+                }
             }
             else
             {
                 [fPictureController setDenoise:0];
             }   
+            
             /* Deblock */
             if ([[chosenPreset objectForKey:@"PictureDeblock"] intValue] == 1)
             {
-                [fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]];
+                /* if its a one, then its the old on/off deblock, set on to 5*/
+                [fPictureController setDeblock:5];
             }
             else
             {
-                [fPictureController setDeblock:0];
+                /* use the settings intValue */
+                [fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]];
             }
-            /* Decomb */
-            /* Even though we currently allow for a custom setting for decomb, ultimately it will only have Off and
-             * Default so we just pay attention to anything greater than 0 as 1 (Default). 0 is Off. */
-            if ([[chosenPreset objectForKey:@"PictureDecomb"] intValue] > 0)
+            
+            if ([[chosenPreset objectForKey:@"VideoGrayScale"] intValue] == 1)
             {
-                [fPictureController setDecomb:1];
+                [fPictureController setGrayscale:1];
             }
             else
             {
-                [fPictureController setDecomb:0];
+                [fPictureController setGrayscale:0];
             }
         }
+        /* we call SetTitle: in fPictureController so we get an instant update in the Picture Settings window */
+        [fPictureController SetTitle:fTitle];
+        [fPictureController SetTitle:fTitle];
         [self calculatePictureSizing:nil];
     }
 }
@@ -5451,6 +6612,46 @@ if (item == nil)
                [self addFactoryPresets:nil];
        }
        [fPresetsOutlineView reloadData];
+    
+    [self checkBuiltInsForUpdates];
+}
+
+- (void) checkBuiltInsForUpdates {
+    
+       BOOL updateBuiltInPresets = NO;
+    int i = 0;
+    NSEnumerator *enumerator = [UserPresets objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
+    {
+        /* iterate through the built in presets to see if any have an old build number */
+        NSMutableDictionary *thisPresetDict = tempObject;
+        /*Key Type == 0 is built in, and key PresetBuildNumber is the build number it was created with */
+        if ([[thisPresetDict objectForKey:@"Type"] intValue] == 0)             
+        {
+                       if (![thisPresetDict objectForKey:@"PresetBuildNumber"] || [[thisPresetDict objectForKey:@"PresetBuildNumber"] intValue] < [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue])
+            {
+                updateBuiltInPresets = YES;
+            }  
+               }
+        i++;
+    }
+    /* if we have built in presets to update, then do so AlertBuiltInPresetUpdate*/
+    if ( updateBuiltInPresets == YES)
+    {
+        if( [[NSUserDefaults standardUserDefaults] boolForKey:@"AlertBuiltInPresetUpdate"] == YES)
+        {
+            /* Show an alert window that built in presets will be updated */
+            /*On Screen Notification*/
+            int status;
+            NSBeep();
+            status = NSRunAlertPanel(@"HandBrake has determined your built in presets are out of date...",@"HandBrake will now update your built-in presets.", @"OK", nil, nil);
+            [NSApp requestUserAttention:NSCriticalRequest];
+        }
+        /* when alert is dismissed, go ahead and update the built in presets */
+        [self addFactoryPresets:nil];
+    }
+    
 }
 
 
@@ -5467,6 +6668,8 @@ if (item == nil)
     [fPresetNewPicSettingsPopUp selectItemAtIndex: 0]; 
     /* Uncheck the preset use filters checkbox */
     [fPresetNewPicFiltersCheck setState:NSOffState];
+    // fPresetNewFolderCheck
+    [fPresetNewFolderCheck setState:NSOffState];
     /* Erase info from the input fields*/
        [fPresetNewName setStringValue: @""];
        [fPresetNewDesc setStringValue: @""];
@@ -5536,132 +6739,171 @@ if (item == nil)
 - (NSDictionary *)createPreset
 {
     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
+    /* Preset build number */
+    [preset setObject:[NSString stringWithFormat: @"%d", [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
+    [preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
        /* Get the New Preset Name from the field in the AddPresetPanel */
     [preset setObject:[fPresetNewName stringValue] forKey:@"PresetName"];
+    /* Set whether or not this is to be a folder fPresetNewFolderCheck*/
+    [preset setObject:[NSNumber numberWithBool:[fPresetNewFolderCheck state]] forKey:@"Folder"];
        /*Set whether or not this is a user preset or factory 0 is factory, 1 is user*/
        [preset setObject:[NSNumber numberWithInt:1] forKey:@"Type"];
        /*Set whether or not this is default, at creation set to 0*/
        [preset setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
-       /*Get the whether or not to apply pic Size and Cropping (includes Anamorphic)*/
-       [preset setObject:[NSNumber numberWithInt:[fPresetNewPicSettingsPopUp indexOfSelectedItem]] forKey:@"UsesPictureSettings"];
-    /* Get whether or not to use the current Picture Filter settings for the preset */
-    [preset setObject:[NSNumber numberWithInt:[fPresetNewPicFiltersCheck state]] forKey:@"UsesPictureFilters"];
-    /* Get New Preset Description from the field in the AddPresetPanel*/
-       [preset setObject:[fPresetNewDesc stringValue] forKey:@"PresetDescription"];
-       /* File Format */
-    [preset setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
-       /* Chapter Markers fCreateChapterMarkers*/
-       [preset setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
-       /* Allow Mpeg4 64 bit formatting +4GB file sizes */
-       [preset setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
-    /* Mux mp4 with http optimization */
-    [preset setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
-    /* Add iPod uuid atom */
-    [preset setObject:[NSNumber numberWithInt:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
-
-    /* Codecs */
-       /* Video encoder */
-       [preset setObject:[fVidEncoderPopUp titleOfSelectedItem] forKey:@"VideoEncoder"];
-       /* x264 Option String */
-       [preset setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
-
-       [preset setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
-       [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
-       [preset setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
-       [preset setObject:[NSNumber numberWithFloat:[fVidQualitySlider floatValue]] forKey:@"VideoQualitySlider"];
-
-       /* Video framerate */
-    if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source is selected
-       {
-        [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
-    }
-    else // we can record the actual titleOfSelectedItem
-    {
-    [preset setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
-    }
-       /* GrayScale */
-       [preset setObject:[NSNumber numberWithInt:[fVidGrayscaleCheck state]] forKey:@"VideoGrayScale"];
-       /* 2 Pass Encoding */
-       [preset setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
-       /* Turbo 2 pass Encoding fVidTurboPassCheck*/
-       [preset setObject:[NSNumber numberWithInt:[fVidTurboPassCheck state]] forKey:@"VideoTurboTwoPass"];
-       /*Picture Settings*/
-       hb_job_t * job = fTitle->job;
-       /* Picture Sizing */
-       /* Use Max Picture settings for whatever the dvd is.*/
-       [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
-       [preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
-       [preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
-       [preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
-       [preset setObject:[NSNumber numberWithInt:fTitle->job->pixel_ratio] forKey:@"PicturePAR"];
-    
-    /* Set crop settings here */
-       [preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
-    [preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
-    [preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
-       [preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
-       [preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
-    
-    /* Picture Filters */
-    [preset setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
-       [preset setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
-    [preset setObject:[NSNumber numberWithInt:[fPictureController vfr]] forKey:@"VFR"];
-       [preset setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
-    [preset setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"]; 
-    [preset setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
-    
-    
-    /*Audio*/
-    if ([fAudLang1PopUp indexOfSelectedItem] > 0)
-    {
-        [preset setObject:[NSNumber numberWithInt:[fAudLang1PopUp indexOfSelectedItem]] forKey:@"Audio1Track"];
-        [preset setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"Audio1TrackDescription"];
-        [preset setObject:[fAudTrack1CodecPopUp titleOfSelectedItem] forKey:@"Audio1Encoder"];
-        [preset setObject:[fAudTrack1MixPopUp titleOfSelectedItem] forKey:@"Audio1Mixdown"];
-        [preset setObject:[fAudTrack1RatePopUp titleOfSelectedItem] forKey:@"Audio1Samplerate"];
-        [preset setObject:[fAudTrack1BitratePopUp titleOfSelectedItem] forKey:@"Audio1Bitrate"];
-        [preset setObject:[NSNumber numberWithFloat:[fAudTrack1DrcSlider floatValue]] forKey:@"Audio1TrackDRCSlider"];
-    }
-    if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+    if ([fPresetNewFolderCheck state] == YES)
     {
-        [preset setObject:[NSNumber numberWithInt:[fAudLang2PopUp indexOfSelectedItem]] forKey:@"Audio2Track"];
-        [preset setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"Audio2TrackDescription"];
-        [preset setObject:[fAudTrack2CodecPopUp titleOfSelectedItem] forKey:@"Audio2Encoder"];
-        [preset setObject:[fAudTrack2MixPopUp titleOfSelectedItem] forKey:@"Audio2Mixdown"];
-        [preset setObject:[fAudTrack2RatePopUp titleOfSelectedItem] forKey:@"Audio2Samplerate"];
-        [preset setObject:[fAudTrack2BitratePopUp titleOfSelectedItem] forKey:@"Audio2Bitrate"];
-        [preset setObject:[NSNumber numberWithFloat:[fAudTrack2DrcSlider floatValue]] forKey:@"Audio2TrackDRCSlider"];
+        /* initialize and set an empty array for children here since we are a new folder */
+        NSMutableArray *childrenArray = [[NSMutableArray alloc] init];
+        [preset setObject:[NSMutableArray arrayWithArray: childrenArray] forKey:@"ChildrenArray"];
+        [childrenArray autorelease];
     }
-    if ([fAudLang3PopUp indexOfSelectedItem] > 0)
-    {
-        [preset setObject:[NSNumber numberWithInt:[fAudLang3PopUp indexOfSelectedItem]] forKey:@"Audio3Track"];
-        [preset setObject:[fAudLang3PopUp titleOfSelectedItem] forKey:@"Audio3TrackDescription"];
-        [preset setObject:[fAudTrack3CodecPopUp titleOfSelectedItem] forKey:@"Audio3Encoder"];
-        [preset setObject:[fAudTrack3MixPopUp titleOfSelectedItem] forKey:@"Audio3Mixdown"];
-        [preset setObject:[fAudTrack3RatePopUp titleOfSelectedItem] forKey:@"Audio3Samplerate"];
-        [preset setObject:[fAudTrack3BitratePopUp titleOfSelectedItem] forKey:@"Audio3Bitrate"];
-        [preset setObject:[NSNumber numberWithFloat:[fAudTrack3DrcSlider floatValue]] forKey:@"Audio3TrackDRCSlider"];
-    }
-    if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+    else // we are not creating a preset folder, so we go ahead with the rest of the preset info
     {
-        [preset setObject:[NSNumber numberWithInt:[fAudLang4PopUp indexOfSelectedItem]] forKey:@"Audio4Track"];
-        [preset setObject:[fAudLang4PopUp titleOfSelectedItem] forKey:@"Audio4TrackDescription"];
-        [preset setObject:[fAudTrack4CodecPopUp titleOfSelectedItem] forKey:@"Audio4Encoder"];
-        [preset setObject:[fAudTrack4MixPopUp titleOfSelectedItem] forKey:@"Audio4Mixdown"];
-        [preset setObject:[fAudTrack4RatePopUp titleOfSelectedItem] forKey:@"Audio4Samplerate"];
-        [preset setObject:[fAudTrack4BitratePopUp titleOfSelectedItem] forKey:@"Audio4Bitrate"];
-        [preset setObject:[NSNumber numberWithFloat:[fAudTrack4DrcSlider floatValue]] forKey:@"Audio4TrackDRCSlider"];
+        /*Get the whether or not to apply pic Size and Cropping (includes Anamorphic)*/
+        [preset setObject:[NSNumber numberWithInt:[fPresetNewPicSettingsPopUp indexOfSelectedItem]] forKey:@"UsesPictureSettings"];
+        /* Get whether or not to use the current Picture Filter settings for the preset */
+        [preset setObject:[NSNumber numberWithInt:[fPresetNewPicFiltersCheck state]] forKey:@"UsesPictureFilters"];
+        
+        /* Get New Preset Description from the field in the AddPresetPanel*/
+        [preset setObject:[fPresetNewDesc stringValue] forKey:@"PresetDescription"];
+        /* File Format */
+        [preset setObject:[fDstFormatPopUp titleOfSelectedItem] forKey:@"FileFormat"];
+        /* Chapter Markers fCreateChapterMarkers*/
+        [preset setObject:[NSNumber numberWithInt:[fCreateChapterMarkers state]] forKey:@"ChapterMarkers"];
+        /* Allow Mpeg4 64 bit formatting +4GB file sizes */
+        [preset setObject:[NSNumber numberWithInt:[fDstMp4LargeFileCheck state]] forKey:@"Mp4LargeFile"];
+        /* Mux mp4 with http optimization */
+        [preset setObject:[NSNumber numberWithInt:[fDstMp4HttpOptFileCheck state]] forKey:@"Mp4HttpOptimize"];
+        /* Add iPod uuid atom */
+        [preset setObject:[NSNumber numberWithInt:[fDstMp4iPodFileCheck state]] forKey:@"Mp4iPodCompatible"];
+        
+        /* Codecs */
+        /* Video encoder */
+        [preset setObject:[fVidEncoderPopUp titleOfSelectedItem] forKey:@"VideoEncoder"];
+        /* x264 Option String */
+        [preset setObject:[fAdvancedOptions optionsString] forKey:@"x264Option"];
+        
+        [preset setObject:[NSNumber numberWithInt:[fVidQualityMatrix selectedRow]] forKey:@"VideoQualityType"];
+        [preset setObject:[fVidTargetSizeField stringValue] forKey:@"VideoTargetSize"];
+        [preset setObject:[fVidBitrateField stringValue] forKey:@"VideoAvgBitrate"];
+        [preset setObject:[NSNumber numberWithFloat:[fVidQualityRFField floatValue]] forKey:@"VideoQualitySlider"];
+        
+        /* Video framerate */
+        if ([fVidRatePopUp indexOfSelectedItem] == 0) // Same as source is selected
+        {
+            [preset setObject:@"Same as source" forKey:@"VideoFramerate"];
+        }
+        else // we can record the actual titleOfSelectedItem
+        {
+            [preset setObject:[fVidRatePopUp titleOfSelectedItem] forKey:@"VideoFramerate"];
+        }
+        
+        /* 2 Pass Encoding */
+        [preset setObject:[NSNumber numberWithInt:[fVidTwoPassCheck state]] forKey:@"VideoTwoPass"];
+        /* Turbo 2 pass Encoding fVidTurboPassCheck*/
+        [preset setObject:[NSNumber numberWithInt:[fVidTurboPassCheck state]] forKey:@"VideoTurboTwoPass"];
+        /*Picture Settings*/
+        hb_job_t * job = fTitle->job;
+        /* Picture Sizing */
+        /* Use Max Picture settings for whatever the dvd is.*/
+        [preset setObject:[NSNumber numberWithInt:0] forKey:@"UsesMaxPictureSettings"];
+        [preset setObject:[NSNumber numberWithInt:fTitle->job->width] forKey:@"PictureWidth"];
+        [preset setObject:[NSNumber numberWithInt:fTitle->job->height] forKey:@"PictureHeight"];
+        [preset setObject:[NSNumber numberWithInt:fTitle->job->keep_ratio] forKey:@"PictureKeepRatio"];
+        [preset setObject:[NSNumber numberWithInt:fTitle->job->anamorphic.mode] forKey:@"PicturePAR"];
+        
+        /* Set crop settings here */
+        [preset setObject:[NSNumber numberWithInt:[fPictureController autoCrop]] forKey:@"PictureAutoCrop"];
+        [preset setObject:[NSNumber numberWithInt:job->crop[0]] forKey:@"PictureTopCrop"];
+        [preset setObject:[NSNumber numberWithInt:job->crop[1]] forKey:@"PictureBottomCrop"];
+        [preset setObject:[NSNumber numberWithInt:job->crop[2]] forKey:@"PictureLeftCrop"];
+        [preset setObject:[NSNumber numberWithInt:job->crop[3]] forKey:@"PictureRightCrop"];
+        
+        /* Picture Filters */
+        [preset setObject:[NSNumber numberWithInt:[fPictureController useDecomb]] forKey:@"PictureDecombDeinterlace"];
+        [preset setObject:[NSNumber numberWithInt:[fPictureController deinterlace]] forKey:@"PictureDeinterlace"];
+        [preset setObject:[fPictureController deinterlaceCustomString] forKey:@"PictureDeinterlaceCustom"];
+        [preset setObject:[NSNumber numberWithInt:[fPictureController detelecine]] forKey:@"PictureDetelecine"];
+        [preset setObject:[fPictureController detelecineCustomString] forKey:@"PictureDetelecineCustom"];
+        [preset setObject:[NSNumber numberWithInt:[fPictureController denoise]] forKey:@"PictureDenoise"];
+        [preset setObject:[fPictureController denoiseCustomString] forKey:@"PictureDenoiseCustom"];
+        [preset setObject:[NSNumber numberWithInt:[fPictureController deblock]] forKey:@"PictureDeblock"]; 
+        [preset setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
+        [preset setObject:[fPictureController decombCustomString] forKey:@"PictureDecombCustom"];
+        [preset setObject:[NSNumber numberWithInt:[fPictureController grayscale]] forKey:@"VideoGrayScale"];
+        
+        /*Audio*/
+        NSMutableArray *audioListArray = [[NSMutableArray alloc] init];
+        /* we actually call the methods for the nests here */
+        if ([fAudLang1PopUp indexOfSelectedItem] > 0)
+        {
+            NSMutableDictionary *audioTrack1Array = [[NSMutableDictionary alloc] init];
+            [audioTrack1Array setObject:[NSNumber numberWithInt:[fAudLang1PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+            [audioTrack1Array setObject:[fAudLang1PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+            [audioTrack1Array setObject:[fAudTrack1CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+            [audioTrack1Array setObject:[fAudTrack1MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+            [audioTrack1Array setObject:[fAudTrack1RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+            [audioTrack1Array setObject:[fAudTrack1BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+            [audioTrack1Array setObject:[NSNumber numberWithFloat:[fAudTrack1DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+            [audioTrack1Array autorelease];
+            [audioListArray addObject:audioTrack1Array];
+        }
+        
+        if ([fAudLang2PopUp indexOfSelectedItem] > 0)
+        {
+            NSMutableDictionary *audioTrack2Array = [[NSMutableDictionary alloc] init];
+            [audioTrack2Array setObject:[NSNumber numberWithInt:[fAudLang2PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+            [audioTrack2Array setObject:[fAudLang2PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+            [audioTrack2Array setObject:[fAudTrack2CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+            [audioTrack2Array setObject:[fAudTrack2MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+            [audioTrack2Array setObject:[fAudTrack2RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+            [audioTrack2Array setObject:[fAudTrack2BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+            [audioTrack2Array setObject:[NSNumber numberWithFloat:[fAudTrack2DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+            [audioTrack2Array autorelease];
+            [audioListArray addObject:audioTrack2Array];
+        }
+        
+        if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+        {
+            NSMutableDictionary *audioTrack3Array = [[NSMutableDictionary alloc] init];
+            [audioTrack3Array setObject:[NSNumber numberWithInt:[fAudLang3PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+            [audioTrack3Array setObject:[fAudLang3PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+            [audioTrack3Array setObject:[fAudTrack3CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+            [audioTrack3Array setObject:[fAudTrack3MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+            [audioTrack3Array setObject:[fAudTrack3RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+            [audioTrack3Array setObject:[fAudTrack3BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+            [audioTrack3Array setObject:[NSNumber numberWithFloat:[fAudTrack3DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+            [audioTrack3Array autorelease];
+            [audioListArray addObject:audioTrack3Array];
+        }
+        
+        if ([fAudLang4PopUp indexOfSelectedItem] > 0)
+        {
+            NSMutableDictionary *audioTrack4Array = [[NSMutableDictionary alloc] init];
+            [audioTrack4Array setObject:[NSNumber numberWithInt:[fAudLang4PopUp indexOfSelectedItem]] forKey:@"AudioTrack"];
+            [audioTrack4Array setObject:[fAudLang4PopUp titleOfSelectedItem] forKey:@"AudioTrackDescription"];
+            [audioTrack4Array setObject:[fAudTrack4CodecPopUp titleOfSelectedItem] forKey:@"AudioEncoder"];
+            [audioTrack4Array setObject:[fAudTrack4MixPopUp titleOfSelectedItem] forKey:@"AudioMixdown"];
+            [audioTrack4Array setObject:[fAudTrack4RatePopUp titleOfSelectedItem] forKey:@"AudioSamplerate"];
+            [audioTrack4Array setObject:[fAudTrack4BitratePopUp titleOfSelectedItem] forKey:@"AudioBitrate"];
+            [audioTrack4Array setObject:[NSNumber numberWithFloat:[fAudTrack4DrcSlider floatValue]] forKey:@"AudioTrackDRCSlider"];
+            [audioTrack4Array autorelease];
+            [audioListArray addObject:audioTrack4Array];
+        }
+        
+        
+        [preset setObject:[NSMutableArray arrayWithArray: audioListArray] forKey:@"AudioList"];
+
+        
+        
+        /* Subtitles*/
+        [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
+        /* Forced Subtitles */
+        [preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
     }
-    
-       /* Subtitles*/
-       [preset setObject:[fSubPopUp titleOfSelectedItem] forKey:@"Subtitles"];
-    /* Forced Subtitles */
-       [preset setObject:[NSNumber numberWithInt:[fSubForcedCheck state]] forKey:@"SubtitlesForced"];
-    
     [preset autorelease];
     return preset;
-
+    
 }
 
 - (void)savePreset
@@ -5674,106 +6916,390 @@ if (item == nil)
 
 - (IBAction)deletePreset:(id)sender
 {
-    int status;
-    NSEnumerator *enumerator;
-    NSNumber *index;
-    NSMutableArray *tempArray;
-    id tempObject;
+    
     
     if ( [fPresetsOutlineView numberOfSelectedRows] == 0 )
+    {
         return;
+    }
     /* Alert user before deleting preset */
-       /* Comment out for now, tie to user pref eventually */
-
-    //NSBeep();
+       int status;
     status = NSRunAlertPanel(@"Warning!", @"Are you sure that you want to delete the selected preset?", @"OK", @"Cancel", nil);
     
-    if ( status == NSAlertDefaultReturn ) {
-        enumerator = [fPresetsOutlineView selectedRowEnumerator];
+    if ( status == NSAlertDefaultReturn ) 
+    {
+        int presetToModLevel = [fPresetsOutlineView levelForItem: [fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]]];
+        NSDictionary *presetToMod = [fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]];
+        NSDictionary *presetToModParent = [fPresetsOutlineView parentForItem: presetToMod];
+        
+        NSEnumerator *enumerator;
+        NSMutableArray *presetsArrayToMod;
+        NSMutableArray *tempArray;
+        id tempObject;
+        /* If we are a root level preset, we are modding the UserPresets array */
+        if (presetToModLevel == 0)
+        {
+            presetsArrayToMod = UserPresets;
+        }
+        else // We have a parent preset, so we modify the chidren array object for key
+        {
+            presetsArrayToMod = [presetToModParent objectForKey:@"ChildrenArray"]; 
+        }
+        
+        enumerator = [presetsArrayToMod objectEnumerator];
         tempArray = [NSMutableArray array];
         
-        while ( (index = [enumerator nextObject]) ) {
-            tempObject = [UserPresets objectAtIndex:[index intValue]];
-            [tempArray addObject:tempObject];
+        while (tempObject = [enumerator nextObject]) 
+        {
+            NSDictionary *thisPresetDict = tempObject;
+            if (thisPresetDict == presetToMod)
+            {
+                [tempArray addObject:tempObject];
+            }
         }
         
-        [UserPresets removeObjectsInArray:tempArray];
+        [presetsArrayToMod removeObjectsInArray:tempArray];
         [fPresetsOutlineView reloadData];
         [self savePreset];   
     }
 }
 
+
+#pragma mark -
+#pragma mark Import Export Preset(s)
+
+- (IBAction) browseExportPresetFile: (id) sender
+{
+    /* Open a panel to let the user choose where and how to save the export file */
+    NSSavePanel * panel = [NSSavePanel savePanel];
+       /* We get the current file name and path from the destination field here */
+    NSString *defaultExportDirectory = [NSString stringWithFormat: @"%@/Desktop/", NSHomeDirectory()];
+
+       [panel beginSheetForDirectory: defaultExportDirectory file: @"HB_Export.plist"
+                                  modalForWindow: fWindow modalDelegate: self
+                                  didEndSelector: @selector( browseExportPresetFileDone:returnCode:contextInfo: )
+                                         contextInfo: NULL];
+}
+
+- (void) browseExportPresetFileDone: (NSSavePanel *) sheet
+                   returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    if( returnCode == NSOKButton )
+    {
+        NSString *presetExportDirectory = [[sheet filename] stringByDeletingLastPathComponent];
+        NSString *exportPresetsFile = [sheet filename];
+        [[NSUserDefaults standardUserDefaults] setObject:presetExportDirectory forKey:@"LastPresetExportDirectory"];
+        /* We check for the presets.plist */
+        if ([[NSFileManager defaultManager] fileExistsAtPath:exportPresetsFile] == 0)
+        {
+            [[NSFileManager defaultManager] createFileAtPath:exportPresetsFile contents:nil attributes:nil];
+        }
+        NSMutableArray * presetsToExport = [[NSMutableArray alloc] initWithContentsOfFile:exportPresetsFile];
+        if (nil == presetsToExport)
+        {
+            presetsToExport = [[NSMutableArray alloc] init];
+            
+            /* now get and add selected presets to export */
+            
+        }
+        if ([fPresetsOutlineView selectedRow] >= 0 && [[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Folder"] intValue] != 1)
+        {
+            [presetsToExport addObject:[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]]];
+            [presetsToExport writeToFile:exportPresetsFile atomically:YES];
+            
+        }
+        
+    }
+}
+
+
+- (IBAction) browseImportPresetFile: (id) sender
+{
+
+    NSOpenPanel * panel;
+       
+    panel = [NSOpenPanel openPanel];
+    [panel setAllowsMultipleSelection: NO];
+    [panel setCanChooseFiles: YES];
+    [panel setCanChooseDirectories: NO ];
+    NSString * sourceDirectory;
+       if ([[NSUserDefaults standardUserDefaults] stringForKey:@"LastPresetImportDirectory"])
+       {
+               sourceDirectory = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastPresetImportDirectory"];
+       }
+       else
+       {
+               sourceDirectory = @"~/Desktop";
+               sourceDirectory = [sourceDirectory stringByExpandingTildeInPath];
+       }
+    /* we open up the browse sources sheet here and call for browseSourcesDone after the sheet is closed
+        * to evaluate whether we want to specify a title, we pass the sender in the contextInfo variable
+        */
+    /* set this for allowed file types, not sure if we should allow xml or not */
+    NSArray *fileTypes = [NSArray arrayWithObjects:@"plist", @"xml", nil];
+    [panel beginSheetForDirectory: sourceDirectory file: nil types: fileTypes
+                   modalForWindow: fWindow modalDelegate: self
+                   didEndSelector: @selector( browseImportPresetDone:returnCode:contextInfo: )
+                      contextInfo: sender];
+}
+
+- (void) browseImportPresetDone: (NSSavePanel *) sheet
+                     returnCode: (int) returnCode contextInfo: (void *) contextInfo
+{
+    if( returnCode == NSOKButton )
+    {
+        NSString *importPresetsDirectory = [[sheet filename] stringByDeletingLastPathComponent];
+        NSString *importPresetsFile = [sheet filename];
+        [[NSUserDefaults standardUserDefaults] setObject:importPresetsDirectory forKey:@"LastPresetImportDirectory"];
+        /* NOTE: here we need to do some sanity checking to verify we do not hose up our presets file   */
+        NSMutableArray * presetsToImport = [[NSMutableArray alloc] initWithContentsOfFile:importPresetsFile];
+        /* iterate though the new array of presets to import and add them to our presets array */
+        int i = 0;
+        NSEnumerator *enumerator = [presetsToImport objectEnumerator];
+        id tempObject;
+        while (tempObject = [enumerator nextObject])
+        {
+            /* make any changes to the incoming preset we see fit */
+            /* make sure the incoming preset is not tagged as default */
+            [tempObject setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
+            /* prepend "(imported) to the name of the incoming preset for clarification since it can be changed */
+            NSString * prependedName = [@"(import) " stringByAppendingString:[tempObject objectForKey:@"PresetName"]] ;
+            [tempObject setObject:prependedName forKey:@"PresetName"];
+            
+            /* actually add the new preset to our presets array */
+            [UserPresets addObject:tempObject];
+            i++;
+        }
+        [presetsToImport autorelease];
+        [self sortPresets];
+        [self addPreset];
+        
+    }
+}
+
 #pragma mark -
 #pragma mark Manage Default Preset
 
 - (IBAction)getDefaultPresets:(id)sender
 {
-       int i = 0;
+       presetHbDefault = nil;
+    presetUserDefault = nil;
+    presetUserDefaultParent = nil;
+    presetUserDefaultParentParent = nil;
+    NSMutableDictionary *presetHbDefaultParent = nil;
+    NSMutableDictionary *presetHbDefaultParentParent = nil;
+    
+    int i = 0;
+    BOOL userDefaultFound = NO;
     presetCurrentBuiltInCount = 0;
+    /* First we iterate through the root UserPresets array to check for defaults */
     NSEnumerator *enumerator = [UserPresets objectEnumerator];
        id tempObject;
        while (tempObject = [enumerator nextObject])
        {
-               NSDictionary *thisPresetDict = tempObject;
+               NSMutableDictionary *thisPresetDict = tempObject;
                if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default
                {
-                       presetHbDefault = i;    
+                       presetHbDefault = thisPresetDict;       
                }
                if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default
                {
-                       presetUserDefault = i;  
-               }
+                       presetUserDefault = thisPresetDict;
+            userDefaultFound = YES;
+        }
         if ([[thisPresetDict objectForKey:@"Type"] intValue] == 0) // Type 0 is a built in preset              
         {
                        presetCurrentBuiltInCount++; // <--increment the current number of built in presets     
                }
                i++;
+        
+        /* if we run into a folder, go to level 1 and iterate through the children arrays for the default */
+        if ([thisPresetDict objectForKey:@"ChildrenArray"])
+        {
+            NSMutableDictionary *thisPresetDictParent = thisPresetDict;
+            NSEnumerator *enumerator = [[thisPresetDict objectForKey:@"ChildrenArray"] objectEnumerator];
+            id tempObject;
+            while (tempObject = [enumerator nextObject])
+            {
+                NSMutableDictionary *thisPresetDict = tempObject;
+                if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default
+                {
+                    presetHbDefault = thisPresetDict;
+                    presetHbDefaultParent = thisPresetDictParent;
+                }
+                if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default
+                {
+                    presetUserDefault = thisPresetDict;
+                    presetUserDefaultParent = thisPresetDictParent;
+                    userDefaultFound = YES;
+                }
+                
+                /* if we run into a folder, go to level 2 and iterate through the children arrays for the default */
+                if ([thisPresetDict objectForKey:@"ChildrenArray"])
+                {
+                    NSMutableDictionary *thisPresetDictParentParent = thisPresetDict;
+                    NSEnumerator *enumerator = [[thisPresetDict objectForKey:@"ChildrenArray"] objectEnumerator];
+                    id tempObject;
+                    while (tempObject = [enumerator nextObject])
+                    {
+                        NSMutableDictionary *thisPresetDict = tempObject;
+                        if ([[thisPresetDict objectForKey:@"Default"] intValue] == 1) // 1 is HB default
+                        {
+                            presetHbDefault = thisPresetDict;
+                            presetHbDefaultParent = thisPresetDictParent;
+                            presetHbDefaultParentParent = thisPresetDictParentParent;  
+                        }
+                        if ([[thisPresetDict objectForKey:@"Default"] intValue] == 2) // 2 is User specified default
+                        {
+                            presetUserDefault = thisPresetDict;
+                            presetUserDefaultParent = thisPresetDictParent;
+                            presetUserDefaultParentParent = thisPresetDictParentParent;
+                            userDefaultFound = YES;    
+                        }
+                        
+                    }
+                }
+            }
+        }
+        
        }
+    /* check to see if a user specified preset was found, if not then assign the parents for
+     * the presetHbDefault so that we can open the parents for the nested presets
+     */
+    if (userDefaultFound == NO)
+    {
+        presetUserDefaultParent = presetHbDefaultParent;
+        presetUserDefaultParentParent = presetHbDefaultParentParent;
+    }
 }
 
 - (IBAction)setDefaultPreset:(id)sender
 {
+/* We need to determine if the item is a folder */
+   if ([[[fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]] objectForKey:@"Folder"] intValue] == 1)
+   {
+   return;
+   }
+
     int i = 0;
     NSEnumerator *enumerator = [UserPresets objectEnumerator];
        id tempObject;
        /* First make sure the old user specified default preset is removed */
-       while (tempObject = [enumerator nextObject])
+    while (tempObject = [enumerator nextObject])
        {
-               /* make sure we are not removing the default HB preset */
-               if ([[[UserPresets objectAtIndex:i] objectForKey:@"Default"] intValue] != 1) // 1 is HB default
+               NSMutableDictionary *thisPresetDict = tempObject;
+               if ([[tempObject objectForKey:@"Default"] intValue] != 1) // if not the default HB Preset, set to 0
                {
-                       [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Default"];
+                       [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:0] forKey:@"Default"]; 
                }
-               i++;
-       }
-       /* Second, go ahead and set the appropriate user specfied preset */
-       /* we get the chosen preset from the UserPresets array */
-       if ([[[UserPresets objectAtIndex:[fPresetsOutlineView selectedRow]] objectForKey:@"Default"] intValue] != 1) // 1 is HB default
-       {
-               [[UserPresets objectAtIndex:[fPresetsOutlineView selectedRow]] setObject:[NSNumber numberWithInt:2] forKey:@"Default"];
+               
+               /* if we run into a folder, go to level 1 and iterate through the children arrays for the default */
+        if ([thisPresetDict objectForKey:@"ChildrenArray"])
+        {
+            NSEnumerator *enumerator = [[thisPresetDict objectForKey:@"ChildrenArray"] objectEnumerator];
+            id tempObject;
+            int ii = 0;
+            while (tempObject = [enumerator nextObject])
+            {
+                NSMutableDictionary *thisPresetDict1 = tempObject;
+                if ([[tempObject objectForKey:@"Default"] intValue] != 1) // if not the default HB Preset, set to 0
+                {
+                    [[[thisPresetDict objectForKey:@"ChildrenArray"] objectAtIndex:ii] setObject:[NSNumber numberWithInt:0] forKey:@"Default"];        
+                }
+                /* if we run into a folder, go to level 2 and iterate through the children arrays for the default */
+                if ([thisPresetDict1 objectForKey:@"ChildrenArray"])
+                {
+                    NSEnumerator *enumerator = [[thisPresetDict1 objectForKey:@"ChildrenArray"] objectEnumerator];
+                    id tempObject;
+                    int iii = 0;
+                    while (tempObject = [enumerator nextObject])
+                    {
+                        if ([[tempObject objectForKey:@"Default"] intValue] != 1) // if not the default HB Preset, set to 0
+                        {
+                            [[[thisPresetDict1 objectForKey:@"ChildrenArray"] objectAtIndex:iii] setObject:[NSNumber numberWithInt:0] forKey:@"Default"];      
+                        }
+                        iii++;
+                    }
+                }
+                ii++;
+            }
+            
+        }
+        i++; 
        }
-       /*FIX ME: I think we now need to use the items not rows in NSOutlineView */
-    presetUserDefault = [fPresetsOutlineView selectedRow];
-       
-       /* We save all of the preset data here */
+    
+    
+    int presetToModLevel = [fPresetsOutlineView levelForItem: [fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]]];
+    NSDictionary *presetToMod = [fPresetsOutlineView itemAtRow:[fPresetsOutlineView selectedRow]];
+    NSDictionary *presetToModParent = [fPresetsOutlineView parentForItem: presetToMod];
+    
+    
+    NSMutableArray *presetsArrayToMod;
+    NSMutableArray *tempArray;
+    
+    /* If we are a root level preset, we are modding the UserPresets array */
+    if (presetToModLevel == 0)
+    {
+        presetsArrayToMod = UserPresets;
+    }
+    else // We have a parent preset, so we modify the chidren array object for key
+    {
+        presetsArrayToMod = [presetToModParent objectForKey:@"ChildrenArray"]; 
+    }
+    
+    enumerator = [presetsArrayToMod objectEnumerator];
+    tempArray = [NSMutableArray array];
+    int iiii = 0;
+    while (tempObject = [enumerator nextObject]) 
+    {
+        NSDictionary *thisPresetDict = tempObject;
+        if (thisPresetDict == presetToMod)
+        {
+            if ([[tempObject objectForKey:@"Default"] intValue] != 1) // if not the default HB Preset, set to 2
+            {
+                [[presetsArrayToMod objectAtIndex:iiii] setObject:[NSNumber numberWithInt:2] forKey:@"Default"];       
+            }
+        }
+     iiii++;
+     }
+    
+    
+    /* We save all of the preset data here */
     [self savePreset];
-       /* We Reload the New Table data for presets */
+    /* We Reload the New Table data for presets */
     [fPresetsOutlineView reloadData];
 }
 
 - (IBAction)selectDefaultPreset:(id)sender
 {
-       /* if there is a user specified default, we use it */
+       NSMutableDictionary *presetToMod;
+    /* if there is a user specified default, we use it */
        if (presetUserDefault)
        {
-       [fPresetsOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetUserDefault] byExtendingSelection:NO];
-       [self selectPreset:nil];
-       }
+        presetToMod = presetUserDefault;
+    }
        else if (presetHbDefault) //else we use the built in default presetHbDefault
        {
-       [fPresetsOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:presetHbDefault] byExtendingSelection:NO];
-       [self selectPreset:nil];
+        presetToMod = presetHbDefault;
        }
+    else
+    {
+    return;
+    }
+    
+    if (presetUserDefaultParent != nil)
+    {
+        [fPresetsOutlineView expandItem:presetUserDefaultParent];
+        
+    }
+    if (presetUserDefaultParentParent != nil)
+    {
+        [fPresetsOutlineView expandItem:presetUserDefaultParentParent];
+        
+    }
+    
+    [fPresetsOutlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[fPresetsOutlineView rowForItem: presetToMod]] byExtendingSelection:NO];
+       [self selectPreset:nil];
 }
 
 
@@ -5809,25 +7335,39 @@ if (item == nil)
 
 }
 
-   /* We use this method to recreate new, updated factory
-   presets */
+   /* We use this method to recreate new, updated factory presets */
 - (IBAction)addFactoryPresets:(id)sender
 {
-   
-   /* First, we delete any existing built in presets */
+    
+    /* First, we delete any existing built in presets */
     [self deleteFactoryPresets: sender];
     /* Then we generate new built in presets programmatically with fPresetsBuiltin
-    * which is all setup in HBPresets.h and  HBPresets.m*/
+     * which is all setup in HBPresets.h and  HBPresets.m*/
     [fPresetsBuiltin generateBuiltinPresets:UserPresets];
+    /* update build number for built in presets */
+    /* iterate though the new array of presets to import and add them to our presets array */
+    int i = 0;
+    NSEnumerator *enumerator = [UserPresets objectEnumerator];
+    id tempObject;
+    while (tempObject = [enumerator nextObject])
+    {
+        /* Record the apps current build number in the PresetBuildNumber key */
+        if ([[tempObject objectForKey:@"Type"] intValue] == 0) // Type 0 is a built in preset          
+        {
+            /* Preset build number */
+            [[UserPresets objectAtIndex:i] setObject:[NSNumber numberWithInt:[[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]] forKey:@"PresetBuildNumber"];
+        }
+        i++;
+    }
+    /* report the built in preset updating to the activity log */
+    [self writeToActivityLog: "built in presets updated to build number: %d", [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] intValue]];
+    
     [self sortPresets];
     [self addPreset];
     
 }
 
 
-
-
-
 @end
 
 /*******************************
@@ -5841,7 +7381,7 @@ if (item == nil)
 
     // By default, NSTableView only drags an image of the first column. Change this to
     // drag an image of the queue's icon and PresetName columns.
-    NSArray * cols = [NSArray arrayWithObjects: [self tableColumnWithIdentifier:@"icon"], [self tableColumnWithIdentifier:@"PresetName"], nil];
+    NSArray * cols = [NSArray arrayWithObjects: [self tableColumnWithIdentifier:@"PresetName"], nil];
     return [super dragImageForRowsWithIndexes:dragRows tableColumns:cols event:dragEvent offset:dragImageOffset];
 }