using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;

using Windows.Foundation;
using Windows.Foundation.Collections;

using Windows.Storage;
using Windows.Storage.Pickers;
using Windows.UI.Popups;
using Windows.UI.ViewManagement;

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 C1.Xaml.Document;
using C1.Xaml.FlexViewer;

namespace FlexPdfViewer
{
    public sealed partial class MainPage : Page
    {
        const string c_CheckedGlyph = "\xE0A2";
        const string c_UncheckedGlyph = "\xE003";
        C1PdfDocumentSource _pdfDocSource;
        ToolMenuItem _closeToolItem;
        ToolMenuItem _useSystemRenderingToolItem;
        ApplicationView _appView;
        bool _useSystemRendering = true;

        public MainPage()
        {
            this.InitializeComponent();

            this.Unloaded += MainPage_Unloaded;
            this.Loaded += MainPage_Loaded;

            flexViewer.PrepareToolMenu += FlexViewer_PrepareToolMenu;
            flexViewer.NavigateToCustomTool += FlexViewer_NavigateToCustomTool;
            _appView = ApplicationView.GetForCurrentView();
        }

        internal void App_Suspending()
        {
            flexViewer.Pane.HandleSuspending();
        }

        void FlexViewer_PrepareToolMenu(object sender, EventArgs e)
        {
            var items = ((C1FlexViewer)sender).ToolMenuItems;
            for (int i = items.Count - 1; i >= 0; i--)
            {
                switch (items[i].Tool)
                {
                    case FlexViewerTool.Outlines:
                    case FlexViewerTool.PageSettings:
                    case FlexViewerTool.Parameters:
                        items.RemoveAt(i);
                        break;
                }
            }
            items.Insert(0, new ToolMenuItem("\xE155", FlexViewerTool.CustomTool1, Strings.OpenToolLabel));
            _useSystemRenderingToolItem = new ToolMenuItem(c_CheckedGlyph, FlexViewerTool.CustomTool3, Strings.UseSystemRenderingToolLabel);
            items.Add(_useSystemRenderingToolItem);
            _closeToolItem = new ToolMenuItem("\xE10A", FlexViewerTool.CustomTool2, Strings.CloseToolLabel);
            items.Add(_closeToolItem);
        }

        async void FlexViewer_NavigateToCustomTool(object sender, CustomToolEventArgs e)
        {
            if (e.Tool == FlexViewerTool.CustomTool1)
            {
                await OpenPdf();
            }
            else if (e.Tool == FlexViewerTool.CustomTool2)
            {
                ClosePdf();
            }
            else if (e.Tool == FlexViewerTool.CustomTool3)
            {
                await ChangeUseSystemRendering();
            }
        }

        void MainPage_Unloaded(object sender, RoutedEventArgs e)
        {
            ClosePdf();
        }

        async void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            var f = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/C1XapOptimizer.pdf"));
            await LoadPdf(f);
        }

        void CheckBox_Changed(object sender, RoutedEventArgs e)
        {
            if (revealModeCheckBox.IsChecked == true)
            {
                passwordBox.PasswordRevealMode = PasswordRevealMode.Visible;
            }
            else
            {
                passwordBox.PasswordRevealMode = PasswordRevealMode.Hidden;
            }
        }

        async Task ChangeUseSystemRendering()
        {
            _closeToolItem.IsEnabled = false;
            _useSystemRenderingToolItem.IsEnabled = false;
            try
            {
                _useSystemRendering = !_useSystemRendering;
                _useSystemRenderingToolItem.Glyph = _useSystemRendering ? c_CheckedGlyph : c_UncheckedGlyph;
                if (_pdfDocSource != null)
                {
                    //System.Diagnostics.Debug.WriteLine("BEFORE ChangeUseSystemRendering");
                    _pdfDocSource.UseSystemRendering = _useSystemRendering;
                    await _pdfDocSource.GenerateAsync();
                    //System.Diagnostics.Debug.WriteLine("AFTER  ChangeUseSystemRendering");
                }
            }
            finally
            {
                _closeToolItem.IsEnabled = true;
                _useSystemRenderingToolItem.IsEnabled = true;
            }
        }

        async Task LoadPdf(StorageFile file)
        {
            if (_pdfDocSource == null)
            {
                _pdfDocSource = new C1PdfDocumentSource();
            }
            flexViewer.DocumentSource = null;
            _closeToolItem.IsEnabled = false;
            _useSystemRenderingToolItem.IsEnabled = false;
            try
            {
                try
                {
                    _pdfDocSource.UseSystemRendering = _useSystemRendering;
                    await _pdfDocSource.LoadFromFileAsync(file);
                }
                catch (PdfPasswordException)
                {
                    fileNameBlock.Text = file.Name;
                    passwordBox.Password = string.Empty;
                    bool passed = false;
                    while (!passed)
                    {
                        var res = await passwordDialog.ShowAsync();
                        if (res == ContentDialogResult.Primary)
                        {
                            try
                            {
                                await _pdfDocSource.LoadFromFileAsync(file, passwordBox.Password);
                                passed = true;
                            }
                            catch (PdfPasswordException)
                            {
                            }
                        }
                        else
                        {
                            ClosePdf();
                            return;
                        }
                    }
                }
                _appView.Title = file.DisplayName;
            }
            catch (Exception ex)
            {
                ClosePdf();
                MessageDialog md = new MessageDialog(string.Format(Strings.PdfErrorFormat, file.Name, ex.Message), Strings.ErrorTitle);
                await md.ShowAsync();
                return;
            }
            finally
            {
                _closeToolItem.IsEnabled = true;
                _useSystemRenderingToolItem.IsEnabled = true;
            }
            flexViewer.DocumentSource = _pdfDocSource;
        }

        void ClosePdf()
        {
            if (_pdfDocSource != null)
            {
                flexViewer.DocumentSource = null;
                _pdfDocSource.Dispose();
                _pdfDocSource = null;

                _closeToolItem.IsEnabled = false;
                _appView.Title = string.Empty;
            }
        }

        async Task OpenPdf()
        {
            FileOpenPicker fop = new FileOpenPicker();
            fop.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
            fop.ViewMode = PickerViewMode.List;
            fop.FileTypeFilter.Clear();
            fop.FileTypeFilter.Add(".pdf");
            StorageFile file = await fop.PickSingleFileAsync();
            if (file != null)
            {
                await LoadPdf(file);
            }
        }
    }
}
