OSDN Git Service

MacGui: Acivity Logs for individual encodes initial implementation
[handbrake-jp/handbrake-jp-git.git] / macosx / Controller.mm
index 1984390..5901249 100644 (file)
@@ -73,9 +73,10 @@ 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);
     /* 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];
@@ -114,26 +115,48 @@ 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;
+        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));
+                                  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];
-   }
+        
+        /* Show Browse Sources Window ASAP */
+        [self performSelectorOnMainThread:@selector(browseSources:)
+                               withObject:nil waitUntilDone:NO];
+    }
 }
 
 - (void) didDimissReloadQueue: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
@@ -141,28 +164,32 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
     if (returnCode == NSAlertOtherReturn)
     {
         [self clearQueueAllItems];
-    }
-    
-    [self performSelectorOnMainThread:@selector(browseSources:)
+        [self performSelectorOnMainThread:@selector(browseSources:)
                            withObject:nil waitUntilDone:NO];
+    }
+    else
+    {
+    [self setQueueEncodingItemsAsPending];
+    [self showQueueWindow:NULL];
+    }
 }
 
 - (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication *) app
 {
+    
     // Warn if encoding a movie
     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 +197,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;
@@ -598,6 +625,12 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             [fStatusField setStringValue: [NSString stringWithFormat:
                                            NSLocalizedString( @"Queue Scanning title %d of %d...", @"" ),
                                            p.title_cur, 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]];
+            
             [fRipIndicator setHidden: NO];
             [fRipIndicator setDoubleValue: 100.0 * ( p.title_cur - 1 ) / p.title_count];
             break;
@@ -634,7 +667,8 @@ 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;
             [fRipIndicator setIndeterminate: NO];
@@ -653,9 +687,7 @@ 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 */
@@ -670,7 +702,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 +717,7 @@ static NSString *        ChooseSourceIdentifier             = @"Choose Source It
             
         case HB_STATE_PAUSED:
                    [fStatusField setStringValue: NSLocalizedString( @"Paused", @"" )];
+            [fQueueController setQueueStatusString: NSLocalizedString( @"Paused", @"" )];
             
                        break;
             
@@ -694,7 +728,9 @@ 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 setDoubleValue: 0.0];
             [[fWindow toolbar] validateVisibleItems];
@@ -712,44 +748,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];
+                    }
+                    
                 }
                 
                 
@@ -1050,7 +1108,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 +1129,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, @"\")"]];
@@ -1536,8 +1594,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 +1672,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 +1711,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 +1726,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 +1743,6 @@ fWorkingCount = 0;
     
     [QueueFileArray removeObjectsInArray:tempArray];
     [self saveQueueFileItem];
-    
 }
 
 /* This method will duplicate prepareJob however into the
@@ -1662,10 +1756,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
@@ -1692,7 +1784,26 @@ fWorkingCount = 0;
     [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 */
+       
+    /* 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 stringWithFormat:@"%s",chapter->title]];
+        }
+    }
+    [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"];
@@ -1742,9 +1853,8 @@ fWorkingCount = 0;
     /* 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 denoise]] forKey:@"PictureDenoise"];
+    [queueFileJob setObject:[NSString stringWithFormat:@"%d",[fPictureController deblock]] forKey:@"PictureDeblock"]; 
     [queueFileJob setObject:[NSNumber numberWithInt:[fPictureController decomb]] forKey:@"PictureDecomb"];
     
     /*Audio*/
@@ -1805,30 +1915,17 @@ 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"];
@@ -1960,8 +2057,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
@@ -2279,8 +2378,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 */
@@ -2344,12 +2442,11 @@ fWorkingCount = 0;
     }
     
     NSMutableDictionary * queueToApply = [QueueFileArray objectAtIndex:currentQueueEncodeIndex];
