#!/usr/local/bin/bash

# ====================================================
#
# DVD Builder script by Dik Takken
#
# License: GPL
#
# ====================================================

# TODO:
#
# * Split GUI and script in authoring and menu creation
# * Add 'transition' option: Return to Menu
# * Support multiple DVD player applications






# Set this variable to true for debug/test mode.
# This will generate very short menu animations and
# will not remove any temporary files.

# DON'T forget to remove temporary files when you turn
# debugging off while using the Kommander GUI.

Debug="false"


# ---------------------------------------------------------
# ROUTINES TO COMMUNICATE ERRORS/WARNINGS TO THE USER
# ----------------------------------------------------------

# Present an error message to the user and abort.
# Argument $1 is error message.

PrintError ()
{
 X=$(type -p kdialog)

 if test $X && test -x $X && [ -n "$DISPLAY" ]; then

  kdialog --error "$1"

  UpdateTask "Aborted."
  UpdateProgress 0

 else

  echo
  echo "---- RECEIVED ERROR MESSAGE ----"
  echo
  echo -e "$1"
  echo
  echo "--------------------------------"

 fi

 exit 1
}

# Present a warning message to the user
# Argument $1 is warning message.

PrintWarning ()
{
 X=$(type -p kdialog)

 if test $X && test -x $X && [ -n "$DISPLAY" ]; then

  kdialog --warningcontinuecancel "$1"
  if [ ! "$?" -eq 0 ]; then
  echo
  echo "USER ABORTED PROGRAM"
  echo
  exit 1
  fi

 else

  echo
  echo "---- WARNING ----"
  echo
  echo -e "$1"
  echo
  echo "-----------------"

 fi

}

# ----------------------------------------------------------
# CHECKS TO SEE IF WE HAVE ALL THE REQUIRED TOOLS AVAILABLE.
# ----------------------------------------------------------

Requirements=( convert composite mogrify identify sox mplex dvdauthor png2yuv tcprobe mpeg2enc mp2enc bc kdialog konsole )

PrettyRequirements=( "ImageMagick >= 6.1" "MJPEGTools" "Sox" "DVDAuthor >= 0.6" "Transcode" "bc" )

# Check if tool $1 is available.

ToolCheck ()
{
 echo -ne "Checking for \"$1\" ...\t"
	X=$(type -p $1)
	if test $X && test -x $X;
		then echo " found." ; return 0
		else echo " MISSING" ; return 1
	fi
}

# Print an error when a required utility is missing

Missing ()
{
 PrintError "The utility \"$1\" has not been installed on your computer! \n\nThe KDE DVD Authoring Wizard requires the following software packages to be installed:\n\n$(
 
 Requirement=0
 while [ -n "${PrettyRequirements[$Requirement]}" ]
 do
  echo -n "* ${PrettyRequirements[$Requirement]}\n"
  Requirement=$[$Requirement + 1]
 done

)" 

}

RunChecks ()
{
 Requirement=0
 while [ -n "${Requirements[$Requirement]}" ]
 do
   ToolCheck "${Requirements[$Requirement]}" || Missing "${Requirements[$Requirement]}"
   Requirement=$[$Requirement + 1]
 done

# if [ -z "$(dvdauthor 2>&1 | grep version | grep 0.6.11)" ]; then

#  PrintError "You have a DVDAuthor version other than 0.6.11 installed. These versions are not supported yet.\n\nPlease replace this package with version 0.6.11."

# fi

}

# ----------------------------------------------------------
# COMMUNICATION ROUTINES FOR USE WITH KOMMANDER GUI
# ----------------------------------------------------------

# Set the currently executing task to $1.

UpdateTask ()
{
 if [ -n "$DialogDCOPTaskCommand" ]; then
  $DialogDCOPTaskCommand "$1"
 fi
}

# Set the currently executing task to $1.

UpdateProgress ()
{
 if [ -n "$DialogDCOPProgressCommand" ]; then
   $DialogDCOPProgressCommand $1
 fi
}

# Set the currently executing task to $1.

UpdateGlobalProgress ()
{
 if [ -n "$DialogDCOPGlobalProgressCommand" ]; then
   $DialogDCOPGlobalProgressCommand $1
 fi
}

# ----------------------------------------------------------
# DISK SPACE CHECKING ROUTINES
# ----------------------------------------------------------

# Warn if disk space in directory $1 lower than $2 MB

DiskSpaceWarning ()
{
  FreeSpace=$(df  -m "$1" -P | awk '{print $4}' | tail -n 1)

  if [ $FreeSpace -lt $2 ]; then

    PrintWarning "You are low on disk space in this folder:\n\n$1\n\nYou are strongly encouraged to free some disk space before continuing."

    if [ "$?" -eq 1 ]; then
      exit 1
    fi

  fi
}

# Abort if disk space ran out in directory $1

DiskSpaceError ()
{
  FreeSpace=$(df  -m "$1" -P | awk '{print $4}' | tail -n 1)

  if [ $FreeSpace -le 1 ]; then
    PrintError "You ran out of disk space in this folder:\n\n$1\n\nPlease free more disk space and try again."
    exit 1
  fi
}

# Detect TV system of MPEG file $1

DetectTVSystem ()
{
 if [ -n "$(tcprobe -i "$1" | grep x480)" ]; then

  echo "PAL"

 elif [ -n "$(tcprobe -i "$1" | grep x576)" ]; then

  echo "NTSC"

 fi
}

# Detect aspect ratio of MPEG file $1

DetectImageAspect ()
{
 if [ -n "$(tcprobe -i "$1" | grep 16:9)" ]; then

  echo "16:9"

 elif [ -n "$(tcprobe -i "$1" | grep 4:3)" ]; then

  echo "4:3"

 fi
}


# ----------------------------------------------------------
# SCALE BACKGROUND IMAGE TO FIT SCREEN
# ----------------------------------------------------------

ProcessBackgroundImage ()
{
 if [ "$BuildMenu" == "true" ] && [ $BackgroundType == "Picture" ]; then

 YRes=$(identify "$BackgroundPicture" | grep -E -o [0-9]{1,\}x[0-9]{1,\} | head -n 1 | cut -d "x" -f 2)
 XRes=$(identify "$BackgroundPicture" | grep -E -o [0-9]{1,\}x[0-9]{1,\} | head -n 1 | cut -d "x" -f 1)

 UpdateTask "Fitting background picture to DVD image size..."
 echo "XRes is $XRes and YRes is $YRes"

 if [ $XRes -gt $YRes ]; then

    echo "Scaling..."
    convert "$BackgroundPicture" -resize $MenuWidth "$WorkingDir/backgroundpicture.png"
    YRes=$(identify "$WorkingDir/backgroundpicture.png" | grep -E -o [0-9]{1,\}x[0-9]{1,\} | head -n 1 | cut -d "x" -f 2)

    if [ $YRes -gt $MenuHeight ]; then
      echo "Cropping..."
      convert "$WorkingDir/backgroundpicture.png" +repage -crop ${MenuWidth}x${MenuHeight}+0+$[$[$YRes - $MenuHeight] / 2] +repage "$WorkingDir/backgroundpicture.png"
    fi

    if [ $YRes -lt $MenuHeight ]; then
      echo "Expanding..."
      convert \( -size ${MenuWidth}x${MenuHeight} xc:black "$WorkingDir/backgroundpicture.png" -geometry +0+$[$[$MenuHeight - $YRes] / 2] -compose over -composite \) "$WorkingDir/backgroundpicture.png"
    fi

 else

    echo "Scaling..."
    convert "$BackgroundPicture" -resize x${MenuHeight} "$WorkingDir/backgroundpicture.png"
    XRes=$(identify "$WorkingDir/backgroundpicture.png" | grep -E -o [0-9]{1,\}x[0-9]{1,\} | head -n 1 | cut -d "x" -f 1)

    if [ $XRes -gt $MenuWidth ]; then
      echo "Cropping..."
      convert "$WorkingDir/backgroundpicture.png" +repage -crop ${MenuWidth}x${MenuHeight}+$[$[$XRes - $MenuWidth] / 2]+0 +repage "$WorkingDir/backgroundpicture.png"
    fi

    if [ $XRes -lt $MenuWidth ]; then
      echo "Expanding..."
      convert \( -size ${MenuWidth}x${MenuHeight} xc:black "$WorkingDir/backgroundpicture.png" -geometry +$[$[$MenuWidth - $XRes] / 2]+0 -compose over -composite \) "$WorkingDir/backgroundpicture.png"
    fi

  fi

  UpdateTask ""

 fi
}

# ----------------------------------------------------------
# FUNCTION THAT SPLITS VIDEO FILE $1 INTO SEPERATE FRAMES
#
# Other parameters:
#
# $2 target frame resolution
# $3 First frame
# $4 Last frame
# $5 effect
#
# ----------------------------------------------------------

SplitVideo ()
{
 # -I 5			de-interlace with linear blend (lb)
 # -K			black and white
 # -G			gamma correction
 # -J doublefps		double framerate (slow motion)
 # -J  fps=25:29.97	convert fps from PAL to NTSC
 # -Z 100		convert size to 100x??
 # --post_clip 20	cut 20 pixels off the top and bottom

 if [ "$5" == "washout" ]; then

   TranscodeEffectString="-K -G 0.2"

 fi

 # Transcode options used:
 #
 # -i			Read file
 # -x			autodetect video, ignore audio
 # -I 5			Deinterlace with linear blend (lb)
 # -Z			Convert frame size
 # --keep_asr		Fit input image in target framesize without changing aspect
 # -y im,null		Export video to ImageMagick, ignore audio

 DiskSpaceWarning "$(pwd)" 100

 transcode -i "$1" -x auto,null -I 5 $TranscodeEffectString -Z $2 \
           --keep_asr -y im,null -F png -c $3-$4 -o frame%d.png 2>&1

 DiskSpaceError "$(pwd)"

 if [ $? -gt 0 ] || [ $(ls | wc -l) -lt 1 ]; then

  if [ $3 -gt 0 ]; then

    PrintError "Whoops. Your Transcode version failed while generating frames from this video file:\n\n$1\n\nPlease check that this file contains at least $3 frames."

  else

    PrintError "Whoops. Your Transcode version failed while generating frames from this video file:\n\n$1\n\nMake sure you have a stable, well tested version of Transcode. Transcode must have ImageMagick and MPEG support enabled."

  fi

 fi

}

