using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.ComponentModel;
using System.Globalization;

using PDFViewWPFTestCS.Controls;

using pdftron;
using pdftron.PDF;
using pdftron.PDF.Tools;

namespace PDFViewWPFTestCS
{
    /// <summary>
    /// Interaction logic for AnnotationPropertiesControl.xaml
    /// </summary>
    public partial class AnnotationsControl : UserControl
    {
        internal int i_toolmode;
        PDFViewWPFTestCS.Controls.ColorPicker m_picker_line;
        PDFViewWPFTestCS.Controls.ColorPicker m_picker_fill;
        PDFViewWPFTestCS.Controls.ColorPicker m_picker_color;
        bool m_control_down;
        bool m_shift_down;
        private int i_currentSelected;
        private bool m_selection_from_ToolManager = false;

        #region Property

        public PDFViewWPF CurrentViewer { get; set; }
        public pdftron.PDF.Tools.ToolManager CurrentToolManager { get; set; }
        public Annot SelectedAnnotation { get; set; }
        public pdftron.PDF.Annots.Markup CurrentMarkup { get; set; }
        public int PageNumber { get; set; }

        #endregion

        private List<PageAnnot> m_annot_list;

        private struct PageAnnot
        {
            public int pagenum;
            public Annot annot;

            public PageAnnot(int pagenum, Annot annot)
            {
                this.pagenum = pagenum;
                this.annot = annot;
            }
        }

        public AnnotationsControl()
        {
            InitializeComponent();

            m_picker_line = new PDFViewWPFTestCS.Controls.ColorPicker();
            line_color_picker.Children.Add(m_picker_line);
            m_picker_line.ValueChanged += new RoutedEventHandler(m_picker_line_ValueChanged);
            m_picker_fill = new PDFViewWPFTestCS.Controls.ColorPicker();
            fill_color_picker.Children.Add(m_picker_fill);
            m_picker_fill.ValueChanged += new RoutedEventHandler(m_picker_fill_ValueChanged);
            m_picker_color = new PDFViewWPFTestCS.Controls.ColorPicker();
            text_markup_color_picker.Children.Add(m_picker_color);
            m_picker_color.ValueChanged += new RoutedEventHandler(m_picker_color_ValueChanged);            
        }

        public void EnableAnnotationTools(PDFViewWPF view, ToolManager toolManager)
        {
            CurrentViewer = view;
            CurrentToolManager = toolManager;
            ctrl_viewer.IsEnabled = true;
            LoadAnnotList();
            m_annots.IsExpanded = true;


            CurrentToolManager.SelectedAnnotationsChanged += new AnnotationSelectionChanged(CurrentToolManager_SelectedAnnotationsChanged);
            CurrentToolManager.AnnotationAdded += new AnnotationModificationHandler(CurrentToolManager_AnnotationAdded);
            CurrentToolManager.AnnotationRemoved += new AnnotationModificationHandler(CurrentToolManager_AnnotationRemoved);
            CurrentToolManager.AnnotationEdited += new AnnotationModificationHandler(CurrentToolManager_AnnotationEdited);
            CurrentToolManager.ToolModeChanged += new ToolModeChangedHandler(CurrentToolManager_ToolModeChanged);
            CurrentToolManager.AnnotationNoteChanged += CurrentToolManager_AnnotationNoteChanged;

            //CurrentViewer.SelectedAnnotChanged += new RoutedEventHandler(CurrentViewer_SelectedAnnotChanged);
            //CurrentViewer.AnnotationAdded += new RoutedEventHandler(CurrentViewer_AnnotationAdded);
            //CurrentViewer.AnnotationRemoved += new RoutedEventHandler(CurrentViewer_AnnotationRemoved);
            //CurrentViewer.AnnotationCommentsChanged += new RoutedEventHandler(CurrentViewer_AnnotationCommentsChanged);
            //CurrentViewer.ToolModeChanged += new RoutedEventHandler(CurrentViewer_ToolModeChanged);
        }