-    [self writeToActivityLog: "processNewQueueEncode currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
+    //[self writeToActivityLog: "processNewQueueEncode currentQueueEncodeIndex is: %d", currentQueueEncodeIndex];
     [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 writeToActivityLog: "processNewQueueEncode sending to prepareJob"];
     [self prepareJob];
-    [self writeToActivityLog: "processNewQueueEncode back from prepareJob"];
     if( [[queueToApply objectForKey:@"SubtitlesForced"] intValue] == 1 )
         job->subtitle_force = 1;
     else
@@ -2446,7 +2543,6 @@ fWorkingCount = 0;
     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;
-    [self writeToActivityLog: "prepareJob reached"];
     /* Chapter selection */
     job->chapter_start = [[queueToApply objectForKey:@"JobChapterStart"] intValue];
     job->chapter_end   = [[queueToApply objectForKey:@"JobChapterEnd"] intValue];
@@ -2479,6 +2575,7 @@ fWorkingCount = 0;
     {
         job->mp4_optimize = 0;
     }
+    
     //}
        
     /* We set the chapter marker extraction here based on the format being
@@ -2486,13 +2583,39 @@ fWorkingCount = 0;
     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)
@@ -2531,7 +2654,6 @@ fWorkingCount = 0;
     }
     
     
-    [self writeToActivityLog: "prepareJob reached Picture Settings"];
     /* Picture Size Settings */
     job->width = [[queueToApply objectForKey:@"PictureWidth"]  intValue];
     job->height = [[queueToApply objectForKey:@"PictureHeight"]  intValue];
@@ -2546,11 +2668,16 @@ fWorkingCount = 0;
     job->crop[2] = [[queueToApply objectForKey:@"PictureLeftCrop"]  intValue];
     job->crop[3] = [[queueToApply objectForKey:@"PictureRightCrop"]  intValue];
     
-    [self writeToActivityLog: "prepareJob reached Frame Rate"];
-    
     /* 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 
@@ -2560,21 +2687,25 @@ fWorkingCount = 0;
     }
     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;
+        }
     }
-    [self writeToActivityLog: "prepareJob reached Bitrate Video Quality"];
-    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 0 )
+    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] != 2 )
     {
         /* Target size.
          Bitrate should already have been calculated and displayed
-         in fVidBitrateField, so let's just use it */
-    }
-    if ( [[queueToApply objectForKey:@"VideoQualityType"] intValue] == 1 )
-    {
+         in fVidBitrateField, so let's just use it same as abr*/
         job->vquality = -1.0;
         job->vbitrate = [[queueToApply objectForKey:@"VideoAvgBitrate"] intValue];
     }
@@ -2589,7 +2720,6 @@ fWorkingCount = 0;
     /* Subtitle settings */
     job->subtitle = [[queueToApply objectForKey:@"JobSubtitlesIndex"] intValue] - 2;
     
-    [self writeToActivityLog: "prepareJob reached Audio"];
     /* 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);
@@ -2662,24 +2792,13 @@ 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;
-    }
-    
-   [self writeToActivityLog: "prepareJob reached Filters"];
-     /* Filters */ 
+    /* Filters */ 
     job->filters = hb_list_init();
     
     /* Now lets call the filters if applicable.
@@ -2737,8 +2856,13 @@ fWorkingCount = 0;
        }
     
     /* 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"];    
@@ -2809,8 +2933,11 @@ fWorkingCount = 0;
         return;
     }
     
-    // If there are pending 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 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 pending item */
@@ -2969,8 +3096,8 @@ fWorkingCount = 0;
 {
     if (!fQueueController) return;
     
-  
-    NSString * alertTitle = [NSString stringWithFormat:NSLocalizedString(@"Stop encoding ?", nil)];
+  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;
@@ -2981,34 +3108,55 @@ fWorkingCount = 0;
         
     NSBeginCriticalAlertSheet(
             alertTitle,
-            NSLocalizedString(@"Keep Encoding", nil),
-            nil,
-            NSLocalizedString(@"Stop Encoding", nil),
+            NSLocalizedString(@"Continue Encoding", nil),
+            NSLocalizedString(@"Cancel Current and Stop", nil),
+            NSLocalizedString(@"Cancel Current and Continue", nil),
             docWindow, self,
-            nil, @selector(didDimissCancelCurrentJob:returnCode:contextInfo:), nil,
-            NSLocalizedString(@"Your movie will be lost if you don't continue encoding.", nil));
+            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) didDimissCancelCurrentJob: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
+- (void) didDimissCancel: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (void *)contextInfo
 {
-    if (returnCode == NSAlertOtherReturn)
+   hb_resume( fQueueEncodeLibhb );
+     if (returnCode == NSAlertOtherReturn)
+    {
         [self doCancelCurrentJob];  // <- this also stops libhb
+    }
+    if (returnCode == NSAlertAlternateReturn)
+    {
+    [self doCancelCurrentJobAndStop];
+    }
 }
 