# Counts how many thumbnail frames were 
# generated, and gets a list of their
# filenames.

CountThumbFrames ()
{
   ThumbWithMostFrames=1
   HighestFrameCount=0

   # Count how many thumb frames were generated for
   # each thumbnail and find out which thumbnail has
   # the most frames.
   # We will read the frame filenames from the dir that
   # has the most frames in it.

   for ((Thumb=1; Thumb <= NumScenes ; Thumb++))
     do

     pushd "$WorkingDir/Thumb$Thumb"

     # Remember how many frames are actually generated. Might be less than requested.
     AvailableFrames[$Thumb]=$[$(ls -l | wc -l) - 1 ]

     if [ ${AvailableFrames[$Thumb]} -gt $HighestFrameCount ]; then
       HighestFrameCount=${AvailableFrames[$Thumb]}
       ThumbWithMostFrames=$Thumb
     fi

     echo "Available frames in Thumb $Thumb: ${AvailableFrames[$Thumb]}"
     popd

   done

   # Store all frame filenames

   ThumbFrameNames=( $(ls "$WorkingDir/Thumb$ThumbWithMostFrames/") )

}


# ----------------------------------------------------------
# FUNCTION THAT SPLITS SCENES INTO THUMBNAILED FRAMES.
# ----------------------------------------------------------

GenerateThumbFrames ()
{
 echo
 echo "--------------------------------"
 echo "Generating Thumbnail Frames"
 echo "--------------------------------"
 echo

   if [ "$BuildMenu" == "true" ]; then

     echo -n "Generating frames for Thumb "
     ForceMenuUpdate="true"

     for ((Thumb=1; Thumb <= NumScenes ; Thumb++))
       do

       echo -n $Thumb,

       mkdir -p "$WorkingDir/Thumb$Thumb" ; pushd "$WorkingDir/Thumb$Thumb"

       rm -f *.png

       UpdateTask "Extracting frames from ${SceneTitles[$Thumb]}..."
       DiskSpaceWarning "$(pwd)" $[ $NumSceneFrames / 10 ]

       SplitVideo "${SceneFiles[$Thumb]}" ${ThumbWidth}x${ThumbHeight} \
                   $ThumbnailSkipFrames $[ $ThumbnailSkipFrames + $NumSceneFrames ]

       popd

       UpdateProgress $[$Thumb * 100 / $NumScenes]

     done

     if [ "$BackgroundType" == "Movie" ]; then

       if [ -d "BackgroundMovie" ]; then

         echo "Background movie frames already generated. Skipping."

       else 

         # Output frames of background movie as png thumbnails.

         UpdateTask "Extracting frames from background movie..."

         mkdir -p "$WorkingDir/BackgroundMovie"
         pushd "$WorkingDir/BackgroundMovie"

         if [ $WidescreenDVD == "true" ]; then

          SplitVideo "$BackgroundMovie" 1024x576 0 $TotalFrameCount $BackgroundWashout

         else

          SplitVideo "$BackgroundMovie" 768x576 0 $TotalFrameCount $BackgroundWashout

         fi

         popd

         UpdateTask "" ; UpdateProgress 0

       fi

     fi

   fi 

 CountThumbFrames
 DecorateThumbFrames
}

# ---------------------------------------------------------------
# ADDS NICE DECORATIVE BORDERS TO THE SCENE FRAMES
# ---------------------------------------------------------------

DecorateThumbFrames ()
{
  echo
  echo "--------------------------------"
  echo "Preprocessing Thumbnail Frames:"
  echo "--------------------------------"
  echo

  # Determine the correct mask for the job
  # Might consider scaling the original on demand

  if [ $ThumbDecoration == "SoftEdge" ]; then

    if [ $WidescreenDVD == "true" ]; then

      ThumbMaskImage="../share/apps/dvdauthorwizard/Pictures/maskwide.png"

    else

      ThumbMaskImage="../share/apps/dvdauthorwizard/Pictures/mask.png"

    fi

  elif [ $ThumbDecoration == "FilmRoll" ]; then

    if [ $WidescreenDVD == "true" ]; then

      ThumbMask="../share/apps/dvdauthorwizard/Pictures/rollwidemask.png"
      ThumbBackground="../share/apps/dvdauthorwizard/Pictures/rollwide.png"

    else

      ThumbMask="../share/apps/dvdauthorwizard/Pictures/rollmask.png"
      ThumbBackground="../share/apps/dvdauthorwizard/Pictures/roll.png"

    fi

  else

    return

  fi

  for ((Thumb=1; Thumb <= NumScenes ; Thumb++))
  do

    UpdateTask "Decorating thumbnail frames of ${SceneTitles[$Thumb]}..."

    FirstDecoFrame=0
    LastDecoFrame=${AvailableFrames[$Thumb]}

    if [ "$StaticMenu" == "true" ]; then

      # Decorate only one frame
      FirstDecoFrame=$[$ThumbFrameCounter % ${AvailableFrames[$Thumb]}]
      LastDecoFrame=$[$FirstDecoFrame + 1]

    fi

    if [ $ThumbDecoration == "SoftEdge" ]; then

      for ((Frame=$FirstDecoFrame; Frame < $LastDecoFrame ; Frame++))
      do

        if [ -n "${ThumbFrameNames[$Frame]}" ] && \
           [ -e "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}" ]; then

	  # Do a Alpha mask composition with clipmask
          composite -gravity center -compose Dst_In "$ThumbMaskImage" "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}" -matte "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}"

          # Don't send too many update commands
          if [ $(( $Frame % 10 )) == 0 ]; then

	    UpdateProgress $[$Frame * 100 / $NumSceneFrames]

	  fi

        fi

      done

    elif [ $ThumbDecoration == "FilmRoll" ]; then

      for ((Frame=$FirstDecoFrame; Frame < $LastDecoFrame ; Frame++))
      do

        if [ -n "${ThumbFrameNames[$Frame]}" ] && \
           [ -e "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}" ]; then

          # Do a Alpha mask composition with mask.png

          convert \(  -gravity center "$ThumbBackground" \( "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}" -shave 0x20 \)  -compose over -composite \) "$WorkingDir/Thumb${Thumb}Shaved.png"

          composite  -gravity center -compose Dst_In "$ThumbBackground" "$WorkingDir/Thumb${Thumb}Shaved.png"                                   "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$Frame]}"

          # Don't send too many update commands
          if [ $(( $Frame % 10 )) == 0 ]; then

             UpdateProgress $[$Frame * 100 / $NumSceneFrames]

          fi

        fi

      done

    fi

   UpdateProgress 100

  done
}

# ---------------------------------------------------------------
# CREATE SOME GRAPHICS THAT WE WILL NEED THROUGHOUT THE PROCESS.
#
# Generates "TextLayer.png".
# ---------------------------------------------------------------