        void CurrentToolManager_AnnotationEdited(Annot annotation)
        {
           
        }


        

        void CurrentToolManager_ToolModeChanged(ToolManager.ToolType newToolType)
        {
            _ChangedFromToolManager = true;
            switch (CurrentToolManager.CurrentTool.ToolMode)
            {
                case ToolManager.ToolType.e_text_annot_create:
                    listbox_annots.SelectedIndex = 0;
                    break;
                case ToolManager.ToolType.e_text_highlight:
                    listbox_annots.SelectedIndex = 1;
                    break;
                case ToolManager.ToolType.e_text_underline:
                    listbox_annots.SelectedIndex = 2;
                    break;
                case ToolManager.ToolType.e_text_strikeout:
                    listbox_annots.SelectedIndex = 3;
                    break;
                case ToolManager.ToolType.e_rect_create:
                    listbox_annots.SelectedIndex = 4;
                    break;
                case ToolManager.ToolType.e_oval_create:
                    listbox_annots.SelectedIndex = 5;
                    break;
                case ToolManager.ToolType.e_line_create:
                    listbox_annots.SelectedIndex = 6;
                    break;
                case ToolManager.ToolType.e_arrow_create:
                    listbox_annots.SelectedIndex = 7;
                    break;
                case ToolManager.ToolType.e_ink_create:
                    listbox_annots.SelectedIndex = 8;
                    break;
                default:
                    listbox_annots.SelectedIndex = -1;
                    break;
            }
            _ChangedFromToolManager = false;
        }

        void CurrentToolManager_AnnotationRemoved(Annot annotation)
        {
            LoadAnnotList();
            m_appearance.Visibility = System.Windows.Visibility.Collapsed;
            m_general.Visibility = System.Windows.Visibility.Collapsed;
        }

        void CurrentToolManager_AnnotationAdded(Annot annotation)
        {
            LoadAnnotList();
        }

        void CurrentToolManager_AnnotationNoteChanged(Annot annotation)
        {
            LoadAnnotList();
        }

        void CurrentToolManager_SelectedAnnotationsChanged()
        {
            if (CurrentToolManager.SelectedAnnotations == null)
            {
                return;
            }

            m_selection_from_ToolManager = true;

            if (CurrentToolManager.SelectedAnnotations.Count == 1)
            {
                SelectedAnnotation = CurrentToolManager.SelectedAnnotations[0];
                m_appearance.Visibility = System.Windows.Visibility.Visible;
                m_general.Visibility = System.Windows.Visibility.Visible;
                CheckAnnotType(SelectedAnnotation);
                CurrentMarkup = new pdftron.PDF.Annots.Markup(SelectedAnnotation);
                PageNumber = GetAnnotationPageNumFromSelection();

                m_annot_type_field.Text = GetAnnotType(SelectedAnnotation);

                if (LineStylePanel.Visibility == System.Windows.Visibility.Visible)
                {
                    line_style_box.SelectedIndex = DashPatternToChoice(CurrentMarkup.GetBorderStyle());
                }

                if (StrokeThicknessPanel.Visibility == System.Windows.Visibility.Visible)
                    m_thickness_slider.Value = CurrentMarkup.GetBorderStyle().width;


                m_opacity_slider.Value = CurrentMarkup.GetOpacity();

                m_subject.Text = CurrentMarkup.GetSubject();
                m_author.Text = CurrentMarkup.GetTitle();
                DateConverter dc = new DateConverter();
                m_dateCreated.Text = (string)dc.Convert(CurrentMarkup.GetCreationDates(), m_dateCreated.Text.GetType(), null, CultureInfo.CurrentCulture);
                m_dateModified.Text = (string)dc.Convert(CurrentMarkup.GetDate(), m_dateModified.Text.GetType(), null, CultureInfo.CurrentCulture);

                if (CurrentMarkup.GetType() == Annot.Type.e_Line || CurrentMarkup.GetType() == Annot.Type.e_Polyline)
                {
                    LineStyleStartConvertBack(line_begin_style_box);
                    LineStyleEndConvertBack(line_end_style_box);
                }
            }
            else
            {
                m_appearance.Visibility = System.Windows.Visibility.Collapsed;
                m_general.Visibility = System.Windows.Visibility.Collapsed;
                if (CurrentToolManager.SelectedAnnotations.Count == 0)
                    annotlistbox.UnselectAll();
                for (int i = 0; i < m_annot_list.Count; ++i)
                {
                    if (CurrentToolManager.SelectedAnnotations.Contains(m_annot_list[i].annot))
                        annotlistbox.SelectedItems.Add(annotlistbox.Items[i]);
                    else
                        annotlistbox.SelectedItems.Remove(annotlistbox.Items[i]);
                }
            }
            //else
            //{
            //    m_appearance.Visibility = System.Windows.Visibility.Collapsed;
            //    m_general.Visibility = System.Windows.Visibility.Collapsed;
            //    annotlistbox.SelectedIndex = -1;
            //}

            m_selection_from_ToolManager = false;
        }