+- (void) doCancelCurrentJobAndStop
+{
+    hb_stop( fQueueEncodeLibhb );
+    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
+    [[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 );
     }
 }
 
@@ -3318,6 +3466,7 @@ the user is using "Custom" settings by determining the sender*/
 
                curUserPresetChosenNum = nil;
        }
+[self calculateBitrate:nil];
 }
 
 
@@ -3465,9 +3614,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;
-     
-    [fVidBitrateField setIntValue: hb_calc_bitrate( job,
-            [fVidTargetSizeField intValue] )];
+    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);
+        
+    }
+
+    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 -
@@ -3480,18 +3718,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 max source storage width and height */
+    job->width = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
+    job->height = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
     
     [self calculatePictureSizing: sender];
     /* We call method to change UI to reflect whether a preset is used or not*/    
@@ -3573,20 +3802,7 @@ the user is using "Custom" settings by determining the sender*/
     }
 
     /* 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];
-    }
+    
     
        /* Deinterlace */
        if ([fPictureController deinterlace] == 0)
@@ -3625,11 +3841,13 @@ the user is using "Custom" settings by determining the sender*/
        }
     
     /* Deblock */
-    if ([fPictureController deblock]) {
-        [fPicSettingDeblock setStringValue: @"Yes"];
+    if ([fPictureController deblock] == 0) 
+    {
+        [fPicSettingDeblock setStringValue: @"Off"];
     }
-    else {
-        [fPicSettingDeblock setStringValue: @"No"];
+    else 
+    {
+        [fPicSettingDeblock setStringValue: [NSString stringWithFormat:@"%d",[fPictureController deblock]]];
     }
        
        if (fTitle->job->pixel_ratio > 0)
@@ -4450,7 +4668,7 @@ the user is using "Custom" settings by determining the sender*/
         [drcSlider setEnabled: YES];
         [drcField setEnabled: YES];
     }
-    
+[self calculateBitrate:nil];    
 }
 
 - (IBAction) audioDRCSliderChanged: (id) sender
@@ -4570,57 +4788,134 @@ the user is using "Custom" settings by determining the sender*/
 #pragma mark Preset Outline View Methods
 #pragma mark - Required
 /* These are required by the NSOutlineView Datasource Delegate */
-/* 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 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;
-}
-/* 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 */
-    if (item == nil)
+    if (item == nil) // for an outline view the root level of the hierarchy is always nil
+    {
         return [UserPresets count];
+    }
     else
-        return 0;
+    {
+        /* 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;
+        }
+    }
 }
-/* Used to tell the outline view which information is to be displayed per item */
-- (id)outlineView:(NSOutlineView *)fPresetsOutlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
+
+/* We use this to deterimine children of an item */
+- (id)outlineView:(NSOutlineView *)fPresetsOutlineView child:(int)index ofItem:(id)item
 {
-       /* We have two columns right now, icon and PresetName */
-       
-    if ([[tableColumn identifier] isEqualToString:@"PresetName"])
+    
+    /* we need to return the count of the array in ChildrenArray for this folder */
+    NSArray *children = nil;
+    if (item == nil)
     {
-        return [item objectForKey:@"PresetName"];
+        children = UserPresets;
+    }
+    else
+    {
+        if ([item objectForKey:@"ChildrenArray"])
+        {
+            children = [item objectForKey:@"ChildrenArray"];
+        }
+    }   
+    if ((children == nil) || ([children count] <= index))
+    {
+        return nil;
     }
     else
     {
-        return @"something";
+        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;
 }
 
-#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
-{
+/* We use this to determine if an item should be expandable */
+- (BOOL)outlineView:(NSOutlineView *)fPresetsOutlineView isItemExpandable:(id)item
+{
+    
+    /* 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"];
+        }
+    }   
+    
+    /* 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 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
+{
+       /* We have two columns right now, icon and PresetName */
+       
+    if ([[tableColumn identifier] isEqualToString:@"PresetName"])
+    {
+        return [item objectForKey:@"PresetName"];
+    }
+    else
+    {
+        //return @"";
+        return nil;
+    }
+}
+
+#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;
@@ -4634,7 +4929,7 @@ if (item == nil)
         }
         else
         {
-            if ([[userPresetDict objectForKey:@"Type"] intValue] == 0)
+            if ([[item objectForKey:@"Type"] intValue] == 0)
             {
                 fontColor = [NSColor blueColor];
             }
@@ -4642,15 +4937,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]];
         }