Initialise ()
{
 echo
 echo "--------------------------------"
 echo "Initialising:"
 echo "--------------------------------"
 echo

 UpdateTask "Initialising frame generator..."

 # Generate a nice title and store in "Title.png"

 NumCharacters=$(echo "$Title" | wc -m)
 StrokeWidth=$[ ($NumCharacters / 10 ) + 3 ]

 convert \( -size ${MenuWidth}x$[${ThumbY[1]} - 50] xc:transparent \( \
         -size 3000x150 -pointsize 100 xc:transparent \
         -gravity center -fill $FontColor -stroke $FontOutlineColor -strokewidth $StrokeWidth \
         -font "$TitleFont" -draw "text 0,0 \"$Title\"" -stroke none \
         -draw "text 0,0 \"$Title\"" -trim +repage -bordercolor transparent -border 10 \
         -resize $[$MenuWidth-60]x$[${ThumbY[1]} - 50] \) -gravity center -compose over -composite \)  \
         "$WorkingDir/Title.png"


 # And a subtitle and store in "Subtitle.png"

 NumCharacters=$(echo "$Subtitle" | wc -m)
 StrokeWidth=$[ ( $NumCharacters / 20 ) + 3 ]

 convert \( -size ${MenuWidth}x$[${ThumbY[1]} - 100] xc:transparent \( \
         -size 3000x80 -pointsize 50 xc:transparent \
         -gravity center -fill $FontColor -stroke $FontOutlineColor -strokewidth $StrokeWidth \
         -font "$SubtitleFont" -draw "text 0,0 \"$Subtitle\"" -stroke none \
         -draw "text 0,0 \"$Subtitle\"" -trim +repage -bordercolor transparent -border 10 \
         -resize $[$MenuWidth-60]x$[${ThumbY[1]} - 100] \) -gravity center -compose over -composite \)  \
         "$WorkingDir/Subtitle.png"

 # Generate labels for all clips and store in "Thumb${Thumb}Label.png"

 echo "Generating Thumbnail Labels"

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
   do

     convert -size $[$ThumbWidth + $InterColSpace + $InterColSpace]x37 \
             -pointsize 18 xc:transparent -gravity center -fill $FontColor \
             -stroke $FontOutlineColor -strokewidth 3 \
             -draw "font \"$LabelFont\" text 0,0 \"${SceneTitles[$Thumb]}\"" -stroke none \
             -draw "font \"$LabelFont\" text 0,0 \"${SceneTitles[$Thumb]}\"" -quality 0 \
             "$WorkingDir/Thumb${Thumb}Label.png"

   done

 # Generate a 'Previous Page' text and store in "Previous.png"

 if [ $CurrentPage -gt 1 ]; then

  convert -size 300x40 -pointsize 24 xc:transparent -gravity center -fill $FontColor \
          -stroke $FontOutlineColor -strokewidth 3 \
          -draw "font \"$LabelFont\" text 0,0 \"Previous Page\"" -stroke none \
          -draw "font \"$LabelFont\" text 0,0 \"Previous Page\"" \
          "$WorkingDir/Previous.png"

 fi

 # Generate a 'Next Page' text and store in "Next.png"

 if [ $CurrentPage -lt $NumPages ]; then

  convert -size 300x40 -pointsize 24 xc:transparent -gravity center -fill $FontColor \
          -stroke $FontOutlineColor -strokewidth 3 \
          -draw "font \"$LabelFont\" text 0,0 'Next Page'" -stroke none \
          -draw "font \"$LabelFont\"  text 0,0 'Next Page'" "$WorkingDir/Next.png"

 fi

 # Combine all elements in one combined Text Layer
 # and store in "TextLayer.png"

 echo "Generating Combination Layer.."

 # We build one big convert command string, which we
 # execute in the end:

 CompositeCommand="convert \( \("

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
  do

   CompositeCommand="$CompositeCommand \( "

  done

 if [ $CurrentPage -gt 1 ]; then

  # Needed for the "Previous" label
  CompositeCommand="$CompositeCommand \( "

 fi

 if [ $CurrentPage -lt $NumPages ]; then

  # Needed for the "Next" label
  CompositeCommand="$CompositeCommand \( "

 fi

 CompositeCommand="$CompositeCommand -size ${MenuWidth}x$MenuHeight xc:transparent "

 if [ $CurrentPage -gt 1 ]; then

  # Add Previous.png to composition
  CompositeCommand="$CompositeCommand Previous.png -geometry +20+500 -compose over -composite \)"

 fi

 if [ $CurrentPage -lt $NumPages ]; then

  # Add Next.png to composition
  CompositeCommand="$CompositeCommand Next.png -geometry +$(echo $[$MenuWidth - 320])+500 -compose over -composite \) "

 fi

 # Add Title.png and Subtitle.png to composition
 CompositeCommand="$CompositeCommand Title.png -geometry +0+20 -compose over -composite \) "
 CompositeCommand="$CompositeCommand Subtitle.png -geometry +0+115 -compose over -composite \) "

 # Add all thumbnail labels to composition

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
  do

  CompositeCommand="$CompositeCommand Thumb${Thumb}Label.png -geometry +$[${ThumbX[$[$Thumb - $FirstScene + 1]]} -  $InterColSpace]+$[${ThumbY[$[$Thumb - $FirstScene + 1]]} + $ThumbHeight + 8 + 15] -compose over -composite \)"

  done

 # Add a slight blur to reduce flicker on TV

 CompositeCommand="$CompositeCommand TextLayer.png"

 echo "Executing Composite Command:"
 echo "$CompositeCommand"

 # Here we go, execute the command string:

 pushd "$WorkingDir" ; eval "$CompositeCommand" ; popd

}

# ---------------------------------------------------------------
# CREATES ONE FRAME CONTAINING SCENE THUMBNAILS
# ---------------------------------------------------------------

GenerateFrame ()
{

 DiskSpaceWarning "$WorkingDir/Frames/" 10

  # Blend Thumb Frames with Background.

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
  do

    # Bounds Check on Blend Factor

    BlendFactor=${BlendFactors[$[$Thumb - $FirstScene + 1]]}

    if [ $BlendFactor -gt 100 ]; then 

     BlendFactor=100

    fi

    if [ $BlendFactor -lt 0 ]; then

     BlendFactor=0

    fi

    FrameIndex=$[$ThumbFrameCounter % ${AvailableFrames[$Thumb]}]

    composite -matte -blend $BlendFactor \
              "$WorkingDir/Thumb$Thumb/${ThumbFrameNames[$FrameIndex]}" \
              "$WorkingDir/Thumb${Thumb}Background.png" -quality 0 \
              "$WorkingDir/Thumb${Thumb}Blend.png"

  done

 # Merge the clip frames, labels and title with the backgound:
 # Build one big convert command string that merges everything in one go:

 CompositeCommand="convert "

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
  do

   CompositeCommand="$CompositeCommand \( "

  done

 CompositeCommand="$CompositeCommand BackgroundBlend.jpg "

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
  do

    CompositeCommand="$CompositeCommand Thumb${Thumb}Blend.png -geometry +${ThumbX[$[$Thumb - $FirstScene + 1]]}+$[${ThumbY[$[$Thumb - $FirstScene + 1]]} + 15] -compose over -composite \)"

  done

 CompositeCommand="$CompositeCommand -resize ${MenuWidth}x$[( $MenuHeight * 90 ) / 100] \
                                     -resize ${MenuWidth}x${MenuHeight} -depth 8 +matte \
                                     Frames/Frame$GeneratedFrameCounter.png"

 PreviousDir="$(pwd)"

 pushd "$WorkingDir" ; eval "$CompositeCommand" ; popd

}


# ---------------------------------------------------------------
# UPDATE THE BACKGROUND OF THE MENU 
# ---------------------------------------------------------------

UpdateBackground ()
{
 echo "Updating Background.."

 if [  "$BackgroundType" == "Movie" ]; then

  # Use frame from background movie as background.

  BackgroundThumbFrameNames=( $(ls "$WorkingDir/BackgroundMovie/") )

  BackgroundFrameFile=${BackgroundThumbFrameNames[$[$GeneratedFrameCounter - 1]]}

  # Maybe frame does not exist because background movie 
  # is shorter than menu animation. Take last frame in that case.

  if [ -z "$BackgroundFrameFile" ]; then

   BackgroundFrameFile=$(ls "$WorkingDir/BackgroundMovie/" | tail -n 1)

  fi

   cp "$WorkingDir/BackgroundMovie/$BackgroundFrameFile" "$WorkingDir/Background.png"

 else

  if [ "$BackgroundType" == "Checkers" ]; then

    # Create a scrolling checkers background

    if [ "WidescreenDVD" == "true" ]; then

      convert -size ${MenuWidth}x${MenuHeight} -roll +${GeneratedFrameCounter}+${GeneratedFrameCounter} \
              tile:"../share/apps/dvdauthorwizard/Pictures/lightbluecheckerboardwide.png" -blur 2 \
              "$WorkingDir/Background.png"

    else

      convert -size ${MenuWidth}x${MenuHeight} -roll +${GeneratedFrameCounter}+${GeneratedFrameCounter} \
              tile:"../share/apps/dvdauthorwizard/Pictures/lightbluecheckerboard.png" -blur 2 \
              "$WorkingDir/Background.png"

    fi

  else

    #rm -f "$WorkingDir/Background.png"
    cp -f "$WorkingDir/backgroundpicture.png" "$WorkingDir/Background.png"

  fi

 fi

 # Create combination layer of Text Layer and Background.

 BlendFactor=${BlendFactors[1]}

 if [ $BlendFactor -gt 100 ]; then 

  BlendFactor=100

 fi

 if [ $BlendFactor -lt 0 ]; then

  BlendFactor=0

 fi


 if [ $WidescreenDVD == "true" ]; then

   WideString="Wide"

 else

   WideString=""

 fi

 # There seems to be a bug in ImageMagick 6.1.x and 6.2.x, the command 
 # "convert test.png -crop 100x100+0+0" cropped.png
 # does not work on png images. Use JPEG in stead.

 convert \( \
            \( "$WorkingDir/Background.png" \
               "../share/apps/dvdauthorwizard/Pictures/Shadow$ThumbsPerPage-$(($LastScene - $FirstScene + 1))$WideString.png" \
               -compose over -composite \
            \) \
            "$WorkingDir/TextLayer.png" -compose over -composite \
         \) \
         "$WorkingDir/temp.jpg"

 composite -blend $BlendFactor "$WorkingDir/temp.jpg" "$WorkingDir/Background.png" \
           -depth 8 "$WorkingDir/BackgroundBlend.jpg"

}

# ---------------------------------------------------------------
# CUT OUT THE BACKGROUNDS OF THE THUMBS. NEEDED FOR BLENDING.
# ---------------------------------------------------------------

CreateThumbBackgrounds ()
{
 echo -n "Cutting Background Images"

 for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
 do

   convert "$WorkingDir/BackgroundBlend.jpg" +repage \
           -crop ${ThumbWidth}x${ThumbHeight}+${ThumbX[$[$Thumb - $FirstScene + 1]]}+$((${ThumbY[$[$Thumb - $FirstScene + 1]]} + 15)) \
           -quality 0 +repage "$WorkingDir/Thumb${Thumb}Background.png"

 done

}

# ---------------------------------------------------------------
# FADE BACKGROUND BY BLENDING IT WITH BLACK FRAME.
# ---------------------------------------------------------------

FadeBackground ()
{

 # Bounds Check
 Fade=$1
 if [ $Fade -gt 100 ]; then 
   Fade=100
 fi

 # size option required???
 eval "composite -blend $Fade \"$WorkingDir/Background.png\" -size ${MenuWidth}x${MenuHeight} xc:black -depth 8 \"$WorkingDir/FadedBackground.png\""

}


# -----------------------------------------------------------------
# GENERATE DVD SUBTITLE BITMAPS FOR MULTIPLEXING WITH MPEG STREAM.
# BITMAPS CONTAIN BORDERS SHOWN FOR CURRENTLY SELECTED TITLE..
# -----------------------------------------------------------------