        #region toolmode

        private bool _ChangedFromToolManager = false;
        private void listbox_annots_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!_ChangedFromToolManager && e.AddedItems.Count > 0)
            {
                i_toolmode = listbox_annots.SelectedIndex;
                switch (i_toolmode)
                {
                    case 0:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_text_annot_create); // sticky note
                        break;
                    case 1:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_text_highlight); // hightlight
                        break;
                    case 2:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_text_underline); // underline
                        break;
                    case 3:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_text_strikeout); // strikeout
                        break;
                    case 4:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_rect_create); // rectangle
                        break;
                    case 5:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_oval_create); // oval
                        break;
                    case 6:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_line_create); // line
                        break;
                    case 7:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_arrow_create); // arrow
                        break;
                    case 8:
                        CurrentToolManager.CreateTool(ToolManager.ToolType.e_ink_create); // freehand
                        break;
                }
            }
        }

        #endregion

        #region properties

        private void m_thickness_slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                Annot.BorderStyle bs = CurrentMarkup.GetBorderStyle();
                //Annot.BorderStyle bs = new Annot.BorderStyle(CurrentMarkup.GetBorderStyle().border_style, e.NewValue);
                if (bs.border_style != Annot.BorderStyle.Style.e_solid && bs.dash == null)
                    return;
                bs.width = e.NewValue;
                CurrentMarkup.SetBorderStyle(bs);
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        private void m_opacity_slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                CurrentMarkup.SetOpacity(e.NewValue);
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        void m_picker_fill_ValueChanged(object sender, RoutedEventArgs e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                if (m_picker_fill.Value == Colors.Transparent)
                    CurrentMarkup.SetInteriorColor(new ColorPt((double)m_picker_fill.Value.R / 255, (double)m_picker_fill.Value.G / 255, (double)m_picker_fill.Value.B / 255), 0);
                else
                    CurrentMarkup.SetInteriorColor(new ColorPt((double)m_picker_fill.Value.R / 255, (double)m_picker_fill.Value.G / 255, (double)m_picker_fill.Value.B / 255), 3);
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        void m_picker_line_ValueChanged(object sender, RoutedEventArgs e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                if (m_picker_line.Value == Colors.Transparent)
                    CurrentMarkup.SetColor(new ColorPt((double)m_picker_line.Value.R / 255, (double)m_picker_line.Value.G / 255, (double)m_picker_line.Value.B / 255),0);
                else
                    CurrentMarkup.SetColor(new ColorPt((double)m_picker_line.Value.R / 255, (double)m_picker_line.Value.G / 255, (double)m_picker_line.Value.B / 255));
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        void m_picker_color_ValueChanged(object sender, RoutedEventArgs e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                if (m_picker_color.Value == Colors.Transparent)
                    CurrentMarkup.SetColor(new ColorPt((double)m_picker_color.Value.R / 255, (double)m_picker_color.Value.G / 255, (double)m_picker_color.Value.B / 255), 0);
                else
                    CurrentMarkup.SetColor(new ColorPt((double)m_picker_color.Value.R / 255, (double)m_picker_color.Value.G / 255, (double)m_picker_color.Value.B / 255));
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        private void m_subject_TextChanged(object sender, TextChangedEventArgs e)
        {
        //    if (CurrentMarkup != null)
        //    {
        //        CurrentMarkup.SetSubject(m_subject.Text);
        //        LoadAnnotList();
        //    }
        }

        private void m_author_TextChanged(object sender, TextChangedEventArgs e)
        {
        //    if (CurrentMarkup != null)
        //    {
        //        CurrentMarkup.SetTitle(m_author.Text);
        //        LoadAnnotList();
        //    }
        }

        private void LineStyleStartConvertBack(ComboBox box)
        {
            pdftron.PDF.Annots.Line line = new pdftron.PDF.Annots.Line(SelectedAnnotation);
            switch (line.GetStartStyle())
            {
                case pdftron.PDF.Annots.Line.EndingStyle.e_Square:
                    box.SelectedIndex = 0;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Circle:
                    box.SelectedIndex = 1;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Diamond:
                    box.SelectedIndex = 2;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_OpenArrow:
                    box.SelectedIndex = 3;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_ClosedArrow:
                    box.SelectedIndex = 4;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Butt:
                    box.SelectedIndex = 5;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_ROpenArrow:
                    box.SelectedIndex = 6;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_RClosedArrow:
                    box.SelectedIndex = 7;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Slash:
                    box.SelectedIndex = 8;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_None:
                    box.SelectedIndex = 9;
                    return;
            }
        }

        private void LineStyleEndConvertBack(ComboBox box)
        {
            pdftron.PDF.Annots.Line line = new pdftron.PDF.Annots.Line(SelectedAnnotation);
            switch (line.GetEndStyle())
            {
                case pdftron.PDF.Annots.Line.EndingStyle.e_Square:
                    box.SelectedIndex = 0;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Circle:
                    box.SelectedIndex = 1;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Diamond:
                    box.SelectedIndex = 2;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_OpenArrow:
                    box.SelectedIndex = 3;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_ClosedArrow:
                    box.SelectedIndex = 4;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Butt:
                    box.SelectedIndex = 5;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_ROpenArrow:
                    box.SelectedIndex = 6;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_RClosedArrow:
                    box.SelectedIndex = 7;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_Slash:
                    box.SelectedIndex = 8;
                    return;
                case pdftron.PDF.Annots.Line.EndingStyle.e_None:
                    box.SelectedIndex = 9;
                    return;
            }
        }

        private void line_begin_style_box_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (SelectedAnnotation != null && !m_selection_from_ToolManager)
            {
                pdftron.PDF.Annots.Line line = new pdftron.PDF.Annots.Line(SelectedAnnotation);
                switch (line_begin_style_box.SelectedValue.ToString())
                {
                    case "t_sq":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Square);
                        break;
                    case "t_circle":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Circle);
                        break;
                    case "t_diamond":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Diamond);
                        break;
                    case "t_openA":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_OpenArrow);
                        break;
                    case "t_closedA":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_ClosedArrow);
                        break;
                    case "t_butt":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Butt);
                        break;
                    case "t_revOpenA":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_ROpenArrow);
                        break;
                    case "t_revClosedA":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_RClosedArrow);
                        break;
                    case "t_slash":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Slash);
                        break;
                    case "t_none":
                        line.SetStartStyle(pdftron.PDF.Annots.Line.EndingStyle.e_None);
                        break;
                }
                line.RefreshAppearance();
                CurrentViewer.Update(line, PageNumber);
            }
        }

        private void line_end_style_box_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (SelectedAnnotation != null && !m_selection_from_ToolManager)
            {
                pdftron.PDF.Annots.Line line = new pdftron.PDF.Annots.Line(SelectedAnnotation);
                switch (line_end_style_box.SelectedValue.ToString())
                {
                    case "t_sq":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Square);
                        break;
                    case "t_circle":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Circle);
                        break;
                    case "t_diamond":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Diamond);
                        break;
                    case "t_openA":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_OpenArrow);
                        break;
                    case "t_closedA":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_ClosedArrow);
                        break;
                    case "t_butt":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Butt);
                        break;
                    case "t_revOpenA":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_ROpenArrow);
                        break;
                    case "t_revClosedA":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_RClosedArrow);
                        break;
                    case "t_slash":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_Slash);
                        break;
                    case "t_none":
                        line.SetEndStyle(pdftron.PDF.Annots.Line.EndingStyle.e_None);
                        break;
                }
                line.RefreshAppearance();
                CurrentViewer.Update(line, PageNumber);
            }
        }

        private int DashPatternToChoice(Annot.BorderStyle bs)
        {
            double[] dash = new double[] { };
            if (bs.border_style == Annot.BorderStyle.Style.e_solid)
                return 0;
            dash = bs.dash;
            if (dash != null)
            {
                if (dash.Length == 2)
                {
                    if (dash[0] < 2)
                        return 1;
                    else if (dash[0] < 4)
                        return 2;
                    else
                        return 5;
                }
                else if (dash.Length > 2)
                {
                    if (dash[0] < 4)
                        return 3;
                    else
                        return 4;
                }
            }
            return 6;
        }

        private void line_style_box_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CurrentMarkup != null && !m_selection_from_ToolManager)
            {
                Annot.BorderStyle bs = CurrentMarkup.GetBorderStyle();
                //Annot.BorderStyle bs = new Annot.BorderStyle(CurrentMarkup.GetBorderStyle().border_style, CurrentMarkup.GetBorderStyle().width);
                switch (line_style_box.SelectedValue.ToString())
                {
                    case "t_solid":
                        bs.border_style = Annot.BorderStyle.Style.e_solid;
                        bs.dash = new double[] { };
                        break;
                    case "t_dotted":
                        bs.border_style = Annot.BorderStyle.Style.e_dashed;
                        bs.dash = new double[] { 1, 1 };
                        break;
                    case "t_dashed":
                        bs.border_style = Annot.BorderStyle.Style.e_dashed;
                        bs.dash = new double[] { 3, 1 };
                        break;
                    case "t_dashdot":
                        bs.border_style = Annot.BorderStyle.Style.e_dashed;
                        bs.dash = new double[] { 3, 1, 1, 1 };
                        break;
                    case "t_longshort":
                        bs.border_style = Annot.BorderStyle.Style.e_dashed;
                        bs.dash = new double[] { 5, 2, 2, 2 };
                        break;
                    case "t_longdash":
                        bs.border_style = Annot.BorderStyle.Style.e_dashed;
                        bs.dash = new double[] { 5, 2 };
                        break;
                    case "t_custom":
                        return;
                    default:
                        throw new Exception("Unhandled dash pattern choices.");
                }
                CurrentMarkup.SetBorderStyle(bs);
                CurrentMarkup.RefreshAppearance();
                CurrentViewer.Update(CurrentMarkup, PageNumber);
            }
        }

        private void CheckAnnotType(Annot a)
        {
            switch (a.GetType())
            {
                case Annot.Type.e_Square:
                case Annot.Type.e_Circle:
                case Annot.Type.e_Polygon:
                case Annot.Type.e_Ink:
                    LinePanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineColorPanel.Visibility = System.Windows.Visibility.Visible;
                    FillColorPanel.Visibility = System.Windows.Visibility.Visible;
                    LineStylePanel.Visibility = System.Windows.Visibility.Visible;
                    StrokeThicknessPanel.Visibility = System.Windows.Visibility.Visible;
                    ColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    return;
                case Annot.Type.e_Line:
                case Annot.Type.e_Polyline:
                    LinePanel.Visibility = System.Windows.Visibility.Visible;
                    LineColorPanel.Visibility = System.Windows.Visibility.Visible;
                    FillColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineStylePanel.Visibility = System.Windows.Visibility.Visible;
                    StrokeThicknessPanel.Visibility = System.Windows.Visibility.Visible;
                    ColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    return;
                case Annot.Type.e_Highlight:
                case Annot.Type.e_StrikeOut:
                case Annot.Type.e_Underline:
                    LinePanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    FillColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineStylePanel.Visibility = System.Windows.Visibility.Collapsed;
                    StrokeThicknessPanel.Visibility = System.Windows.Visibility.Visible;
                    ColorPanel.Visibility = System.Windows.Visibility.Visible;
                    return;
                case Annot.Type.e_Text:
                case Annot.Type.e_FileAttachment:
                case Annot.Type.e_Sound:
                case Annot.Type.e_Caret:
                case Annot.Type.e_Redact:
                    LinePanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    FillColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineStylePanel.Visibility = System.Windows.Visibility.Collapsed;
                    StrokeThicknessPanel.Visibility = System.Windows.Visibility.Collapsed;
                    ColorPanel.Visibility = System.Windows.Visibility.Visible;
                    return;
                default:
                    LinePanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    FillColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    LineStylePanel.Visibility = System.Windows.Visibility.Collapsed;
                    StrokeThicknessPanel.Visibility = System.Windows.Visibility.Collapsed;
                    ColorPanel.Visibility = System.Windows.Visibility.Collapsed;
                    break;
            }
        }

        #endregion

        #region list

        private void LoadAnnotList()
        {
            m_annot_list = new List<PageAnnot>();
            if (annotlistbox.SelectedItems.Count == 1)
            {
                i_currentSelected = annotlistbox.SelectedIndex;
            }
            annotlistbox.Items.Clear();

            PDFDoc doc = CurrentViewer.GetDoc();
            if (null == doc)
            {
                return;
            }
            for (int i = 1; i <= CurrentViewer.GetDoc().GetPageCount(); ++i)
            {
                pdftron.PDF.Page page = CurrentViewer.GetDoc().GetPage(i);
                int annot_num = page.GetNumAnnots();
                for (int j = 0; j < annot_num; ++j)
                {
                    Annot annot = page.GetAnnot(j);
                    if (annot.IsValid() == false || annot.GetFlag(Annot.Flag.e_hidden) || annot.GetType() == Annot.Type.e_Popup ||
                        annot.GetType() == Annot.Type.e_Widget || annot.GetType() == Annot.Type.e_Link || annot.GetType() == Annot.Type.e_3D)
                        continue;
                    m_annot_list.Add(new PageAnnot(i, annot));
                }
            }
            for (int i = 0; i < m_annot_list.Count; ++i)
            {
                PageAnnot annot = m_annot_list[i];
                Annot a = annot.annot;
                pdftron.PDF.Annots.Markup m = new pdftron.PDF.Annots.Markup(a);

                Border border = new Border()
                {
                    BorderThickness = new Thickness(0, 0, 0, 1),
                    BorderBrush = Brushes.Black,
                    Padding = new Thickness(5),
                    Width = annotlistbox.Width
                };
                StackPanel panel = new StackPanel();
                border.Child = panel;

                TextBlock author = new TextBlock(); // author name
                TextBlock info = new TextBlock(); // page number + date
                TextBlock note = new TextBlock(); // popup note
                TextBlock t = new TextBlock(); // tool tip
                panel.Children.Add(author);
                panel.Children.Add(info);
                panel.Children.Add(note);

                author.Text = m.GetTitle();

                DateConverter dc = new DateConverter();
                string str = (string)dc.Convert(a.GetDate(), info.Text.GetType(), null, CultureInfo.CurrentCulture);

                info.Text = "Page " + annot.pagenum.ToString() + " " + str;
                note.Text = a.GetContents();
                note.MaxHeight = 80;
                note.Width = 175;
                note.TextWrapping = TextWrapping.Wrap;

                t.Text = GetAnnotType(a);

                FormatText(ref author, m.GetTitle(), FontWeights.Bold);
                ToolTipService.SetToolTip(panel, t);

                annotlistbox.Items.Add(border);
            }
            annotlistbox.SelectedIndex = -1;
        }

        private void annotlistbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (m_selection_from_ToolManager)
            {
                return;
            }

            //if (e.AddedItems.Count > 0)
            if (CurrentToolManager.CurrentTool.ToolMode != ToolManager.ToolType.e_annot_edit)
            {
                CurrentToolManager.CreateTool(ToolManager.ToolType.e_annot_edit);
            }
            AnnotEdit annotEdit = CurrentToolManager.CurrentTool as AnnotEdit;

            m_control_down = false;
            m_shift_down = false;

            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Control) == System.Windows.Input.ModifierKeys.Control)
                m_control_down = true;
            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Shift) == System.Windows.Input.ModifierKeys.Shift)
                m_shift_down = true;

            if ((e.AddedItems.Count > 0 || e.RemovedItems.Count > 0) &&
                (annotlistbox.SelectedItems.Count != CurrentToolManager.SelectedAnnotations.Count || e.AddedItems.Count == e.RemovedItems.Count))
            {
                if (!m_control_down && !m_shift_down)
                {
                    List<Tuple<Annot, int>> annotsWithPageNums = new List<Tuple<Annot, int>>();
                    for (int i = 0; i < e.AddedItems.Count; ++i)
                    {
                        int index = annotlistbox.Items.IndexOf(e.AddedItems[i]);
                        if (index < 0) break;
                        annotsWithPageNums.Add(new Tuple<Annot, int>(m_annot_list[index].annot, m_annot_list[index].pagenum));
                    }
                    annotEdit.SelectAnnotations(annotsWithPageNums);
                }
                else
                {
                    for (int i = 0; i < e.RemovedItems.Count; ++i)
                    {
                        int index = annotlistbox.Items.IndexOf(e.RemovedItems[i]);
                        if (index < 0) break;
                        annotEdit.RemoveSelection(m_annot_list[index].annot);
                    }
                    for (int i = 0; i < e.AddedItems.Count; ++i)
                    {
                        int index = annotlistbox.Items.IndexOf(e.AddedItems[i]);
                        if (index < 0) break;
                        annotEdit.AddSelection(m_annot_list[index].annot, m_annot_list[index].pagenum);
                    }
                }
            }
            else
                annotlistbox.ScrollIntoView(annotlistbox.SelectedItem);

            if (annotlistbox.SelectedItems.Count == 1)
            {
                CurrentViewer.SetCurrentPage(m_annot_list[annotlistbox.SelectedIndex].pagenum);
            }
        }

        private void annotlistbox_KeyDown(object sender, KeyEventArgs e)
        {
            m_control_down = false;
            m_shift_down = false;
            if (annotlistbox.SelectedItems.Count > 0 && CurrentToolManager.CurrentTool.ToolMode == ToolManager.ToolType.e_annot_edit)
            {
                if (e.Key == Key.Delete)
                {
                    AnnotEdit annotEdit = CurrentToolManager.CurrentTool as AnnotEdit;
                    if (annotEdit != null)
                    {
                        annotEdit.DeleteSelectedAnnotations();
                    }
                }
            }
            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Control) == System.Windows.Input.ModifierKeys.Control)
                m_control_down = true;
            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Shift) == System.Windows.Input.ModifierKeys.Shift)
                m_shift_down = true;
        }

        private void annotlistbox_KeyUp(object sender, KeyEventArgs e)
        {
            m_control_down = false;
            m_shift_down = false;

            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Control) == System.Windows.Input.ModifierKeys.Control)
                m_control_down = true;
            if ((System.Windows.Input.Keyboard.Modifiers & ModifierKeys.Shift) == System.Windows.Input.ModifierKeys.Shift)
                m_shift_down = true;
        }

        private String GetAnnotType(Annot a)
        {
            switch (a.GetType())
            {
                case Annot.Type.e_Circle:
                    return "Ellipse";
                case Annot.Type.e_Highlight:
                    return "Highlight";
                case Annot.Type.e_Ink:
                    return "Free Hand";
                case Annot.Type.e_Line:
                    return "Line";
                case Annot.Type.e_Square:
                    return "Rectangle";
                case Annot.Type.e_StrikeOut:
                    return "Srikethrough";
                case Annot.Type.e_Underline:
                    return "Underline";
                case Annot.Type.e_Squiggly:
                    return "Squiggly Underline";
                case Annot.Type.e_Text:
                    return "Sticky Note";
                case Annot.Type.e_Stamp:
                    return "Stamp";
                case Annot.Type.e_Link:
                    return "Link";
                case Annot.Type.e_FreeText:
                    return "Text Box";
                case Annot.Type.e_Polygon:
                    return "Polygon";
                case Annot.Type.e_Polyline:
                    return "Polyline";
                case Annot.Type.e_Caret:
                    return "Caret";
                case Annot.Type.e_FileAttachment:
                    return "File Attachment";
                case Annot.Type.e_Sound:
                    return "Sound";
                case Annot.Type.e_Movie:
                    return "Movie";
                case Annot.Type.e_Screen:
                    return "Screen";
                case Annot.Type.e_PrinterMark:
                    return "Printer's Mark";
                case Annot.Type.e_TrapNet:
                    return "Trap Network";
                case Annot.Type.e_Widget:
                    return "Widget";
                case Annot.Type.e_Watermark:
                    return "Watermark";
                case Annot.Type.e_3D:
                    return "3D";
                case Annot.Type.e_Redact:
                    return "Redact";
                case Annot.Type.e_Projection:
                    return "Projection";
                case Annot.Type.e_RichMedia:
                    return "Rich Media";
                case Annot.Type.e_Unknown:
                    return "Unknown";
            }
            return "";
        }

        internal static void FormatText(ref TextBlock tb, string PartToFormat, FontWeight FontWeight)
        {
            string Text = tb.Text;
            tb.Inlines.Clear();

            Run r = new Run();
            r.Text = Text.Substring(0, Text.IndexOf(PartToFormat, StringComparison.OrdinalIgnoreCase));
            tb.Inlines.Add(r);

            r = new Run();
            r.Text = Text.Substring(Text.IndexOf(PartToFormat, StringComparison.OrdinalIgnoreCase), PartToFormat.Length);
            r.FontWeight = FontWeight;
            tb.Inlines.Add(r);

            r = new Run();
            r.Text = Text.Substring(Text.IndexOf(PartToFormat) + PartToFormat.Length, Text.Length - (Text.IndexOf(PartToFormat) + PartToFormat.Length));
            tb.Inlines.Add(r);

        }

        #endregion

        #region Utility

        public int GetAnnotationPageNumFromSelection()
        {
            if (SelectedAnnotation != null)
            {
                for (int i = 0; i < m_annot_list.Count; ++i)
                {
                    if (m_annot_list[i].annot == SelectedAnnotation)
                    {
                        annotlistbox.SelectedIndex = i;
                        return m_annot_list[i].pagenum;
                    }
                }
            }
            return -1;
        }

        [ValueConversion(typeof(Date), typeof(String))]
        public class DateConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                Date date = (Date)value;
                return date.year + "-" + date.month + "-" + date.day + " " + date.hour + ":" + date.minute + ":" + date.second;
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return DependencyProperty.UnsetValue;
            }
        }

        #endregion
    }
}
