using System;
using System.Collections.Generic;

/*
    Copyright (c) 2010 flixmonk. (http://DVDSwarm.codeplex.com)
    All Rights Reserved.
        
    Redistribution and use in source and binary forms, with or without modification,
    are permitted provided that the following conditions are met:
        
    * Redistributions of source code must retain the above copyright notice, this list
      of conditions and the following disclaimer.
        
    * Redistributions in binary form must reproduce the above copyright notice, this
    list of conditions and the following disclaimer in the documentation and/or other
    materials provided with the distribution. 
        
    * Neither the name of The Flixmonk nor the names of its contributors may be used to
    endorse or promote products derived from this software without specific prior written
    permission.
        
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
    SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
    OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace DVDSwarm
{
    /// <summary>
    /// Contains information about a conversion job.
    /// </summary>
    sealed public class JobInfo
    {
        #region Fields

        private List<AudioTrackInfo> _audioTracks = new List<AudioTrackInfo>();
        private string _baseFilename = string.Empty;
        private Int32 _bFrameCount = 0;
        private CropMode _crop = CropMode.Auto;
        private VideoAspectRatio _cropAspectRatio = VideoAspectRatio.Aspect_1_78;
        private Int32 _cropBottom = 0;
        private Int32 _cropLeft = 0;
        private Int32 _cropRight = 0;
        private Int32 _cropTop = 0;
        private VideoAspectRatio _displayAspectRatio = VideoAspectRatio.Aspect_1_78;
        private Dvd.SmpteTimecode _duration = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
        private DateTime _endTime = DateTime.Now;
        private VideoFieldOrder _fieldOrder =VideoFieldOrder.TopFieldFirst;
        private Int64 _fileLength = 0;
        private Int32 _frameCount = 0;
        private VideoFramerate _framerate = VideoFramerate.Fps30;
        private VideoFrameType _frameType = VideoFrameType.Interlaced;
        private Int32 _iFrameCount = 0;
        private Boolean _isAnimation = false;
        private string _outputFilename = string.Empty;
        private Int32 _outputFrameCount = 0;
        private VideoFramerate _outputFramerate = VideoFramerate.Fps30;
        private Int32 _outputHeight = 0;
        private Int32 _outputWidth = 0;
        private Int32 _pFrameCount = 0;
        private VideoProcessingType _processing = VideoProcessingType.None;
        private VideoProcessingType _processingOverride = VideoProcessingType.None;
        private Boolean _processingOverrideEnabled = false;
        private Int32 _resizeHeight = 0;
        private Int32 _resizeWidth = 0;
        private string _sourceFilename = string.Empty;
        private Int32 _sourceHeight = 0;
        private Int32 _sourceWidth = 0;
        private DateTime _startTime = DateTime.Now;
        private JobStatus _status = JobStatus.Inactive;
        private Boolean _trim = false;
        private Dvd.SmpteTimecode _trimEndTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
        private Dvd.SmpteTimecode _trimOutputEndTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
        private Dvd.SmpteTimecode _trimOutputStartTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
        private Dvd.SmpteTimecode _trimStartTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
        private VideoType _videoType = VideoType.NtscVideo;
        private double _videoTypePercentage = 0;
        private Tools.X264.InputTuning _x264InputTuning = Tools.X264.InputTuning.Film;
              
        #endregion

        #region Properties

        /// <summary>
        /// Gets the list of audio tracks for the job.
        /// </summary>
        public List<AudioTrackInfo> AudioTracks
        {
            get
            {
                return _audioTracks;
            }
        }
        /// <summary>
        /// Gets and sets the user determined video output filename for the job. The filename has no path and no extension.
        /// </summary>
        public string BaseFilename
        {
            get
            {
                return _baseFilename;
            }
            internal set
            {
                _baseFilename = value;
            }
        }
        /// <summary>
        /// Gets and sets the number of B-frames for the video.
        /// </summary>
        public Int32 BFrameCount
        {
            get
            {
                return _bFrameCount;
            }
            internal set
            {
                _bFrameCount = value;
            }
        }
        /// <summary>
        /// Gets and sets the cropping mode.
        /// </summary>
        public CropMode Crop
        {
            get
            {
                return _crop;
            }
            internal set
            {
                _crop = value;
            }
        }
        /// <summary>
        /// Gets and sets the cropping aspect ratio for the source video.
        /// </summary>
        /// <remarks>
        /// DisplayAspectRatio is the value specified by the video stream. CropAspectRatio is the 
        /// value used to remove letterboxing from the video. For example: a 2.35 widescreen video
        /// stored in a fullscreeen video stream would have a DisplayAspectRatio of 1.33 and use a
        /// CropAspectRatio of 2.35 to remove the black borders.
        /// </remarks>
        public VideoAspectRatio CropAspectRatio
        {
            get
            {
                return _cropAspectRatio;
            }
            internal set
            {
                _cropAspectRatio = value;
            }
        }
        /// <summary>
        /// Gets and sets the manual cropping in pixels. The value must be a positive number.
        /// </summary>
        /// <exception cref="System.ArgumentException">Thrown when value is less than zero.</exception>
        public Int32 CropBottom
        {
            get
            {
                return _cropBottom;
            }
            internal set
            {
                if (value < 0)
                {
                    throw new ArgumentException("value is less than zero.");
                }

                _cropBottom = value;
            }
        }
        /// <summary>
        /// Gets and sets the manual cropping in pixels. The value must be a positive number.
        /// </summary>
        /// <exception cref="System.ArgumentException">Thrown when value is less than zero.</exception>
        public Int32 CropLeft
        {
            get
            {
                return _cropLeft;
            }
            internal set
            {
                if (value < 0)
                {
                    throw new ArgumentException("value is less than zero.");
                }

                _cropLeft = value;
            }
        }
        /// <summary>
        /// Gets and sets the manual cropping in pixels. The value must be a positive number.
        /// </summary>
        /// <exception cref="System.ArgumentException">Thrown when value is less than zero.</exception>
        public Int32 CropRight
        {
            get
            {
                return _cropRight;
            }
            internal set
            {
                if (value < 0)
                {
                    throw new ArgumentException("value is less than zero.");
                }

                _cropRight = value;
            }
        }
        /// <summary>
        /// Gets and sets the manual cropping in pixels. The value must be a positive number.
        /// </summary>
        /// <exception cref="System.ArgumentException">Thrown when value is less than zero.</exception>
        public Int32 CropTop
        {
            get
            {
                return _cropTop;
            }
            internal set
            {
                if (value < 0)
                {
                    throw new ArgumentException("value is less than zero.");
                }

                _cropTop = value;
            }
        }
        /// <summary>
        /// Gets and sets the display aspect ratio for the source video as specified in the
        /// transport stream. This value is independent of the CropAspectRatio.
        /// </summary>
        /// <remarks>
        /// DisplayAspectRatio is the value specified by the video stream. CropAspectRatio is the 
        /// value used to remove letterboxing from the video. For example: a 2.35 widescreen video
        /// stored in a fullscreeen video stream would have a DisplayAspectRatio of 1.33 and use a
        /// CropAspectRatio of 2.35 to remove the black borders.
        /// </remarks>
        public VideoAspectRatio DisplayAspectRatio
        {
            get
            {
                return _displayAspectRatio;
            }
            internal set
            {
                _displayAspectRatio = value;
            }
        }
        /// <summary>
        /// Gets and sets the duration of the video.
        /// </summary>
        public Dvd.SmpteTimecode Duration
        {
            get
            {
                return _duration;
            }
            internal set
            {
                _duration = value;
            }
        }
        /// <summary>
        /// Gets and sets the end time for the job.
        /// </summary>
        public DateTime EndTime
        {
            get
            {
                return _endTime;
            }
            internal set
            {
                _endTime = value;
            }
        }
        /// <summary>
        /// Gets and sets the video field order.
        /// </summary>
        public VideoFieldOrder FieldOrder
        {
            get
            {
                return _fieldOrder;
            }
            internal set
            {
                _fieldOrder = value;
            }
        }
        /// <summary>
        /// Gets and sets the video file length in bytes.
        /// </summary>
        public Int64 FileLength
        {
            get
            {
                return _fileLength;
            }
            internal set
            {
                _fileLength = value;
            }
        }
        /// <summary>
        /// Gets and sets the video frame count.
        /// </summary>
        public Int32 FrameCount
        {
            get
            {
                return _frameCount;
            }
            internal set
            {
                _frameCount = value;
            }
        }
        /// <summary>
        /// Gets and sets the video frame rate.
        /// </summary>
        public VideoFramerate Framerate
        {
            get
            {
                return _framerate;
            }
            internal set
            {
                _framerate = value;
            }
        }
        /// <summary>
        /// Gets and sets the video frame type.
        /// </summary>
        public VideoFrameType FrameType
        {
            get
            {
                return _frameType;
            }
            internal set
            {
                _frameType = value;
            }
        }
        /// <summary>
        /// Gets and sets the number of I-frames for the video.
        /// </summary>
        public Int32 IFrameCount
        {
            get
            {
                return _iFrameCount;
            }
            internal set
            {
                _iFrameCount = value;
            }
        }
        /// <summary>
        /// Gets and sets a value indicating whether the video is animation.
        /// </summary>
        public Boolean IsAnimation
        {
            get
            {
                return _isAnimation;
            }
            internal set
            {
                _isAnimation = value;
            }
        }
        /// <summary>
        /// Gets and sets the video output video filename including the full path and file extension.
        /// </summary>
        public string OutputFilename
        {
            get
            {
                return _outputFilename;
            }
            internal set
            {
                _outputFilename = value;
            }
        }
        /// <summary>
        /// Gets and sets the approximate video frame count based on the output framerate.
        /// </summary>
        public Int32 OutputFrameCount
        {
            get
            {
                return _outputFrameCount;
            }
            internal set
            {
                _outputFrameCount = value;
            }
        }
        /// <summary>
        /// Gets and sets the output frame rate after processing the video.
        /// </summary>
        public VideoFramerate OutputFramerate
        {
            get
            {
                return _outputFramerate;
            }
            internal set
            {
                _outputFramerate = value;
            }
        }
        /// <summary>
        /// Gets and sets the output video height.
        /// </summary>
        public Int32 OutputHeight
        {
            get
            {
                return _outputHeight;
            }
            internal set
            {
                _outputHeight = value;
            }
        }
        /// <summary>
        /// Gets and sets the output video width.
        /// </summary>
        public Int32 OutputWidth
        {
            get
            {
                return _outputWidth;
            }
            internal set
            {
                _outputWidth = value;
            }
        }
        /// <summary>
        /// Gets and sets the number of P-frames for the video.
        /// </summary>
        public Int32 PFrameCount
        {
            get
            {
                return _pFrameCount;
            }
            internal set
            {
                _pFrameCount = value;
            }
        }
        /// <summary>
        /// Gets and sets automatic video processing.
        /// </summary>
        public VideoProcessingType Processing
        {
            get
            {
                return _processing;
            }
            internal set
            {
                _processing = value;
            }
        }
        /// <summary>
        /// Gets and sets video processing that will override automatic processing.
        /// </summary>
        public VideoProcessingType ProcessingOverride
        {
            get
            {
                return _processingOverride;
            }
            internal set
            {
                _processingOverride = value;
            }
        }
        /// <summary>
        /// Gets and sets a value indicating whether automatic video processing will be overriden.
        /// </summary>
        public Boolean ProcessingOverrideEnabled
        {
            get
            {
                return _processingOverrideEnabled;
            }
            internal set
            {
                _processingOverrideEnabled = value;
            }
        }
        /// <summary>
        /// Gets and sets the height to which the video will be resized to.
        /// </summary>
        public Int32 ResizeHeight
        {
            get
            {
                return _resizeHeight;
            }
            internal set
            {
                _resizeHeight = value;
            }
        }
        /// <summary>
        /// Gets and sets the width to which the video will be resized to.
        /// </summary>
        public Int32 ResizeWidth
        {
            get
            {
                return _resizeWidth;
            }
            internal set
            {
                _resizeWidth = value;
            }
        }
        /// <summary>
        /// Gets and sets the source video filename for the job.
        /// </summary>
        public string SourceFilename
        {
            get
            {
                return _sourceFilename;
            }
            internal set
            {
                _sourceFilename = value;
            }
        }
        /// <summary>
        /// Gets and sets the source video height.
        /// </summary>
        public Int32 SourceHeight
        {
            get
            {
                return _sourceHeight;
            }
            internal set
            {
                _sourceHeight = value;
            }
        }
        /// <summary>
        /// Gets and sets the source video width.
        /// </summary>
        public Int32 SourceWidth
        {
            get
            {
                return _sourceWidth;
            }
            internal set
            {
                _sourceWidth = value;
            }
        }
        /// <summary>
        /// Gets and sets the start time for the job.
        /// </summary>
        public DateTime StartTime
        {
            get
            {
                return _startTime;
            }
            internal set
            {
                _startTime = value;
            }
        }
        /// <summary>
        /// Gets and sets the status of the job.
        /// </summary>
        public JobStatus Status
        {
            get
            {
                return _status;
            }
            internal set
            {
                _status = value;
            }
        }
        /// <summary>
        /// Gets and sets a value indicating whether to trim the video to a specified range.
        /// </summary>
        public Boolean Trim
        {
            get
            {
                return _trim;
            }
            internal set
            {
                _trim = value;
            }
        }
        /// <summary>
        /// Gets and sets the end timecode for the trimmed video. A timecode of zero frames
        /// means the trim extends to the end of the video.
        /// </summary>
        public Dvd.SmpteTimecode TrimEndTimecode
        {
            get
            {
                return _trimEndTimecode;
            }
            internal set
            {
                _trimEndTimecode = value;
            }
        }
        /// <summary>
        /// Gets and sets the end timecode for the trimmed video and is based on the OutputFramerate.
        /// A timecode of zero frames means the trim extends to the end of the video.
        /// </summary>
        public Dvd.SmpteTimecode TrimOutputEndTimecode
        {
            get
            {
                return _trimOutputEndTimecode;
            }
            internal set
            {
                _trimOutputEndTimecode = value;
            }
        }
        /// <summary>
        /// Gets and sets the start timecode where trimming will begin and is based on the OutputFramerate.
        /// </summary>
        public Dvd.SmpteTimecode TrimOutputStartTimecode
        {
            get
            {
                return _trimOutputStartTimecode;
            }
            internal set
            {
                _trimOutputStartTimecode = value;
            }
        }
        /// <summary>
        /// Gets and sets the start timecode where trimming will begin.
        /// </summary>
        public Dvd.SmpteTimecode TrimStartTimecode
        {
            get
            {
                return _trimStartTimecode;
            }
            internal set
            {
                _trimStartTimecode = value;
            }
        }
        /// <summary>
        /// Gets and sets the video type.
        /// </summary>
        public VideoType VideoType
        {
            get
            {
                return _videoType;
            }
            internal set
            {
                _videoType = value;
            }
        }
        /// <summary>
        /// Gets and sets the VideoType percentage.
        /// </summary>
        public double VideoTypePercentage
        {
            get
            {
                return _videoTypePercentage;
            }
            internal set
            {
                _videoTypePercentage = value;
            }
        }
        /// <summary>
        /// Gets and sets the x264 input tuning.
        /// </summary>
        public Tools.X264.InputTuning X264InputTuning
        {
            get
            {
                return _x264InputTuning;
            }
            internal set
            {
                _x264InputTuning = value;
            }
        }
        
        #endregion

        #region Methods

        /// <summary>
        /// Clears internal values.
        /// </summary>
        public void Clear()
        {
            _audioTracks.Clear();
            _baseFilename = string.Empty;
            _bFrameCount = 0;
            _crop = CropMode.Auto;
            _cropAspectRatio = VideoAspectRatio.Aspect_1_78;
            _cropBottom = 0;
            _cropLeft = 0;
            _cropRight = 0;
            _cropTop = 0;
            _displayAspectRatio = VideoAspectRatio.Aspect_1_78;
            _duration = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
            _endTime = DateTime.Now;
            _fieldOrder = VideoFieldOrder.TopFieldFirst;
            _fileLength = 0;
            _frameCount = 0;
            _framerate = VideoFramerate.Fps30;
            _frameType = VideoFrameType.Interlaced;
            _iFrameCount = 0;
            _isAnimation = false;
            _outputFilename = string.Empty;
            _outputFrameCount = 0;
            _outputFramerate = VideoFramerate.Fps30;
            _outputHeight = 0;
            _outputWidth = 0;
            _pFrameCount = 0;
            _processing = VideoProcessingType.None;
            _processingOverride = VideoProcessingType.None;
            _processingOverrideEnabled = false;
            _trim = false;
            _trimEndTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
            _trimOutputEndTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
            _trimOutputStartTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
            _trimStartTimecode = new Dvd.SmpteTimecode(VideoFramerate.Fps30, true);
            _resizeHeight = 0;
            _resizeWidth = 0;
            _sourceFilename = string.Empty;
            _sourceHeight = 0;
            _sourceWidth = 0;
            _startTime = DateTime.Now;
            _status = JobStatus.Inactive;
            _videoType =VideoType.NtscVideo;
            _videoTypePercentage = 0;
            _x264InputTuning = Tools.X264.InputTuning.Film;
        }

        /// <summary>
        /// Returns whether the specified filename exists in the audio tracks collection.
        /// </summary>
        /// <param name="filename">The audio track filename to find.</param>
        /// <returns>True if the filename was found, otherwise false.</returns>
        public Boolean ContainsAudioTrack(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentException("filename is null or empty.");
            }

            bool result = false;
            for (Int32 i = 0; i < _audioTracks.Count; i++)
            {
                if (_audioTracks[i].Filename == filename)
                {
                    result = true;
                    break;
                }
            }

            return result;
        }

        /// <summary>
        /// Copies data from a DgindexBackgroundWorker object. CropAspectRatio is updated, but
        /// Status is not.
        /// </summary>
        /// <param name="value">A DgindexBackgroundWorker object to copy values from.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when value is null.</exception>
        public void Copy(Tools.DgindexBackgroundWorker value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            _bFrameCount = value.BFrameCount;
            _displayAspectRatio = value.DisplayAspectRatio;
            _duration = new Dvd.SmpteTimecode(value.Framerate, true);
            _duration.Add(0, 0, 0, value.FrameCount);
            _fieldOrder = value.FieldOrder;
            _fileLength = value.FileLength;
            _frameCount = value.FrameCount;
            _framerate = value.Framerate;
            _frameType = value.FrameType;
            _iFrameCount = value.IFrameCount;
            _pFrameCount = value.PFrameCount;
            _sourceFilename = value.SourceFilename;
            _sourceHeight = value.SourceHeight;
            _sourceWidth = value.SourceWidth;
            _videoType = value.VideoType;
            _videoTypePercentage = value.VideoTypePercentage;
        }

        /// <summary>
        /// Copies data from another instance to this instance, clearing any existing values.
        /// </summary>
        /// <param name="job">A JobInfo instance to copy values from.</param>
        /// <exception cref="System.ArgumentNullException">Thrown when job is null.</exception>
        public void Copy(JobInfo job)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }

            Clear();

            for (Int32 i = 0; i < job._audioTracks.Count; i++)
            {
                AudioTrackInfo newTrack = new AudioTrackInfo();
                newTrack.Copy(job._audioTracks[i]);
                _audioTracks.Add(newTrack);
            }

            _baseFilename = job._baseFilename;
            _bFrameCount = job._bFrameCount;
            _crop = job._crop;
            _cropAspectRatio = job._cropAspectRatio;
            _cropBottom = job._cropBottom;
            _cropLeft = job._cropLeft;
            _cropRight = job._cropRight;
            _cropTop = job._cropTop;
            _displayAspectRatio = job._displayAspectRatio;
            _duration = new Dvd.SmpteTimecode(job._duration);
            _endTime = new DateTime(job._endTime.Ticks);
            _fieldOrder = job._fieldOrder;
            _fileLength = job._fileLength;
            _frameCount = job._frameCount;
            _framerate = job._framerate;
            _frameType = job._frameType;
            _iFrameCount = job._iFrameCount;
            _isAnimation = job._isAnimation;
            _outputFilename = job._outputFilename;
            _outputFrameCount = job._outputFrameCount;
            _outputFramerate = job._outputFramerate;
            _outputHeight = job._outputHeight;
            _outputWidth = job._outputWidth;
            _pFrameCount = job._pFrameCount;
            _processing = job._processing;
            _processingOverride = job._processingOverride;
            _processingOverrideEnabled = job._processingOverrideEnabled;
            _trim = job._trim;
            _trimEndTimecode = new Dvd.SmpteTimecode(job._trimEndTimecode);
            _trimOutputEndTimecode = new Dvd.SmpteTimecode(job._trimOutputEndTimecode);
            _trimOutputStartTimecode = new Dvd.SmpteTimecode(job._trimOutputStartTimecode);
            _trimStartTimecode = new Dvd.SmpteTimecode(job._trimStartTimecode);
            _resizeHeight = job._resizeHeight;
            _resizeWidth = job._resizeWidth;
            _sourceFilename = job._sourceFilename;
            _sourceHeight = job._sourceHeight;
            _sourceWidth = job._sourceWidth;
            _startTime = new DateTime(job._startTime.Ticks);
            _status = job._status;
            _videoType = job.VideoType;
            _videoTypePercentage = job._videoTypePercentage;
            _x264InputTuning = job._x264InputTuning;
        }

        /// <summary>
        /// Returns the audio track delays with the specified global delay added. The results are synced by
        /// index to the results of the GetAudoTrackFilenames method.
        /// </summary>
        /// <param name="value">The global delay in milliseconds to add to all track delay values.</param>
        /// <returns>An array of Int32 values representing the audio delays in milliseconds. If there are no
        /// audio tracks, an empty array is returned.</returns>
        public Int32[] GetAudoTrackDelays(Int32 value)
        {
            Int32[] result = new Int32[_audioTracks.Count];

            for (Int32 i = 0; i < _audioTracks.Count; i++)
            {
                result[i] = _audioTracks[i].Delay + value;
            }

            return result;
        }

        /// <summary>
        /// Returns the audio track output filenames. The results are synced by index to the results of the
        /// GetAudoTrackDelays method.
        /// </summary>
        /// <returns>An array of strings containing the audio filenames. If there are no audio tracks, an
        /// empty array is returned.</returns>
        public string[] GetAudoTrackOutputFilenames()
        {
            string[] result = new string[_audioTracks.Count];

            for (Int32 i = 0; i < _audioTracks.Count; i++)
            {
                // No conversion to another format?
                if (_audioTracks[i].Format == _audioTracks[i].OutputFormat)
                {
                    result[i] = _audioTracks[i].Filename;
                }
                else
                {
                    result[i] = System.IO.Path.ChangeExtension(_audioTracks[i].Filename,
                        Utility.ConvertAudioFormatToExtension(_audioTracks[i].OutputFormat));
                }
            }

            return result;
        }

        #endregion
    }
}