AddSubtitles ()
{
 # Create empty base images

 if [ $TVSystem == "PAL" ]; then

  convert -size 720x576 xc:transparent "$WorkingDir/DVDMenuBase.png"
  MenuStrokeWidth=4

 else

  convert -size 720x480 xc:transparent "$WorkingDir/DVDMenuBase.png"
  MenuStrokeWidth=4

 fi

 convert -size ${MenuWidth}x576 xc:black "$WorkingDir/DVDMenuSelection.png"

 # Generate image for selected menu items.
 # Draws red rectangles around all clickable items in the menu.

 convert "$WorkingDir/DVDMenuSelection.png" -stroke '#FF0000' -fill '#000000' \
         -strokewidth $MenuStrokeWidth \
         -draw "$(

                   # Thumbnails

                   for ((Thumb=FirstScene; Thumb <= LastScene ; Thumb++))
                   do

                     X1=${ThumbX[$[$Thumb - $FirstScene + 1]]}
                     Y1=$[${ThumbY[$[$Thumb - $FirstScene + 1]]} + 15]

                     X2=$[${ThumbX[$[$Thumb - $FirstScene + 1]]} + $ThumbWidth]
                     Y2=$[${ThumbY[$[$Thumb - $FirstScene + 1]]} + $ThumbHeight + 15]

                     echo -n "rectangle $X1,$Y1 $X2,$Y2 "

                   done 

                   # 'Previous' button

                   if [ $CurrentPage -gt 1 ]; then

                    X1=2
                    Y1=500

                    X2=300
                    Y2=540

                    echo -n "rectangle $X1,$Y1 $X2,$Y2 "

                   fi

                   # 'Next' button

                   if [ $CurrentPage -lt $NumPages ]; then

                    X1=$(echo $[$MenuWidth - 300])
                    Y1=500

                    X2=$(echo $[$MenuWidth - 4])
                    Y2=540

                    echo -n "rectangle $X1,$Y1 $X2,$Y2 "

                   fi

                 )"  "$WorkingDir/DVDMenuSelection.png"


 # Scale the image to the right size for PAL or NTSC
 # Use a scaling filter that makes sure that the number
 # of red pixels in the image does not grow. Otherwise
 # DVDAuthor fails to detect the rectangles properly.

 if [ $TVSystem == "PAL" ]; then

   convert "$WorkingDir/DVDMenuSelection.png" -filter Point -resize 720x576! \
           "$WorkingDir/DVDMenuSelection.png"

 else

   convert "$WorkingDir/DVDMenuSelection.png" -filter Point -resize 720x480! \
           "$WorkingDir/DVDMenuSelection.png"

 fi

 # Make sure that the images do not contain more than 4 colors
 # Otherwise DVDAuthor goes nuts.

 convert "$WorkingDir/DVDMenuSelection.png" \
         -colors 4 -matte -type PaletteMatte -transparent '#000000' \
         "$WorkingDir/DVDMenuSelection.png"

 # The 'Selection' image and the 'Highlight' image are identical.

 cp "$WorkingDir/DVDMenuSelection.png" "$WorkingDir/DVDMenuHighlight.png"


 # Create a soundtrack in mp2 format.

 if [ "$SoundtrackFile" == "" ]; then

   # Generate a bit of silence, the length of the track doesn't matter.

   NumAudioFrames=$(echo "scale=2; (48000 / $VideoFramerate) * $TotalFrameCount" | bc | cut -d . -f 1)

   UpdateTask "Generating Empty Soundtrack..."

   pushd "$WorkingDir"

   dd if=/dev/zero bs=2 count=$NumAudioFrames | sox -r 48000 -t .sw - -t .wav -w /dev/stdout \
                                              | mp2enc -b 128 -r 48000 -o soundtrack.mp2 < /dev/stdin

   popd

 else

   DiskSpaceWarning "$WorkingDir" 100

   # Detect sample rate

   DetectedSampleRate=$(sox "$SoundtrackFile" -t .wav /dev/stdout | sox -V -t .wav /dev/stdin -e 2>&1 | \
                        grep -E -o [0-9]{1,\}\ samp/sec | \
                        awk '{print $1}')

   Length=$(echo "scale=4; tmp = $TotalFrameCount / $VideoFramerate; if (tmp <= 1) tmp = 1; tmp" | bc)
   FadeoutLength=$(echo "scale=4; tmp = $Length * 0.05; if (tmp <= 1) tmp=1; tmp" | bc)

   UpdateTask "Processing Soundtrack File..."

   # Trim and Fade-out soundtrack, resample to 48 KHz when needed.

   if [ "$DetectedSampleRate" == 48000 ]; then

     sox "$SoundtrackFile" -t .wav -w "$WorkingDir/soundtrack.wav" \
         fade t 0 $Length  $FadeoutLength trim 0 $Length

   else

     sox "$SoundtrackFile" -t .wav -w -r 48000 "$WorkingDir/soundtrack.wav" \
         fade t 0 $Length  $FadeoutLength trim 0 $Length resample -qs

   fi

   # Encode to mp2 format

   pushd "$WorkingDir"

   cat soundtrack.wav | mp2enc -s -r 48000 -o soundtrack.mp2 < /dev/stdin

   popd

   #rm -f "$WorkingDir/soundtrack.wav" "$WorkingDir/audiodump.wav"

 fi

 DiskSpaceError "$WorkingDir"

 echo "Multiplexing.."

 # Write SPUMux Control File

 rm -f "$WorkingDir/spumux.xml"

 echo "<subpictures>" >> "$WorkingDir/spumux.xml"
 echo "<stream>" >> "$WorkingDir/spumux.xml"
 echo "  <spu" >> "$WorkingDir/spumux.xml"
 echo "      force=\"yes\"" >> "$WorkingDir/spumux.xml"
 echo "      start=\"00:00:00.00\"" >> "$WorkingDir/spumux.xml"
 echo "      image=\"$WorkingDir/DVDMenuBase.png\"" >> "$WorkingDir/spumux.xml"
 echo "      select=\"$WorkingDir/DVDMenuSelection.png\"" >> "$WorkingDir/spumux.xml"
 echo "      highlight=\"$WorkingDir/DVDMenuHighlight.png\"" >> "$WorkingDir/spumux.xml"
 echo "      autooutline=\"infer\"" >> "$WorkingDir/spumux.xml"
 echo "      outlinewidth=\"20\"" >> "$WorkingDir/spumux.xml"
 echo "      autoorder=\"rows\">" >> "$WorkingDir/spumux.xml"
 echo "</spu>" >> "$WorkingDir/spumux.xml"
 echo "</stream>" >> "$WorkingDir/spumux.xml"
 echo "</subpictures>" >> "$WorkingDir/spumux.xml"

 # Multiplex Audio, Video and subtitles into one MPEG stream.

 UpdateTask "Multiplexing..."

 mplex -f 8 -o /dev/stdout "$OutputDir/MenuPage$CurrentPage.m2v" \
                           "$WorkingDir/soundtrack.mp2" | \
                    spumux "$WorkingDir/spumux.xml" 2> "$WorkingDir/MPlexOutput" > \
                           "$OutputDir/MenuPage$CurrentPage.mpg" 

 echo ""
 echo "MPlex / SPUMux STDERR output:"
 echo ""

 cat "$WorkingDir/MPlexOutput"

 # Check for a known problem with ImageMagick

 if [ -n "$(cat "$WorkingDir/MPlexOutput" | grep "WARN: Bad image")" ]; then

   PrintError "Your version of ImageMagick fails to cooperate with DVDAuthor.\n\nPlease downgrade to an older version of ImageMagick or upgrade to a newer version of DVDAuthor."

 fi

 # Check if something went wrong

 if [ -n "$(cat "$WorkingDir/MPlexOutput" | grep "ERR:")" ]; then

   PrintError "MPlex and/or SPUMux generated errors:\n\n$(cat "$WorkingDir/MPlexOutput" | grep "ERR:")"

 fi

 rm -f "$OutputDir/MenuPage$CurrentPage.m2v"

}


# Write an XML file that describes the DVD structure to DVDAuthor

