using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using Aurora.Design.Components.NavigationMenu;
using Aurora.Design.Views.MainView;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Aurora.Models.Media;
using Aurora.Design.Components.MediaPlayer;
namespace Aurora.Design.Views.Main
{
///
/// Delegate for updating player metadata
///
///
public delegate void SetPlayerMetadataDelegate(BaseMedia media);
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainView : MasterDetailPage, IDisposable
{
private Dictionary _viewModels;
private BaseViewModel _lastViewModel;
public MainView()
{
InitializeComponent();
BindingContext = new MainViewModel();
_viewModels = new Dictionary();
MasterPage.ListView.ItemSelected += OnNavItemSelected;
Appearing += OnAppearing;
}
public void Dispose()
{
Appearing -= OnAppearing;
}
///
/// Event handler for side bar items being selected
///
///
///
private void OnNavItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as NavigationItem;
if (item == null)
return;
var view = (View)Activator.CreateInstance(item.TargetType);
//Check if we have an instantiated viewModel
BaseViewModel vm = new BaseViewModel();
if (_viewModels.ContainsKey(item.Id))
{
_viewModels.TryGetValue(item.Id, out vm);
}
else
{
if (item.TargetViewModelType.BaseType != typeof(BaseViewModel))
{
throw new InvalidOperationException("TargetViewModel field must be of type BaseViewModel");
}
//Instantiate new view model
vm = (BaseViewModel)Activator.CreateInstance(item.TargetViewModelType);
_viewModels.Add(item.Id, vm);
}
//Activate viewmodel
vm.OnActive();
//Deactivate last viewModel
_lastViewModel.OnInactive();
//Unasign deactivating vm
UnassignPlayerControls(_lastViewModel);
//Assign viewModel
_lastViewModel = vm;
view.BindingContext = vm;
//Assign player controls to viewmodel
AssignPlayerControls(vm);
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view;
MasterPage.ListView.SelectedItem = null;
}
///
/// Event handler for page appearing.
///
/// The object that fired the event.
/// The event arguments
private void OnAppearing(object sender, EventArgs args)
{
//Set initial view from first item in list
ObservableCollection screenList = (ObservableCollection)MasterPage.ListView.ItemsSource;
//Assign viewModel
NavigationItem firstNavItem = screenList.FirstOrDefault().FirstOrDefault();
var view = (View)Activator.CreateInstance(firstNavItem.TargetType);
BaseViewModel vm = new BaseViewModel();
if (_viewModels.ContainsKey(firstNavItem.Id))
{
_viewModels.TryGetValue(firstNavItem.Id, out vm);
}
else
{
//Instantiate new view model
vm = (BaseViewModel)Activator.CreateInstance(firstNavItem.TargetViewModelType);
_viewModels.Add(firstNavItem.Id, vm);
}
view.BindingContext = vm;
_lastViewModel = vm;
AssignPlayerControls(vm);
vm.OnActive();
ContentPresenter viewContent = (ContentPresenter)ContentPage.Content.FindByName("ViewContent");
viewContent.Content = view;
MasterPage.ListView.SelectedItem = screenList.FirstOrDefault();
}
///
/// Unassign setplayer delegate to prevent vms from changing player info when inactive
///
///
private void UnassignPlayerControls(BaseViewModel vm)
{
vm.SetPlayerMetadata = null;
}
///
/// Assign main views music player controls to a view model
///
/// BaseViewModel to assign controls to
private void AssignPlayerControls(BaseViewModel vm)
{
Player player = (Player)ContentPage.FindByName("Player");
player.PlayButtonCommand = new Command(vm.OnPlayExecute, vm.CanPlayExecute);
player.NextButtonCommand = new Command(vm.OnNextExecute, vm.CanNextExecute);
player.PreviousButtonCommand = new Command(vm.OnPreviousExecute, vm.CanPreviousExecute);
//Assign SetPlayer delegate
vm.SetPlayerMetadata = SetPlayerDelegate;
}
private void SetPlayerDelegate(BaseMedia media)
{
Player player = (Player)ContentPage.FindByName("Player");
if (media.Metadata is AudioMetadata)
{
AudioMetadata meta = (AudioMetadata)media.Metadata;
player.ArtistName = meta.Artist;
player.SongTitle = meta.Title;
}
}
}
}