using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Packaging;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Input;
using DynamicXAPLoading.Infrastructure;

namespace DynamicXAPLoading.ViewModels
{
    [Export]
    public class MainPageViewModel : ViewModelBase, IPartImportsSatisfiedNotification 
    {
        private Uri _navigateUri;

        private DelegateCommand _navigateCommand;
        public DelegateCommand NavigateCommand
        {
            get { return _navigateCommand ?? (_navigateCommand = new DelegateCommand(OnNavigate)); }
        }

        public void OnNavigate(object parameter)
        {
            //CurrentPageName = parameter.ToString();
            var module = (ModuleEnum)parameter;
            Navigate(module);
        }

        public void Navigate(ModuleEnum module)
        {
            var uri = GetNavigateUri(module);
            if (GetNavigateUri(module) != null)
            {
                // The xap has already been loaded, so we can navigate to its page
                NavigateUri = uri;
                return;
            }

            // If we get here, the xap has not yet been loaded
            Thread.Sleep(2000); // Simulate a 2 second initial loading delay
            switch (module)
            {
                case ModuleEnum.Page1:
                    DownloadPackage("Page1.xap");
                    break;
                case ModuleEnum.Page2:
                    DownloadPackage("Page2.xap");
                    break;
                default:
                    break;
            }
        }

        private Uri GetNavigateUri(ModuleEnum moduleEnum)
        {
            return (from page in Pages
                    where page.Metadata.Module == moduleEnum
                    select new Uri(page.Metadata.NavigateUri, UriKind.Relative)).FirstOrDefault();
        }

        public void OnImportsSatisfied()
        {
            if (Pages.Count <= 0)
            {
                return;
            }
            var page = Pages[Pages.Count - 1];
            NavigateUri = new Uri(page.Metadata.NavigateUri, UriKind.Relative);
        }

        public Uri NavigateUri
        {
            get { return _navigateUri; }
            set { _navigateUri = value; this.OnPropertyChanged(p => p.NavigateUri); }
        }

        private void DownloadPackage(string path)
        {
            Package.DownloadPackageAsync(new Uri(path, UriKind.Relative), LoadPackage);
        }

        public void LoadPackage(AsyncCompletedEventArgs args, Package package)
        {
            if (!args.Cancelled && args.Error == null)
            {
                Packages.AddPackage(package);
            }
        }

        [Import]
        public PackageCatalog Packages { get; set; }

        [ImportMany(AllowRecomposition = true)]
        public ObservableCollection<Lazy<FrameworkElement, IPageMetadata>> Pages;

        public ModuleEnum ModulePage1
        {
            get { return ModuleEnum.Page1; }
        }

        public ModuleEnum ModulePage2
        {
            get { return ModuleEnum.Page2; }
        }
    }
}