WriteDVDAuthorXML ()
{

 echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>" > "$WorkingDir/dvdauthor.xml"
 echo "<dvdauthor dest=\"$OutputDir/DVD/\">" >> "$WorkingDir/dvdauthor.xml"

 if [ "$IntroMovie" == "" ]; then
   echo " <vmgm />" >> "$WorkingDir/dvdauthor.xml"
 else

   # Play the intro movie right after inserting the DVD

   echo " <vmgm>" >> "$WorkingDir/dvdauthor.xml"
   echo "   <menus>" >> "$WorkingDir/dvdauthor.xml"
   echo "     <pgc>" >> "$WorkingDir/dvdauthor.xml"
   echo "        <vob file=\"$IntroMovie\"/>" >> "$WorkingDir/dvdauthor.xml"
   echo "        <post>" >> "$WorkingDir/dvdauthor.xml"

   # Jump to Menu after playing intro
   # Jump to first title when no menu available.

   if [ -f "$OutputDir/MenuPage1.mpg" ]; then

    echo "          jump titleset 1 menu;" >> "$WorkingDir/dvdauthor.xml"

   else 

    echo "          jump vmgm title 1;" >> "$WorkingDir/dvdauthor.xml"

   fi

   echo "        </post>" >> "$WorkingDir/dvdauthor.xml"
   echo "     </pgc>" >> "$WorkingDir/dvdauthor.xml"
   echo "   </menus>" >> "$WorkingDir/dvdauthor.xml"
   echo " </vmgm>" >> "$WorkingDir/dvdauthor.xml"

 fi 

 echo " <titleset>" >> "$WorkingDir/dvdauthor.xml"

 # Add the DVD menu pages, when available.

 if [ -f "$OutputDir/MenuPage1.mpg" ]; then

   echo "File $OutputDir/MenuPage1.mpg found. DVD will have menus."


   echo "   <menus>" >> "$WorkingDir/dvdauthor.xml"
   echo "     <audio lang=\"en\" />" >> "$WorkingDir/dvdauthor.xml"

   FirstScene=1
   LastScene=$ThumbsPerPage

   # Define all menu pages

   for ((CurrentPage=1; CurrentPage <= $NumPages ; CurrentPage++))
     do
       echo -n "     <pgc" >> "$WorkingDir/dvdauthor.xml"

       # First menu page is the Root menu.

       if [ $CurrentPage -eq 1 ]; then
        echo -n " entry=\"root\"" >> "$WorkingDir/dvdauthor.xml"
       fi

       echo ">" >> "$WorkingDir/dvdauthor.xml"

       echo "       <vob file=\"$OutputDir/MenuPage$CurrentPage.mpg\" pause=\"2\" />" >> "$WorkingDir/dvdauthor.xml"

       # Add buttons for all thumbnails

       for ((Scene=FirstScene; Scene <= LastScene ; Scene++))
         do
            echo "       <button>jump title $Scene;</button>" >> "$WorkingDir/dvdauthor.xml"
         done

       # Add a PREVIOUS button

       if [ $CurrentPage -gt 1 ]; then
         echo "       <button>jump menu $(echo $[$CurrentPage - 1]);</button>" >> "$WorkingDir/dvdauthor.xml"
       fi

       # Add a NEXT button

       if [ $CurrentPage -lt $NumPages ]; then
         echo "       <button>jump menu $(echo $[$CurrentPage + 1]);</button>" >> "$WorkingDir/dvdauthor.xml"
       fi

       echo "       <post>jump menu ${CurrentPage};</post>" >> "$WorkingDir/dvdauthor.xml"
       echo "     </pgc>" >> "$WorkingDir/dvdauthor.xml"

       FirstScene=$[$FirstScene + $ThumbsPerPage]
       LastScene=$[$LastScene + $ThumbsPerPage]

       if [ $LastScene -gt $NumScenes ]; then
         LastScene=$NumScenes
       fi

     done

   echo "   </menus>" >> "$WorkingDir/dvdauthor.xml"
 fi

 # Add the actual titles

 echo "   <titles>" >> "$WorkingDir/dvdauthor.xml"
 echo "     <audio lang=\"en\" />" >> "$WorkingDir/dvdauthor.xml"
 
 for ((Scene=1; Scene <= NumScenes ; Scene++))
   do
     echo "     <pgc>" >> "$WorkingDir/dvdauthor.xml"
     echo -n "       <vob file=\"${SceneFiles[$Scene]}\" " >> "$WorkingDir/dvdauthor.xml"

     # See if there is a Chapters file that defines the chapters in the current MPEG file.
     # A Chapters file contains only one line, listing time indices of chapters.
     #
     # Example:
     #
     # 0,30:0,1:0:0,1:30:0,2:0:0,2:30:0,3:0:0
     #
     # We also try getting chapter info from a DVDAuthor XML file, when present.
     #
     # Add user-configurable pause.
     # Wait 5 seconds after last movie.

     ChapterFileName="${SceneFiles[$Scene]%%.*}.chapters"
     KinoChapterFileName="${SceneFiles[$Scene]%%.*}-dvdauthor.xml"

     if [ -e "$ChapterFileName" ]; then

       echo ""
       echo "Found a chapters file for mpeg ${SceneFiles[$Scene]}"
       echo "Chapters=\"$(cat "$ChapterFileName" | head -n 1)\""
       echo ""

       echo -n "chapters=\"$(cat "$ChapterFileName" | head -n 1)\" " >> "$WorkingDir/dvdauthor.xml"

     elif [ -e "$KinoChapterFileName" ]; then

       echo ""
       echo "Found a Kino chapters file for mpeg ${SceneFiles[$Scene]}"
       echo "Chapters=\"$(grep vob "$KinoChapterFileName" | sed 's/.* chapters="//' | sed 's/".*$//')\""
       echo ""

       echo -n "chapters=\"$(grep vob "$KinoChapterFileName" | sed 's/.* chapters="//' | sed 's/".*$//')\" " >> "$WorkingDir/dvdauthor.xml"

     else

       echo -n "chapters=\"0:0\" " >> "$WorkingDir/dvdauthor.xml"

     fi

     # Add user configurable pause at end of movie.
     # Add 5 second pause after last movie

     if [ ${ScenePause[$Scene]} != 0 ]; then 

       echo -n "pause=\"${ScenePause[$Scene]}\" " >> "$WorkingDir/dvdauthor.xml"

     elif [ $Scene -eq $NumScenes ]; then

       echo -n "pause=\"5\" " >> "$WorkingDir/dvdauthor.xml"

     fi

     echo  "/>" >> "$WorkingDir/dvdauthor.xml"

     if [ $Scene -ne $NumScenes ]; then

       # Jump to next movie, if any

       echo "       <post>jump title $(($Scene + 1));</post>" >> "$WorkingDir/dvdauthor.xml"

     else 
 
       # Call Root Menu, if we have a menu.

       if [ -f "$OutputDir/MenuPage1.mpg" ]; then

         echo "       <post>call menu entry root;</post>" >> "$WorkingDir/dvdauthor.xml"

       fi

     fi

     echo "     </pgc>" >> "$WorkingDir/dvdauthor.xml"

   done

 echo "   </titles>" >> "$WorkingDir/dvdauthor.xml"
 echo " </titleset>" >> "$WorkingDir/dvdauthor.xml"
 echo "</dvdauthor>" >> "$WorkingDir/dvdauthor.xml"

 if [ "$EditXML" == "true" ]; then

   kdialog --msgbox "You requested to manually edit the generated XML file before authoring. KDE DVDAuthor Wizard will open the XML file using 'KWrite'.\n\nWhen you are finished editing, save the file and close the editor. The DVD will be built using your customized XML file.\n\nIf you make a mistake, you can simply run the 'Finalize' step of KDE DVDAuthor Wizard again."

   if [ -z "$(which kwrite)" ]; then

     PrintError "Could not find the 'KWrite' editor. Please install it in order to use the XML editing function."

   else

     kwrite "$WorkingDir/dvdauthor.xml"

   fi


 fi

}


# ---------------------------------------------------------------
# GENERATE DVD FILE STRUCTURE USING DVDAUTHOR.
# ---------------------------------------------------------------

AuthorDVD ()
{

 UpdateTask "Building DVD file structure..."

 # Clear output directory

 rm -f -R "$OutputDir/DVD"
 mkdir "$OutputDir/DVD" 

 DiskSpaceWarning "$OutputDir" $TotalDVDSize

 dvdauthor -x "$WorkingDir/dvdauthor.xml" > "$WorkingDir/DVDAuthorOutput.txt" 2>&1

 echo ""
 echo "DVDAuthor warnings (first 100 lines):"
 echo ""
 echo "------------------------------"
 echo ""

 cat "$WorkingDir/DVDAuthorOutput.txt" | head -n 100

 echo ""
 echo "------------------------------"
 echo ""

 # Check if DVDAuthor failed

 if [ -n "$(cat "$WorkingDir/DVDAuthorOutput.txt" | grep ERR:)" ]; then

   PrintError "DVDAuthor failed.\n\nPlease check that your MPEG files are DVD compatible, and that the file names of your MPEG files do not contain any special characters.\n\nThe error message was:\n\n$(cat "$WorkingDir/DVDAuthorOutput.txt" | grep ERR:)"

 fi

 DiskSpaceError "$OutputDir/DVD"

 UpdateTask "DVD is finished."
}


# Generate the frames for a static menu.
# We only need to generate one frame and
# duplicate it.

GenerateStaticFrames ()
{
 UpdateTask "Generating static frames..."

 for ((Thumb=1; Thumb <= ThumbsPerPage ; Thumb++))
  do
  BlendFactors[$Thumb]=100
  done

 # Duplicate a frame in the middle of the menu animation
 GeneratedFrameCounter="$[ ($TotalFrameCount / 2) + 1 ]"

 # Initialise background
 UpdateBackground
 CreateThumbBackgrounds

 # Clean up first
 rm -f -R "$WorkingDir/Frames"
 mkdir "$WorkingDir/Frames"

 # Output one frame
 GenerateFrame

 # Create lots of duplicates of this one frame,
 # use symlinks to save diskspace

 for ((Frame=1; Frame <= $TotalFrameCount ; Frame++))
  do
  ln -s "$WorkingDir/Frames/Frame$GeneratedFrameCounter.png" "$WorkingDir/Frames/Frame$Frame.png"
  done

 UpdateGlobalProgress $[ ( $CurrentPage * 100 ) / $NumPages ]

 UpdateTask "Done."
}

# Generate the frames for an animated DVD menu.

