using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;

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

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

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

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

            // ウィンドウに既にコンテンツが表示されている場合は、アプリケーションの初期化を繰り返さずに、
            // ウィンドウがアクティブであることだけを確認してください
            if (rootFrame == null)
            {
                // ナビゲーション コンテキストとして動作するフレームを作成し、最初のページに移動します
                rootFrame = new Frame();

                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: 以前中断したアプリケーションから状態を読み込みます。
                }

                // フレームを現在のウィンドウに配置します
                Window.Current.Content = rootFrame;
            }

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

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

            var policyCommand = new SettingsCommand("setting", "設定", handler);
            eventArgs.Request.ApplicationCommands.Add(policyCommand);
        }

        private void OnSettingsCommand(IUICommand command)
        {
            var settingsCommand = (SettingsCommand)command;
            switch (settingsCommand.Id.ToString())
            {
                case "setting":
                    ShowSettingsFlyout();
                    break;
            }
        }

        void ShowSettingsFlyout()
        {
            var bounds = Window.Current.Bounds;
            var width = 646; // 横幅は UI ガイドラインによると 346 または 646

            // Popupオブジェクトの生成
            Popup = new Popup();
            Popup.IsLightDismissEnabled = true;
            Popup.Width = width;
            Popup.Height = bounds.Height;

            // アニメーション設定
            Popup.ChildTransitions = new Windows.UI.Xaml.Media.Animation.TransitionCollection();
            Popup.ChildTransitions.Add(new Windows.UI.Xaml.Media.Animation.PaneThemeTransition()
            {
                Edge = (SettingsPane.Edge == SettingsEdgeLocation.Right) ?
                       EdgeTransitionLocation.Right :
                       EdgeTransitionLocation.Left
            });

            // SettingsFlyout オブジェクトを生成し，Popup.Child プロパティに指定
            var pane = new SettingsFlyout();
            pane.Width = width;
            pane.Height = bounds.Height;
            Popup.Child = pane;

            // ポップアップの位置を調整し，表示
            Popup.SetValue(Canvas.LeftProperty, SettingsPane.Edge == SettingsEdgeLocation.Right ? (bounds.Width - width) : 0);
            Popup.SetValue(Canvas.TopProperty, 0);
            Popup.IsOpen = true;
        }

        /// <summary>
        /// アプリケーションの実行が中断されたときに呼び出されます。アプリケーションの状態は、
        /// アプリケーションが終了されるのか、メモリの内容がそのままで再開されるのか
        /// わからない状態で保存されます。
        /// </summary>
        /// <param name="sender">中断要求の送信元。</param>
        /// <param name="e">中断要求の詳細。</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            //TODO: アプリケーションの状態を保存してバックグラウンドの動作があれば停止します
            deferral.Complete();
        }
    }
}
