using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Extensions;
namespace MediaBrowser.Controller.Entities
{
    /// 
    /// Class Video
    /// 
    public class Video : BaseItem,
        IHasAspectRatio,
        ISupportsPlaceHolders,
        IHasMediaSources
    {
        [IgnoreDataMember]
        public string PrimaryVersionId { get; set; }
        public string[] AdditionalParts { get; set; }
        public string[] LocalAlternateVersions { get; set; }
        public LinkedChild[] LinkedAlternateVersions { get; set; }
        [IgnoreDataMember]
        public override bool SupportsPlayedStatus
        {
            get
            {
                return true;
            }
        }
        [IgnoreDataMember]
        public override bool SupportsInheritedParentImages
        {
            get
            {
                return true;
            }
        }
        [IgnoreDataMember]
        public override bool SupportsPositionTicksResume
        {
            get
            {
                var extraType = ExtraType;
                if (extraType.HasValue)
                {
                    if (extraType.Value == Model.Entities.ExtraType.Sample)
                    {
                        return false;
                    }
                    if (extraType.Value == Model.Entities.ExtraType.ThemeVideo)
                    {
                        return false;
                    }
                    if (extraType.Value == Model.Entities.ExtraType.Trailer)
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        public override string CreatePresentationUniqueKey()
        {
            if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
            {
                return PrimaryVersionId;
            }
            return base.CreatePresentationUniqueKey();
        }
        [IgnoreDataMember]
        public override bool EnableRefreshOnDateModifiedChange
        {
            get
            {
                return VideoType == VideoType.VideoFile || VideoType == VideoType.Iso;
            }
        }
        [IgnoreDataMember]
        public override bool SupportsThemeMedia
        {
            get { return true; }
        }
        /// 
        /// Gets or sets the timestamp.
        /// 
        /// The timestamp.
        public TransportStreamTimestamp? Timestamp { get; set; }
        /// 
        /// Gets or sets the subtitle paths.
        /// 
        /// The subtitle paths.
        public string[] SubtitleFiles { get; set; }
        /// 
        /// Gets or sets a value indicating whether this instance has subtitles.
        /// 
        /// true if this instance has subtitles; otherwise, false.
        public bool HasSubtitles { get; set; }
        public bool IsPlaceHolder { get; set; }
        public bool IsShortcut { get; set; }
        public string ShortcutPath { get; set; }
        /// 
        /// Gets or sets the default index of the video stream.
        /// 
        /// The default index of the video stream.
        public int? DefaultVideoStreamIndex { get; set; }
        /// 
        /// Gets or sets the type of the video.
        /// 
        /// The type of the video.
        public VideoType VideoType { get; set; }
        /// 
        /// Gets or sets the type of the iso.
        /// 
        /// The type of the iso.
        public IsoType? IsoType { get; set; }
        /// 
        /// Gets or sets the video3 D format.
        /// 
        /// The video3 D format.
        public Video3DFormat? Video3DFormat { get; set; }
        public string[] GetPlayableStreamFileNames()
        {
            var videoType = VideoType;
            if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.BluRay)
            {
                videoType = VideoType.BluRay;
            }
            else if (videoType == VideoType.Iso && IsoType == Model.Entities.IsoType.Dvd)
            {
                videoType = VideoType.Dvd;
            }
            else
            {
                return new string[] { };
            }
            return MediaEncoder.GetPlayableStreamFileNames(Path, videoType);
        }
        /// 
        /// Gets or sets the aspect ratio.
        /// 
        /// The aspect ratio.
        public string AspectRatio { get; set; }
        public Video()
        {
            AdditionalParts = EmptyStringArray;
            LocalAlternateVersions = EmptyStringArray;
            SubtitleFiles = EmptyStringArray;
            LinkedAlternateVersions = EmptyLinkedChildArray;
        }
        public override bool CanDownload()
        {
            if (VideoType == VideoType.Dvd || VideoType == VideoType.BluRay)
            {
                return false;
            }
            var locationType = LocationType;
            return locationType != LocationType.Remote &&
                   locationType != LocationType.Virtual;
        }
        [IgnoreDataMember]
        public override bool SupportsAddingToPlaylist
        {
            get { return true; }
        }
        [IgnoreDataMember]
        public int MediaSourceCount
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
                {
                    var item = LibraryManager.GetItemById(PrimaryVersionId) as Video;
                    if (item != null)
                    {
                        return item.MediaSourceCount;
                    }
                }
                return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1;
            }
        }
        [IgnoreDataMember]
        public bool IsStacked
        {
            get { return AdditionalParts.Length > 0; }
        }
        [IgnoreDataMember]
        public bool HasLocalAlternateVersions
        {
            get { return LocalAlternateVersions.Length > 0; }
        }
        public IEnumerable GetAdditionalPartIds()
        {
            return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        public IEnumerable GetLocalAlternateVersionIds()
        {
            return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
        }
        [IgnoreDataMember]
        public override SourceType SourceType
        {
            get
            {
                if (IsActiveRecording())
                {
                    return SourceType.LiveTV;
                }
                return base.SourceType;
            }
        }
        protected bool IsActiveRecording()
        {
            return LiveTvManager.GetActiveRecordingInfo(Path) != null;
        }
        public override bool CanDelete()
        {
            if (IsActiveRecording())
            {
                return false;
            }
            return base.CanDelete();
        }
        [IgnoreDataMember]
        public bool IsCompleteMedia
        {
            get { return !IsActiveRecording(); }
        }
        [IgnoreDataMember]
        protected virtual bool EnableDefaultVideoUserDataKeys
        {
            get
            {
                return true;
            }
        }
        public override List GetUserDataKeys()
        {
            var list = base.GetUserDataKeys();
            if (EnableDefaultVideoUserDataKeys)
            {
                if (ExtraType.HasValue)
                {
                    var key = this.GetProviderId(MetadataProviders.Tmdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                    key = this.GetProviderId(MetadataProviders.Imdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, GetUserDataKey(key));
                    }
                }
                else
                {
                    var key = this.GetProviderId(MetadataProviders.Imdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, key);
                    }
                    key = this.GetProviderId(MetadataProviders.Tmdb);
                    if (!string.IsNullOrWhiteSpace(key))
                    {
                        list.Insert(0, key);
                    }
                }
            }
            return list;
        }
        private string GetUserDataKey(string providerId)
        {
            var key = providerId + "-" + ExtraType.ToString().ToLower();
            // Make sure different trailers have their own data.
            if (RunTimeTicks.HasValue)
            {
                key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
            }
            return key;
        }
        public IEnumerable