GenerateDynamicFrames ()
{
 # Clean up first
 rm -f -R "$WorkingDir/Frames"
 mkdir "$WorkingDir/Frames"
 
 # Initialise background
 UpdateBackground
 
 #--------------------------------------------------
 # STEP 1
 # Start by fading in the (animating) background.
 #--------------------------------------------------

 echo -n "Fading in Background"
 UpdateTask "Step 1 of 5: Background appears..."

 for ((Frame=1; Frame <= $NumFadeinFrames ; Frame++,GeneratedFrameCounter++))
  do

   DiskSpaceWarning "$WorkingDir//Frames" 10

   # Make sure the argument runs to 100.
   FadeBackground $[$[$Frame * 150] / $NumFadeinFrames]

   mv "$WorkingDir/FadedBackground.png" "$WorkingDir/Frames/Frame$GeneratedFrameCounter.png"

   if [ "$StaticBackground" != "true" ]; then
     UpdateBackground
   fi

   UpdateProgress       $[$Frame * 100 / $NumFadeinFrames]
   UpdateGlobalProgress $[ ( ( ( ( $CurrentPage - 1 ) * $TotalFrameCount ) + $GeneratedFrameCounter) * 100 ) / ( $NumPages * $TotalFrameCount ) ]

 done

 #--------------------------------------------------
 # STEP 2 
 # Fade in the animating thumbnails.
 #--------------------------------------------------

 UpdateBackground
 CreateThumbBackgrounds

 # Thumb Frame Counter. 
 ThumbFrameCounter="0"

 UpdateTask "Step 2 of 5: Thumbnails appear..."

 for ((Frame=0; Frame < $ThumbNumFadeinFrames ; Frame++,ThumbFrameCounter++,GeneratedFrameCounter++))
  do

   # Update Background if Necessary
   if [ "$StaticBackground" != "true" ]; then
    UpdateBackground
    CreateThumbBackgrounds
   fi

   # Output Next Frame
   GenerateFrame

   # Update Blend Factors
   for ((Thumb=1; Thumb <= ThumbsPerPage ; Thumb++))
    do
     BlendFactors[$Thumb]=$[${BlendFactors[$Thumb]} + $BlendStepSize]
    done

   UpdateProgress $[$Frame * 100 / $ThumbNumFadeinFrames]
   UpdateGlobalProgress $[ ( ( ( ( $CurrentPage - 1 ) * $TotalFrameCount ) + $GeneratedFrameCounter) * 100 ) / ( $NumPages * $TotalFrameCount ) ]

  done


 #--------------------------------------------------
 # STEP 3
 # Just animate the thumbnails and background.
 #--------------------------------------------------

 UpdateBackground

 UpdateTask "Step 3 of 5: Animating thumbnails ..."
 for ((Frame=0; Frame < $ThumbAnimateFrames ; Frame++,ThumbFrameCounter++,GeneratedFrameCounter++))
  do

  # Update Background if Necessary
  if [ "$StaticBackground" != "true" ]; then
   UpdateBackground
   CreateThumbBackgrounds
  fi

  # Output Next Frame
  GenerateFrame

  UpdateProgress $[$Frame * 100 / $ThumbAnimateFrames]
  UpdateGlobalProgress $[ ( ( ( ( $CurrentPage - 1 ) * $TotalFrameCount ) + $GeneratedFrameCounter) * 100 ) / ( $NumPages * $TotalFrameCount ) ]

 done

 #--------------------------------------------------
 # STEP 4
 # Fade out the thumbs.
 #--------------------------------------------------

 UpdateTask "Step 4 of 5: Thumbnails disappear..."
 for ((Frame=0; Frame < $ThumbFadeOutFrames ; Frame++,ThumbFrameCounter++,GeneratedFrameCounter++))
  do

  # Update Background if Necessary
  if [ "$StaticBackground" != "true" ]; then

   UpdateBackground
   CreateThumbBackgrounds

  fi

  # Output Next Frame
  GenerateFrame

  # Update Blend Factors
  for ((Thumb=1; Thumb <= ThumbsPerPage ; Thumb++))
   do

     BlendFactors[$Thumb]=$[${BlendFactors[$Thumb]} - $BlendStepSize]

   done

  UpdateProgress $[$Frame * 100 / $ThumbFadeOutFrames]
  UpdateGlobalProgress $[ ( ( ( ( $CurrentPage - 1 ) * $TotalFrameCount ) + $GeneratedFrameCounter) * 100 ) / ( $NumPages * $TotalFrameCount ) ]

 done

 #--------------------------------------------------
 # STEP 5
 # Fade out the Background. End.
 #--------------------------------------------------

 echo "Fading out Background"
 UpdateTask "Step 5 of 5: Background disappears..."

 for ((Frame=1; Frame <= $NumFadeinFrames ; Frame++,GeneratedFrameCounter++))
  do

  # Make sure the argument runs to 100.
  FadeBackground $[150 - $[$Frame * 150 / $NumFadeinFrames]]
  mv "$WorkingDir/FadedBackground.png" "$WorkingDir/Frames/Frame$GeneratedFrameCounter.png"

  if [ "$StaticBackground" != "true" ] || [ $Frame == 1 ]; then

   UpdateBackground

  fi

  UpdateProgress $[$Frame * 100 / $NumFadeinFrames]
  UpdateGlobalProgress $[ ( ( ( ( $CurrentPage - 1 ) * $TotalFrameCount ) + $GeneratedFrameCounter) * 100 ) / ( $NumPages * $TotalFrameCount ) ]

  done
}



# ---------------------------------------------------------------
# GENERATE ONE MPEG STREAM FOR CURRENT MENU PAGE
# ---------------------------------------------------------------

GeneratePage ()
{
 Initialise

 mkdir -p "$WorkingDir/Frames"
 rm -f "$WorkingDir/Frames/*"

 # Global Frame Counter. Should always start at 1.
 GeneratedFrameCounter="1"

 if [ "$StaticMenu" == "true" ]; then

  GenerateStaticFrames

 else

  GenerateDynamicFrames

 fi

 UpdateTask "Encoding to DVD Video stream..."
 UpdateProgress 0
 echo "Generating MPEG stream..."

 DiskSpaceWarning "$OutputDir" $[$TotalFrameCount / 20]

 PreviousDir="$(pwd)"
 cd "$WorkingDir/Frames"

 # Check if MJPEGTools version is >= 1.8.0
 which y4munsharp

 if [ $? -eq 0 ]; then 

   # We have MJPEGTools >= 1.8.0
   # Generate CBR stream

   MPEGOptions="--cbr"

 else

   # Generate VBR stream for old MJPEGTools versions

   if [ "$BackgroundType" == "Movie" ]; then

    MPEGOptions=""

   else

    MPEGOptions="-q 6 -H"

   fi

 fi

 if [ $TVSystem == "PAL" ]; then

  TVSystemOption="-n p"

 else

  TVSystemOption="-n n"
  NTSCFramerateOption="-F 4"

 fi

 # Use correct aspect ratio
 if [ $WidescreenDVD == "true" ]; then

  WideScreenDVDOption="-a 3"

 else

  WideScreenDVDOption="-a 2"

 fi


 # Generate a nice MPEG2 stream:

 echo "png2yuv -j Frame%d.png -b 1 -f $VideoFramerate -I p | yuvscaler -O DVD $TVSystemOption | yuvcorrect -Y LUMINANCE_1.0_16_235_16_235 -Y CHROMINANCE_0.0_1.0_128_1.0_128_16_240 | mpeg2enc $NTSCFramerateOption -f 8 -b 7400 -D 10 -M 0 $MPEGOptions $TVSystemOption $WideScreenDVDOption -o \"$OutputDir/MenuPage$CurrentPage.m2v\"" > "$WorkingDir/EncodingScript"

 konsole -e nice bash "$WorkingDir/EncodingScript"

 rm -f "$WorkingDir/EncodingScript"

 DiskSpaceError "$OutputDir"

 cd "$PreviousDir"

 # Add selectable area's to the menu
 AddSubtitles
 UpdateTask "Done."
}



# Read config file and check user input

ReadConfigFile ()

{
 BackgroundType="$(cat "$1" | grep BackgroundType | cut -d \" -f 2)"
 BackgroundMovie="$(cat "$1" | grep BackgroundMovie | cut -d \" -f 2)"
 BackgroundPicture="$(cat "$1" | grep BackgroundPicture | cut -d \" -f 2)"
 BackgroundWashout="$(cat "$1" | grep BackgroundWashout | cut -d \" -f 2)"
 IntroMovie="$(cat "$1" | grep IntroMovie | cut -d \" -f 2)"
 SoundtrackFile="$(cat "$1" | grep SoundtrackFile | cut -d \" -f 2)"
 NumScenes=$(cat "$1" | grep NumScenes | cut -d = -f 2)
 Title="$(cat "$1" | grep Title= | cut -d \" -f 2)"
 Subtitle="$(cat "$1" | grep Subtitle= | cut -d \" -f 2)"
 TitleFont="$(cat "$1" | grep TitleFont | cut -d \" -f 2)"
 SubtitleFont="$(cat "$1" | grep SubtitleFont | cut -d \" -f 2)"
 LabelFont="$(cat "$1" | grep LabelFont | cut -d \" -f 2)"
 FontColor="$(cat "$1" | grep FontColor | cut -d \" -f 2)"
 FontOutlineColor="$(cat "$1" | grep FontOutlineColor | cut -d \" -f 2)"
 ThumbDecoration="$(cat "$1" | grep SceneDecoration | cut -d \" -f 2)"
 WidescreenDVD="$(cat "$1" | grep Widescreen | cut -d \" -f 2)"
 TVSystem="$(cat "$1" | grep TVSystem | cut -d \" -f 2)"
 Command="$(cat "$1" | grep Command | cut -d \" -f 2)"
 BuildMenu="$(cat "$1" | grep BuildMenu | cut -d \" -f 2)"
 StaticMenu="$(cat "$1" | grep StaticMenu | cut -d \" -f 2)"
 EditXML="$(cat "$1" | grep EditXML | cut -d \" -f 2)"
 ThumbnailSkip=$(cat "$1" | grep ThumbnailSkip | cut -d = -f 2)
 OutputDir="$(cat "$1" | grep OutputDir | cut -d \" -f 2)"
 WorkingDir="$(cat "$1" | grep WorkingDir | cut -d \" -f 2)"


 # Remove any trailing slashes in OutputDir. DVDAuthor does not like them.

 if [ "$(echo "$OutputDir" | tail -c -2)" == "/" ]; then

  OutputDir="$(echo "$OutputDir" | head -c -2)"

 fi

 if [ -z "$WorkingDir" ]; then

  PrintError "No working directory given."

 fi

 if [ -z "$NumScenes" ] || [ "$NumScenes" -lt 1 ]; then

  PrintError "Your playlist is empty!"

 fi

 for ((Thumb=1; Thumb <= NumScenes ; Thumb++))
  do

  SceneFiles[$Thumb]="$( cat "$1" | grep -F SceneFiles[$[$Thumb - 1]]  | cut -d \" -f 2)"
  echo ${SceneFiles[$Thumb]}
  SceneTitles[$Thumb]="$(cat "$1" | grep -F SceneTitles[$[$Thumb - 1]] | cut -d \" -f 2)"

  if [ $(echo "${SceneTitles[$Thumb]}" | wc -m) -gt 28 ]; then

    SceneTitles[$Thumb]="$(echo "${SceneTitles[$Thumb]}" | head -c 25)..."

  fi

  ScenePause[$Thumb]="$( cat "$1" | grep -F ScenePause[$[$Thumb - 1]]  | cut -d = -f 2)"

  done

 if [ $BackgroundType == "Picture" ]; then

   if [ -z "$BackgroundPicture" ]; then

     PrintError "You chose to display a picture on the background of the menu, but you did not select one."

   fi

 elif [ $BackgroundType == "Movie" ]; then

   if [ -z "$BackgroundMovie" ]; then

     PrintError "You chose to play a video on the menu background, but you did not select one."

   fi

 fi

 if [ $BackgroundType == "Picture" ]; then

   StaticBackground="true"

 else

   StaticBackground="false"

 fi

}