@@ -4707,7 +5008,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;
     }
@@ -4725,16 +5027,15 @@ if (item == nil)
 
 - (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)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;
@@ -4745,7 +5046,7 @@ if (item == nil)
     {
         return NSDragOperationNone;
         index = MAX (index, presetCurrentBuiltInCount);
-       }
+       }    
        
     [outlineView setDropItem:item dropChildIndex:index];
     return NSDragOperationGeneric;
@@ -4755,16 +5056,27 @@ if (item == nil)
 
 - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)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;
@@ -4805,12 +5117,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"]]];
@@ -4819,17 +5131,18 @@ 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]];
         /* 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"]];
@@ -4864,22 +5177,22 @@ if (item == nil)
         {
             [fVidEncoderPopUp selectItemWithTitle:[chosenPreset objectForKey:@"VideoEncoder"]];
         }
-
+        
         /* 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]];
-
+        
         [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*/
@@ -4891,16 +5204,16 @@ 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"])
         {
@@ -5019,7 +5332,7 @@ if (item == nil)
                 }
             }
             /* 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*/
+             * 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")
@@ -5170,10 +5483,10 @@ 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 */
@@ -5202,12 +5515,12 @@ 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:
          * height, width, keep ar, anamorphic and crop settings.
@@ -5221,6 +5534,32 @@ if (item == nil)
         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)
             {
@@ -5266,30 +5605,7 @@ if (item == nil)
                 job->pixel_ratio = [[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
+                                /* 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.
@@ -5319,12 +5635,11 @@ if (item == nil)
                     /* VFR */
                     if ([[chosenPreset objectForKey:@"VFR"] intValue] == 1)
                     {
-                        [fPictureController setVFR:[[chosenPreset objectForKey:@"VFR"] intValue]];
-                    }
-                    else
-                    {
-                        [fPictureController setVFR:0];
+                        // We make sure that framerate is set to Same as source variable
+                        // detelecine will take care of itself right below
+                        //[fPictureController setVFR:[[chosenPreset objectForKey:@"VFR"] intValue]];
                     }
+                    
                     /* Detelecine */
                     if ([[chosenPreset objectForKey:@"PictureDetelecine"] intValue] == 1)
                     {
@@ -5346,19 +5661,21 @@ if (item == nil)
                     /* Deblock */
                     if ([[chosenPreset objectForKey:@"PictureDeblock"] intValue] == 1)
                     {
-                        [fPictureController setDeblock:[[chosenPreset objectForKey:@"PictureDeblock"] intValue]];
+                        /* since we used to use 1 to turn on deblock, we now use a 5 in our sliding scale */
+                        [fPictureController setDeblock:5];
                     }
                     else
                     {
                         [fPictureController setDeblock:0];
+                        
                     }
-
-                   [self calculatePictureSizing:nil];
+                    
+                    [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.
@@ -5384,15 +5701,7 @@ if (item == nil)
             {
                 [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)
             {
@@ -5414,11 +5723,13 @@ if (item == nil)
             /* 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
@@ -5475,6 +5786,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: @""];
@@ -5546,130 +5859,141 @@ if (item == nil)
     NSMutableDictionary *preset = [[NSMutableDictionary alloc] init];
        /* 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)
-    {
-        [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"];
-    }
-    if ([fAudLang3PopUp indexOfSelectedItem] > 0)
+    if ([fPresetNewFolderCheck state] == YES)
     {
-        [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"];
+        /* 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 ([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:[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)
+        {
+            [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"];
+        }
+        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)
+        {
+            [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"];
+        }
+        
+        /* 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
@@ -5682,30 +6006,49 @@ 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];   
     }
@@ -5716,72 +6059,224 @@ if (item == nil)
 
 - (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];
 }
 
 
@@ -5849,7 +6344,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];
 }