using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Input;
using Windows.ApplicationModel.Store;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

// 基本ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234237 を参照してください

namespace FooEditor
{
    /// <summary>
    /// 多くのアプリケーションに共通の特性を指定する基本ページ。
    /// </summary>
    public sealed partial class HomePage : FooEditor.Common.LayoutAwarePage
    {
        HomePageViewModel vm;
        LicenseInformation licenseInfomation;

        public HomePage()
        {
            this.InitializeComponent();

            this.vm = new HomePageViewModel();

            this.DataContext = this.vm;

#if DEBUG
            this.licenseInfomation = CurrentAppSimulator.LicenseInformation;
            this.ad1.ApplicationId = "d25517cb-12d4-4699-8bdc-52040c712cab";
            this.ad1.AdUnitId = "10043134";
#else
            this.licenseInfomation = CurrentApp.LicenseInformation;
            this.ad1.ApplicationId = "10d877d4-6c21-42fe-8b89-9c8001a31f29";
            this.ad1.AdUnitId = "10076683";
#endif

            this.licenseInfomation.LicenseChanged += LicenseInformation_LicenseChanged;

            this.LicenseInformation_LicenseChanged();
        }

        void LicenseInformation_LicenseChanged()
        {
            this.ad1.Visibility = this.licenseInfomation.IsTrial ? Visibility.Visible : Visibility.Collapsed;
        }

        /// <summary>
        /// このページには、移動中に渡されるコンテンツを設定します。前のセッションからページを
        /// 再作成する場合は、保存状態も指定されます。
        /// </summary>
        /// <param name="navigationParameter">このページが最初に要求されたときに
        /// <see cref="Frame.Navigate(Type, Object)"/> に渡されたパラメーター値。
        /// </param>
        /// <param name="pageState">前のセッションでこのページによって保存された状態の
        /// ディクショナリ。ページに初めてアクセスするとき、状態は null になります。</param>
        protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            await this.vm.LoadState((MainPageViewModel)navigationParameter);
        }

        /// <summary>
        /// アプリケーションが中断される場合、またはページがナビゲーション キャッシュから破棄される場合、
        /// このページに関連付けられた状態を保存します。値は、
        /// <see cref="SuspensionManager.SessionState"/> のシリアル化の要件に準拠する必要があります。
        /// </summary>
        /// <param name="pageState">シリアル化可能な状態で作成される空のディクショナリ。</param>
        protected override void SaveState(Dictionary<String, Object> pageState)
        {
        }

    }

    class HomePageViewModel : ViewModelBase
    {
        public HomePageViewModel()
        {
            this.Items = new ObservableCollection<GroupItems>();
        }

        ObservableCollection<GroupItems> _Items;
        public ObservableCollection<GroupItems> Items
        {
            get { return this._Items; }
            private set
            {
                this._Items = value;
                this.OnPropertyChanged();
            }
        }

        public async Task LoadState(MainPageViewModel main)
        {
            var loader = new Windows.ApplicationModel.Resources.ResourceLoader();

            DelegateCommand<object> cmd;
            GroupItems item = new GroupItems(loader.GetString("NewListGroup"));

            cmd = new DelegateCommand<object>(async (param) =>
            {
                await main.CreateDocument((FileType)param);
            });
            foreach (FileType type in AppSettings.Current.FileTypeCollection)
                item.items.Add(new ButtonItem(type.DocumentTypeName, cmd, type));

            this.Items.Add(item);

            item = new GroupItems(loader.GetString("RecentListGroup"));

            cmd = new DelegateCommand<object>(async (param) =>
            {
                FileOpenPicker openPicker = new FileOpenPicker();

                openPicker.ViewMode = PickerViewMode.List;

                openPicker.FileTypeFilter.Add("*");

                openPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
                StorageFile file = await openPicker.PickSingleFileAsync();
                if (file != null)
                {
                    await main.CreateDocument(file);
                    StorageApplicationPermissions.MostRecentlyUsedList.Add(file, "mrufile");
                }
            });
            item.items.Add(new ButtonItem(loader.GetString("OpenButton"), cmd));

            await this.GetRecentFiles(main,item.items);

            this.Items.Add(item);
        }

        private async Task GetRecentFiles(MainPageViewModel main,ObservableCollection<IItem> items)
        {
            AccessListEntryView mruEntries = StorageApplicationPermissions.MostRecentlyUsedList.Entries;
            if (mruEntries.Count > 0)
            {
                var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
                foreach (AccessListEntry entry in mruEntries)
                {
                    try
                    {
                        String token = entry.Token;
                        StorageFile mrudFile = await StorageApplicationPermissions.MostRecentlyUsedList.GetFileAsync(token);
                        DelegateCommand<StorageFile> cmd = new DelegateCommand<StorageFile>(async (param) =>
                        {
                            await main.CreateDocument(param);
                        });
                        items.Add(new FileItem(mrudFile, cmd));
                    }
                    catch (FileNotFoundException)
                    {
                    }
                }
            }
        }
    }

    public class ItemGridViewTemplateSelector : DataTemplateSelector
    {
        public DataTemplate ButtonItem { get; set; }
        public DataTemplate RecentFileItem { get; set; }
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            var data = item as IItem;
            if (data.IsButton)
            {
                return this.ButtonItem;
            }
            return this.RecentFileItem;
        }
    }
    
    public class GroupItems
    {
        private string _title;

        public string title
        {
            get
            {
                return _title;
            }
        }

        private ObservableCollection<IItem> _items = new ObservableCollection<IItem>();

        public ObservableCollection<IItem> items
        {
            get
            {
                return _items;
            }
        }
        public GroupItems(string title)
        {
            this._title = title;
        }
    }
    
    public interface IItem
    {
        bool IsButton
        {
            get;
        }
    }
    public struct ButtonItem : IItem
    {
        string _Title;
        ICommand _Command;
        FileType _DocumentType;
        public string Title
        {
            get
            {
                return _Title;
            }
        }
        public bool IsButton
        {
            get
            {
                return true;
            }
        }
        public ICommand Command
        {
            get
            {
                return _Command;
            }
        }
        public FileType DocumentType
        {
            get
            {
                return _DocumentType;
            }
        }
        public ButtonItem(string title, ICommand cmd,FileType doctype = null)
        {
            this._Command = cmd;
            this._Title = title;
            this._DocumentType = doctype;
        }
    }
    public struct FileItem : IItem
    {
        StorageFile _File;
        ICommand _Command;
        public StorageFile File
        {
            get
            {
                return _File;
            }
        }
        public bool IsButton
        {
            get
            {
                return false;
            }
        }
        public ICommand Command
        {
            get
            {
                return _Command;
            }
        }
        public FileItem(StorageFile file, DelegateCommand<StorageFile> cmd)
        {
            this._Command = cmd;
            this._File = file;
        }
    }
}