CalcGlobalMenuParameters ()

{

 # How many clips fit on one menu page?

 ThumbsPerPage=$NumScenes

 if [ $ThumbsPerPage -gt 6 ]; then

  ThumbsPerPage=6

 fi

 # How many menu pages do we need in order
 # to show all thumbs?

 NumPages=$[$NumScenes / $ThumbsPerPage]

 if [ $[$NumScenes % $ThumbsPerPage] != 0 ]; then

  NumPages=$[$NumPages + 1]

 fi

 echo "We will need $NumPages menu pages."


 # Choose the right thumb size and aspect ratio

 if [ $WidescreenDVD == "true" ]; then

  ThumbWidth=200
  ThumbHeight=112

  # This odd number '1025' is needed for Checkers background.
  # Needs to divide by 5

  MenuWidth=1025
  MenuHeight=576

 else

  ThumbWidth=152
  ThumbHeight=112

  MenuWidth=768
  MenuHeight=576

 fi

 # What framerate do we need?

 if [ $TVSystem == "PAL" ]; then

  VideoFramerate=25

 else

  VideoFramerate=29.97

 fi

 # Now that we know the framerate, we can convert the
 # ThumbnailSkip (in seconds) value to a number of frames.

 ThumbnailSkipFrames=$(echo "scale=2; $ThumbnailSkip * $VideoFramerate" | bc | cut -d . -f 1)

}



# --------------------------------------------------
# Calculate positions of clips on the screen
# --------------------------------------------------

CalcMenuGeometry ()
{

 # Horizontal Space between Thumbnails
 InterColSpace=45

 # Vertical Space between Rows of Thumbnails
 InterRowSpace=55

 # Layout for 6 thumbs

 if [ $ThumbsPerPage == 6 ]; then

  ThumbX[1]=$[ ( $MenuWidth - ( 3 * $ThumbWidth ) - ( 2 * $InterColSpace ) ) / 2 ]
  ThumbX[2]=$[ ${ThumbX[1]} + $ThumbWidth + $InterColSpace ]
  ThumbX[3]=$[ ${ThumbX[2]} + $ThumbWidth + $InterColSpace ]
  ThumbX[4]=${ThumbX[1]}
  ThumbX[5]=${ThumbX[2]}
  ThumbX[6]=${ThumbX[3]}

  ThumbY[1]=$[ ( $MenuHeight - ( 2 * $ThumbHeight ) - $InterRowSpace ) / 2 ]
  ThumbY[2]=${ThumbY[1]}
  ThumbY[3]=${ThumbY[1]}
  ThumbY[4]=$[ ${ThumbY[1]} + $ThumbHeight + $InterRowSpace ]
  ThumbY[5]=${ThumbY[4]}
  ThumbY[6]=${ThumbY[4]}

  BlendFactors[1]=0
  BlendFactors[2]=-20
  BlendFactors[3]=-40
  BlendFactors[4]=-60
  BlendFactors[5]=-80
  BlendFactors[6]=-100

  BlendSteps=200

 fi

 # Layout for 5 thumbs

 if [ $ThumbsPerPage == 5 ]; then

  ThumbX[1]=$[ ( $MenuWidth - ( 3 * $ThumbWidth ) - ( 2 * $InterColSpace ) ) / 2 ]
  ThumbX[2]=$[ ${ThumbX[1]} + $ThumbWidth + $InterColSpace ]
  ThumbX[3]=$[ ${ThumbX[2]} + $ThumbWidth + $InterColSpace ]
  ThumbX[4]=$[ ( $MenuWidth - ( 2 * $ThumbWidth ) - $InterColSpace) / 2 ]
  ThumbX[5]=$[ ${ThumbX[4]} + $ThumbWidth + $InterColSpace ]

  ThumbY[1]=$[ ( $MenuHeight - ( 2 * $ThumbHeight ) - $InterRowSpace ) / 2 ]
  ThumbY[2]=${ThumbY[1]}
  ThumbY[3]=${ThumbY[1]}
  ThumbY[4]=$[ ${ThumbY[1]} + $ThumbHeight + $InterRowSpace ]
  ThumbY[5]=${ThumbY[4]}

  BlendFactors[1]=0
  BlendFactors[2]=-20
  BlendFactors[3]=-40
  BlendFactors[4]=-60
  BlendFactors[5]=-80

  BlendSteps=180

 fi

 # Layout for 4 thumbs

 if [ $ThumbsPerPage == 4 ]; then

  # Create more space between Thumbnails

  InterColSpace=75

  ThumbX[1]=$[ ( $MenuWidth - ( 2 * $ThumbWidth ) - $InterColSpace ) / 2 ]
  ThumbX[2]=$[ ${ThumbX[1]} + $ThumbWidth + $InterColSpace ]
  ThumbX[3]=${ThumbX[1]}
  ThumbX[4]=${ThumbX[2]}

  ThumbY[1]=$[ ( $MenuHeight - ( 2 * $ThumbHeight ) - $InterRowSpace ) / 2 ]
  ThumbY[2]=${ThumbY[1]}
  ThumbY[3]=$[ ${ThumbY[1]} + $ThumbHeight + $InterRowSpace ]
  ThumbY[4]=${ThumbY[3]}

  BlendFactors[1]=0
  BlendFactors[2]=-30
  BlendFactors[3]=-60
  BlendFactors[4]=-90

  BlendSteps=190

 fi

 # Layout for 3 thumbs

 if [ $ThumbsPerPage == 3 ]; then

  ThumbX[1]=$[ ( $MenuWidth - ( 2 * $ThumbWidth ) - $InterColSpace ) / 2 ]
  ThumbX[2]=$[ ${ThumbX[1]} + $ThumbWidth + $InterColSpace ]
  ThumbX[3]=$[ ( $MenuWidth - $ThumbWidth ) / 2 ]

  ThumbY[1]=$[ ( $MenuHeight - ( 2 * $ThumbHeight ) - $InterRowSpace ) / 2 ]
  ThumbY[2]=${ThumbY[1]}
  ThumbY[3]=$[ ${ThumbY[1]} + $ThumbHeight + $InterRowSpace ]

  BlendFactors[1]=0
  BlendFactors[2]=-20
  BlendFactors[3]=-40

  BlendSteps=140

 fi

 # Layout for 2 thumbs

 if [ $ThumbsPerPage == 2 ]; then

  ThumbX[1]=$[ ( $MenuWidth - $ThumbWidth ) / 2 ]
  ThumbX[2]=${ThumbX[1]}

  ThumbY[1]=$[ ( $MenuHeight - ( 2 * $ThumbHeight ) - $InterRowSpace ) / 2 ]
  ThumbY[2]=$[ ${ThumbY[1]} + $ThumbHeight + $InterRowSpace ]

  BlendFactors[1]=0
  BlendFactors[2]=-20

  BlendSteps=120

 fi

 # Layout for 1 thumb

 if [ $ThumbsPerPage == 1 ]; then

  ThumbX[1]=$[ ( $MenuWidth - $ThumbWidth ) / 2 ]
  ThumbY[1]=$[ ( $MenuHeight - $ThumbHeight ) / 2 ]

  BlendFactors[1]=0

  BlendSteps=100

 fi

 # Calculate the space between the columns of thumbnails

 if [ $ThumbsPerPage -le 2 ]; then

   InterColSpace=200

 else

   InterColSpace=$[$[${ThumbX[2]}-${ThumbX[1]}-$ThumbWidth] / 2]

 fi

}

# Calculate frame counts for all 
# animation steps in the menu

CalcAnimationTimings ()

{

 # Calc how many frames we will see the
 # thumbnails animating.

 if [ "$Debug" == "true" ]; then

  NumSceneFrames=15

 elif [ "$Command" == "Preview" ]; then

  NumSceneFrames=1

 else

   if [ $TVSystem == "PAL" ]; then

     NumSceneFrames=400

   else

     NumSceneFrames=480

   fi

 fi

 # How many frames do we spend fading in the background?

 if [ "$Debug" == "true" ]; then

  NumFadeinFrames=2

 elif [ "$Command" == "Preview" ]; then

  NumFadeinFrames=0

 else

  if [ $TVSystem == "PAL" ]; then

    NumFadeinFrames=30

  else

    NumFadeinFrames=36

  fi

fi

 # How big a step size to use for fading in thumbs?
 # This step size determines how fast the thumbnails
 # will appear. The Blend parameter runs from 0 to 100
 # so a blend step of 5 will result in 20 fade-in frames.

 if [ "$Debug" == "true" ]; then

  BlendStepSize=40

 elif [ "$Command" == "Preview" ]; then

  BlendStepSize=200

 else

   if [ $TVSystem == "PAL" ]; then

     BlendStepSize=6

   else

     BlendStepSize=5

   fi

 fi

 # Calculate some handy frame counts

 ThumbNumFadeinFrames=$[$BlendSteps / $BlendStepSize]
 ThumbAnimateFrames=$[$NumSceneFrames - $[$ThumbNumFadeinFrames * 2]]
 ThumbFadeOutFrames=$[$BlendSteps / $BlendStepSize]
 TotalFrameCount=$[$[2 * $NumFadeinFrames] + $NumSceneFrames]

}



