using FooEditor.Common;

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
using Windows.System;

// 分割アプリケーション テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234228 を参照してください

namespace FooEditor
{
    /// <summary>
    /// 既定の Application クラスを補完するアプリケーション固有の動作を提供します。
    /// </summary>
    sealed partial class App : Application
    {
        bool SettingRegistored;

        /// <summary>
        /// 単一アプリケーション オブジェクトを初期化します。これは、実行される作成したコードの
        /// 最初の行であり、main() または WinMain() と論理的に等価です。
        /// </summary>
        public App()
        {
            this.InitializeComponent();
            this.Suspending += OnSuspending;
            SuspensionManager.KnownTypes.Add(typeof(FileType));
        }

        /// <summary>
        /// アプリケーションがエンド ユーザーによって正常に起動されたときに呼び出されます。他のエントリ ポイントは、
        /// アプリケーションが特定のファイルを開くために呼び出されたときに
        /// 検索結果やその他の情報を表示するために使用されます。
        /// </summary>
        /// <param name="args">起動要求とプロセスの詳細を表示します。</param>
        protected override async void OnLaunched(LaunchActivatedEventArgs args)
        {
            await LunchApp(args.PreviousExecutionState);
            // 現在のウィンドウがアクティブであることを確認します
            Window.Current.Activate();
        }

        protected override async void OnFileActivated(FileActivatedEventArgs args)
        {
            Frame rootFrame = await LunchApp(args.PreviousExecutionState);
            MainPage mainPage = rootFrame.Content as MainPage;
            await mainPage.OnLoadFile(args.Files);
            // 現在のウィンドウがアクティブであることを確認します
            Window.Current.Activate();
        }

        async Task<Frame> LunchApp(ApplicationExecutionState PreviousExecutionState)
        {
            Frame rootFrame = Window.Current.Content as Frame;

            // ウィンドウに既にコンテンツが表示されている場合は、アプリケーションの初期化を繰り返さずに、
            // ウィンドウがアクティブであることだけを確認してください

            if (rootFrame == null)
            {
                // ナビゲーション コンテキストとして動作するフレームを作成し、最初のページに移動します
                rootFrame = new Frame();
                //フレームを SuspensionManager キーに関連付けます                                
                SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

                if (PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // 必要な場合のみ、保存されたセッション状態を復元します
                    try
                    {
                        await SuspensionManager.RestoreAsync();
                    }
                    catch (SuspensionManagerException)
                    {
                        //状態の復元に何か問題があります。
                        //状態がないものとして続行します
                    }
                }

                // フレームを現在のウィンドウに配置します
                Window.Current.Content = rootFrame;
            }
            if (rootFrame.Content == null)
            {
                // ナビゲーション スタックが復元されていない場合、最初のページに移動します。
                // このとき、必要な情報をナビゲーション パラメーターとして渡して、新しいページを
                // を構成します
                if (!rootFrame.Navigate(typeof(MainPage),"AllGroup"))
                {
                    throw new Exception("Failed to create initial page");
                }
            }
            if (!this.SettingRegistored)
            {
                SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
                this.SettingRegistored = true;
            }
            return rootFrame;
        }

        void OnCommandsRequested(SettingsPane settingsPane, SettingsPaneCommandsRequestedEventArgs eventArgs)
        {
            var handler = new UICommandInvokedHandler(OnSettingsCommand);

            var loader = new Windows.ApplicationModel.Resources.ResourceLoader();

            eventArgs.Request.ApplicationCommands.Add(new SettingsCommand("setting", loader.GetString("SettingCommandTitle"), handler));
            eventArgs.Request.ApplicationCommands.Add(new SettingsCommand("filetypes", loader.GetString("FileTypesCommandTitle"), handler));
            eventArgs.Request.ApplicationCommands.Add(new SettingsCommand("print", loader.GetString("PrintSettingCommandTitle"), handler));
            eventArgs.Request.ApplicationCommands.Add(new SettingsCommand("about", loader.GetString("AboutCommandTitle"), handler));
        }

        private async void OnSettingsCommand(IUICommand command)
        {
            var settingsCommand = (SettingsCommand)command;
            Windows.UI.Xaml.Controls.SettingsFlyout flyout = null;
            switch (settingsCommand.Id.ToString())
            {
                case "setting":
                    flyout = new GlobalSettingFlyout();
                    flyout.Show();
                    break;
                case "filetypes":
                    flyout = new FileTypesFlyout();
                    flyout.Show();
                    break;
                case "print":
                    flyout = new PrintSettingsFlyout();
                    flyout.Show();
                    break;
                case "about":
                    flyout = new AboutFlyout();
                    flyout.Show();
                    break;
            }
        }

        /// <summary>
        /// アプリケーションの実行が中断されたときに呼び出されます。アプリケーションの状態は、
        /// アプリケーションが終了されるのか、メモリの内容がそのままで再開されるのか
        /// わからない状態で保存されます。
        /// </summary>
        /// <param name="sender">中断要求の送信元。</param>
        /// <param name="e">中断要求の詳細。</param>
        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SuspensionManager.SaveAsync();
            await AppSettings.Current.Save();
            deferral.Complete();
        }
    }
}
