using MediaBrowser.Model.DTO;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Net;
using MediaBrowser.UI.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace MediaBrowser.UI.Pages
{
///
/// Provides a base class for pages based on a folder item (list, home)
///
public abstract class BaseFolderPage : BasePage
{
///
/// Initializes a new instance of the class.
///
/// The item id.
protected BaseFolderPage(string itemId)
: base()
{
ItemId = itemId;
}
///
/// The _item id
///
private string _itemId;
///
/// Gets or sets the Id of the item being displayed
///
/// The item id.
protected string ItemId
{
get { return _itemId; }
private set
{
_itemId = value;
OnPropertyChanged("ItemId");
}
}
///
/// The _index by
///
private string _indexBy;
///
/// Gets or sets the name of the current index function
///
/// The index by.
public string IndexBy
{
get { return _indexBy; }
private set
{
_indexBy = value;
OnPropertyChanged("IndexBy");
}
}
///
/// The _sort by
///
private string _sortBy;
///
/// Gets or sets the name of the current sort function
///
/// The sort by.
public string SortBy
{
get { return _sortBy; }
private set
{
_sortBy = value;
OnPropertyChanged("SortBy");
}
}
///
/// The _folder
///
private DtoBaseItem _folder;
///
/// Gets or sets the Folder being displayed
///
/// The folder.
public DtoBaseItem Folder
{
get { return _folder; }
set
{
_folder = value;
OnPropertyChanged("Folder");
OnFolderChanged();
ReloadChildren();
}
}
///
/// If wrap panels are being used this will get the orientation that should be used, based on scroll direction
///
/// The wrap panel orientation.
public Orientation WrapPanelOrientation
{
get
{
return DisplayPreferences.ScrollDirection == ScrollDirection.Horizontal ? Orientation.Vertical : Orientation.Horizontal;
}
}
///
/// The _display preferences
///
private DisplayPreferences _displayPreferences;
///
/// Gets of sets the current DisplayPreferences
///
/// The display preferences.
public DisplayPreferences DisplayPreferences
{
get { return _displayPreferences; }
private set
{
_displayPreferences = value;
// If the page is using it's own image type and not honoring the DisplayPreferences setting, set it now
if (_displayPreferences != null && FixedImageType.HasValue)
{
_displayPreferences.PrimaryImageType = FixedImageType.Value;
}
NotifyDisplayPreferencesChanged();
}
}
///
/// The _children
///
private ItemsResult _children;
///
/// Gets or sets the children of the Folder being displayed
///
/// The children.
public ItemsResult Children
{
get { return _children; }
private set
{
_children = value;
OnPropertyChanged("Children");
ChildCount = _children.TotalRecordCount;
OnChildrenChanged();
DisplayChildren = DtoBaseItemViewModel.GetObservableItems(Children.Items, AveragePrimaryImageAspectRatio, DisplayPreferences);
}
}
///
/// The _display children
///
private ObservableCollection _displayChildren;
///
/// Gets the actual children that should be displayed.
/// Subclasses should bind to this, not Children.
///
/// The display children.
public ObservableCollection DisplayChildren
{
get { return _displayChildren; }
private set
{
_displayChildren = value;
OnPropertyChanged("DisplayChildren");
}
}
///
/// The _child count
///
private int _childCount;
///
/// Gets or sets the number of children within the Folder
///
/// The child count.
public int ChildCount
{
get { return _childCount; }
private set
{
_childCount = value;
OnPropertyChanged("ChildCount");
}
}
///
/// If the page is using it's own image type and not honoring the DisplayPreferences setting, it should return it here
///
/// The type of the fixed image.
protected virtual ImageType? FixedImageType
{
get { return null; }
}
///
/// The _average primary image aspect ratio
///
private double _averagePrimaryImageAspectRatio;
///
/// Gets or sets the average primary image aspect ratio for all items
///
/// The average primary image aspect ratio.
public double AveragePrimaryImageAspectRatio
{
get { return _averagePrimaryImageAspectRatio; }
private set
{
_averagePrimaryImageAspectRatio = value;
OnPropertyChanged("AveragePrimaryImageAspectRatio");
}
}
///
/// Gets the aspect ratio that should be used based on a given ImageType
///
/// Type of the image.
/// System.Double.
public double GetAspectRatio(ImageType imageType)
{
return GetAspectRatio(imageType, AveragePrimaryImageAspectRatio);
}
///
/// Gets the aspect ratio that should be used based on a given ImageType
///
/// Type of the image.
/// The average primary image aspect ratio.
/// System.Double.
public static double GetAspectRatio(ImageType imageType, double averagePrimaryImageAspectRatio)
{
switch (imageType)
{
case ImageType.Art:
return 1.777777777777778;
case ImageType.Backdrop:
return 1.777777777777778;
case ImageType.Banner:
return 5.414285714285714;
case ImageType.Disc:
return 1;
case ImageType.Logo:
return 1.777777777777778;
case ImageType.Primary:
return averagePrimaryImageAspectRatio;
case ImageType.Thumb:
return 1.777777777777778;
default:
return 1;
}
}
///
/// Called when [property changed].
///
/// The name.
public async override void OnPropertyChanged(string name)
{
base.OnPropertyChanged(name);
// Reload the Folder when the itemId changes
if (name.Equals("ItemId"))
{
await ReloadFolder();
}
}
///
/// Reloads the folder
///
/// Task.
private async Task ReloadFolder()
{
try
{
if (string.IsNullOrEmpty(ItemId))
{
Folder = await App.Instance.ApiClient.GetRootFolderAsync(App.Instance.CurrentUser.Id);
}
else
{
Folder = await App.Instance.ApiClient.GetItemAsync(ItemId, App.Instance.CurrentUser.Id);
}
}
catch (HttpException)
{
App.Instance.ShowDefaultErrorMessage();
}
}
///
/// Gets called anytime the Folder gets refreshed
///
protected virtual void OnFolderChanged()
{
SetBackdrops(Folder);
DisplayPreferences = Folder.DisplayPreferences;
if (DisplayPreferences.RememberIndexing)
{
IndexBy = DisplayPreferences.IndexBy;
}
if (DisplayPreferences.RememberSorting)
{
SortBy = DisplayPreferences.SortBy ?? Folder.SortOptions.FirstOrDefault();
}
else if (string.IsNullOrEmpty(SortBy))
{
SortBy = Folder.SortOptions.FirstOrDefault();
}
}
///
/// Gets called anytime the Children get refreshed
///
protected virtual void OnChildrenChanged()
{
AveragePrimaryImageAspectRatio = DtoBaseItemViewModel.GetAveragePrimaryImageAspectRatio(Children.Items);
if (DisplayPreferences != null)
{
DisplayPreferences.PrimaryImageWidth = Convert.ToInt32(DisplayPreferences.PrimaryImageHeight * GetAspectRatio(DisplayPreferences.PrimaryImageType));
}
NotifyDisplayPreferencesChanged();
}
///
/// Reloads the Folder's children
///
/// Task.
public async Task ReloadChildren()
{
var query = new ItemQuery
{
ParentId = Folder.Id,
Fields = new[] {
ItemFields.UserData,
ItemFields.PrimaryImageAspectRatio
},
UserId = App.Instance.CurrentUser.Id,
IndexBy = IndexBy,
DynamicSortBy = SortBy
};
try
{
Children = await App.Instance.ApiClient.GetItemsAsync(query);
}
catch (HttpException)
{
App.Instance.ShowDefaultErrorMessage();
}
}
///
/// Gets called anytime a DisplayPreferences property is updated
///
public virtual void NotifyDisplayPreferencesChanged()
{
OnPropertyChanged("DisplayPreferences");
if (DisplayChildren != null)
{
// Notify all of the child view models
foreach (var child in DisplayChildren)
{
child.AveragePrimaryImageAspectRatio = AveragePrimaryImageAspectRatio;
child.NotifyDisplayPreferencesChanged();
}
}
OnPropertyChanged("WrapPanelOrientation");
}
///
/// Changes the sort option on the page
///
/// The option.
/// Task.
public async Task UpdateSortOption(string option)
{
var tasks = new List();
SortBy = option;
if (DisplayPreferences.RememberSorting)
{
DisplayPreferences.SortBy = option;
NotifyDisplayPreferencesChanged();
tasks.Add(Task.Run(async () =>
{
try
{
await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences);
}
catch
{
App.Instance.ShowDefaultErrorMessage();
}
}));
}
tasks.Add(ReloadChildren());
await Task.WhenAll(tasks);
}
///
/// Changes the index option on the page
///
/// The option.
/// Task.
public async Task UpdateIndexOption(string option)
{
var tasks = new List();
IndexBy = option;
if (DisplayPreferences.RememberIndexing)
{
DisplayPreferences.IndexBy = option;
NotifyDisplayPreferencesChanged();
tasks.Add(Task.Run(async () =>
{
try
{
await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences);
}
catch
{
App.Instance.ShowDefaultErrorMessage();
}
}));
}
tasks.Add(ReloadChildren());
await Task.WhenAll(tasks);
}
///
/// Updates the index of the remember.
///
/// if set to true [remember].
/// Task.
public async Task UpdateRememberIndex(bool remember)
{
DisplayPreferences.RememberIndexing = remember;
if (remember)
{
DisplayPreferences.IndexBy = IndexBy;
}
await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences);
}
///
/// Updates the remember sort.
///
/// if set to true [remember].
/// Task.
public async Task UpdateRememberSort(bool remember)
{
DisplayPreferences.RememberSorting = remember;
if (remember)
{
DisplayPreferences.SortBy = SortBy;
}
await App.Instance.ApiClient.UpdateDisplayPreferencesAsync(App.Instance.CurrentUser.Id, Folder.Id, DisplayPreferences);
}
}
}