# Estimate total size of DVD file structure.

CalcDVDSize ()
{
 # Add 100 MB for the filestructure itself.

 TotalDVDSize=100

 # Add space needed for each MPEG file

 for ((Scene=1; Scene <= NumScenes ; Scene++))
 do

  TotalDVDSize=$[ $TotalDVDSize + \
                  $(du -m "${SceneFiles[$Scene]}" | awk '{print $1}') ]

 done

 # Each menu page is at most 30 MB 

 TotalDVDSize=$[ $TotalDVDSize + ( $NumPages * 30 ) ]

}

# Check if all MPEG files are valid

CheckMPEGFiles ()

{
 UpdateTask "Checking validity of MPEG files..."
 UpdateProgress 0

 mkdir "$WorkingDir/DVD"

 for ((Thumb=1; Thumb <= NumScenes ; Thumb++))
  do

  dvdauthor -t -o "$WorkingDir/DVD" -f "${SceneFiles[$Thumb]}" > "$WorkingDir/DVDAuthorOutput.txt" 2>&1

  if [ $(cat "$WorkingDir/DVDAuthorOutput.txt" | grep ERR: | wc -l) -gt 0 ]; then

   PrintError "The file\n\n${SceneFiles[$Thumb]}\n\nis not a DVD compatible MPEG2 file.\n\nNOTE: You can discover problems like this *before* building the DVD, by using the 'Check Compatibility' button at the playlist page."

  elif [ $(cat "$WorkingDir/DVDAuthorOutput.txt" | grep WARN: | wc -l) -gt 0 ]; then

   NumWarnings=$(cat "$WorkingDir/DVDAuthorOutput.txt" | grep WARN: | wc -l)

   if [ -n "$DISPLAY" ]; then

     kdialog --yesno "The file\n\n${SceneFiles[$Thumb]}\n\ngenerated $NumWarnings warnings. Correct display on DVD players can not be guaranteed!\n\nNOTE: You can discover problems like this *before* building the DVD, by using the 'Check Compatibility' button at the playlist page.\n\nWould you like to view the warnings?"

     if [ $? == 0 ]; then

       cat "$WorkingDir/DVDAuthorOutput.txt" | grep WARN: > "$WorkingDir/DVDAuthorWarnings.txt"

       kfmclient exec "$WorkingDir/DVDAuthorWarnings.txt"

     fi

   fi

  fi

  UpdateProgress $[ ( 100 * $Thumb ) / $NumScenes ]

  done

 UpdateTask "All files are OK."

 CalcDVDSize

 if [ $TotalDVDSize -gt 4500 ]; then

  PrintWarning "The MPEG files in the playlist add up to more than 4500 MB. The resulting DVD image may not fit on a DVD disk!"

 fi

}

# Checks if user is trying to mix PAL and NTSC files
# on one DVD Disk

CheckMixedTVSystems ()
{
 DetectedTVSystemA=$(DetectTVSystem "${SceneFiles[1]}")

 if [ -z "$DetectedTVSystemA" ]; then

   PrintWarning "Failed to detect the intended TV system for one of more MPEG files.\n\nThe file(s) may cause display problems on DVD players."

 else

   for ((Thumb=2; Thumb <= NumScenes ; Thumb++))
    do

    DetectedTVSystemB=$(DetectTVSystem "${SceneFiles[$Thumb]}")

    if [ -z "$DetectedTVSystemB" ]; then

     PrintWarning "Failed to detect the intended TV system for this file:\n\n${SceneFiles[$Thumb]}\n\nThe file may cause display problems on DVD players."

    else

      if [ "$DetectedTVSystemA" != "$DetectedTVSystemB" ]; then
 
       PrintWarning "Some of the files in the playlist are intended for NTSC television systems, while others are for PAL systems.\n\nThe resulting DVD will ONLY play correctly on DVD players and TV systems that support both PAL and NTSC video."

       return

      fi

    fi

    done

 fi
}

# Checks if user is trying to mix widescreen and 'normal'
# aspect ratio files on one DVD Disk

CheckMixedAspectRatios ()
{
 DetectedAspectA=$(DetectImageAspect "${SceneFiles[1]}")

 if [ -z "$DetectedAspectA" ]; then

   PrintWarning "Failed to detect the display aspect ratio for one of more MPEG files.\n\nThe file(s) may cause display problems on DVD players."

 else

   for ((Thumb=2; Thumb <= NumScenes ; Thumb++))
    do

    DetectedAspectB=$(DetectImageAspect "${SceneFiles[$Thumb]}")

    if [ -z "$DetectedAspectB" ]; then

     PrintWarning "Failed to detect the display aspect ratio for this file:\n\n${SceneFiles[$Thumb]}\n\nThe file may cause display problems on DVD players."

    else

      if [ "$DetectedAspectA" != "$DetectedAspectB" ]; then
 
       PrintWarning "Some of the files in the playlist are in widescreen (16:9) format, while others are in standard 4:3 format.\n\nCombining these files in a way that DVD players can handle is a complicated task, DVDAuthor Wizard currently does not support this.\n\nThe resulting DVD will probably NOT display correctly."

       return

      fi

    fi

    done

 fi
}

# Check if soundtrack is valid, if any.

CheckSoundtrack ()

{
 if [ -n "$SoundtrackFile" ]; then

   UpdateTask "Checking validity of soundtrack file..."

   # Detect sample rate

   DetectedSampleRate=$(sox "$SoundtrackFile" -t .wav /dev/stdout | sox -V -t .wav /dev/stdin -e 2>&1 | \
                        grep -E -o [0-9]{1,\}\ samp/sec | \
                        awk '{print $1}')

   if [ -z "$DetectedSampleRate" ]; then

     PrintError "Your version of Sox failed to read the soundtrack file ($(basename "$SoundtrackFile"))."

   fi

   UpdateTask "Soundtrack is OK."

 fi
}


# Create one frame of the menu animation, 
# for use as a preview.

CommandCreatePreview ()
{
  UpdateProgress 0

  for ((Thumb=1; Thumb <= ThumbsPerPage ; Thumb++))
   do
   BlendFactors[$Thumb]=100
   done

  # Create a frame of page 1, in the middle of the animation
  CurrentPage=1
  ThumbFrameCounter="$[$NumSceneFrames / 2]"
  GeneratedFrameCounter="$[$TotalFrameCount / 2]"

  mkdir -p "$WorkingDir/Frames"

  FirstScene=1
  LastScene=$ThumbsPerPage

  GenerateThumbFrames
  ProcessBackgroundImage

  Initialise
  UpdateProgress 10

  UpdateBackground
  UpdateProgress 20

  CreateThumbBackgrounds
  UpdateProgress 30

  GenerateFrame
  UpdateProgress 70

  mv "$WorkingDir/Frames/Frame$GeneratedFrameCounter.png" "$OutputDir/Preview.png"

  if [ $Debug == "false" ]; then
    rm -f "$WorkingDir/Background.png"
  fi

  UpdateProgress 100
  UpdateTask "Done."
}

# Author the DVD. Use any menu animations
# when they are found.

CommandAuthorDVD ()
{
 WriteDVDAuthorXML
 AuthorDVD

 UpdateProgress 100
 UpdateTask "Done."
}

# Create the menu animations

CommandGenerateMenu ()
{
  FirstScene=1
  LastScene=$ThumbsPerPage
  if [ "$StaticMenu" == "true" ]; then
    ThumbFrameCounter="$[$NumSceneFrames / 2]"
  else
    ThumbFrameCounter="0"
  fi

  if [ "$BuildMenu" == "false" ]; then
    echo "We are not building a menu in this run."
  else

    GenerateThumbFrames
    ProcessBackgroundImage

      # Create menu pages

      for ((CurrentPage=1; CurrentPage <= $NumPages ; CurrentPage++))
      do

        GeneratePage

        FirstScene=$[$FirstScene + $ThumbsPerPage]
        LastScene=$[$LastScene + $ThumbsPerPage]

        if [ $LastScene -gt $NumScenes ]; then
          LastScene=$NumScenes
        fi
      done
  fi

 UpdateProgress 100
 UpdateTask "Done."
}




# --------------------
# PROGRAM STARTS HERE
# --------------------

DialogDCOPProgressCommand="$2"
DialogDCOPGlobalProgressCommand="$3"
DialogDCOPTaskCommand="$4"

if [ -z "$1" ]; then

 RunChecks
 echo "You did not provide a config file."
 echo
 echo "USAGE: DVDBuilder ConfigFile.conf"
 exit

fi

ReadConfigFile "$1"
CalcGlobalMenuParameters
CalcMenuGeometry
CalcAnimationTimings
RunChecks

rm -f -R "$WorkingDir"
mkdir -p "$WorkingDir"

# See what command was passed to the script
# and act accordingly.

if [ "$Command" == "Preview" ]; then

 CheckSoundtrack
 CommandCreatePreview

elif [ "$Command" == "Build" ]; then

 CheckMPEGFiles
 CheckMixedTVSystems
 CheckMixedAspectRatios
 CommandAuthorDVD

else

 CheckSoundtrack
 CheckMixedTVSystems
 CheckMixedAspectRatios
 CommandGenerateMenu

fi

rm -f -R "$WorkingDir"

echo ""
echo ""
echo "------------------------"
echo "  END OF SCRIPT RUN"
echo "------------------------"
echo ""
echo ""

# END
