using System.Windows;
using C1.Silverlight;
using C1.Silverlight.RichTextBox;
using C1.Silverlight.RichTextBox.Documents;
using C1.Silverlight.SpellChecker;

namespace CustomSpellCheckerMenu
{
    public class SpellCheckerMenu : C1ContextMenu
    {
        private C1RichTextBox _rtb;
        private C1MenuItem _cut, _copy, _paste, _ignoreAll, _add, _spelling;
        private C1Separator _separator1, _separator2;
        private bool _isWrongText, _isWord;

        public SpellCheckerMenu(C1RichTextBox rtb)
            : base()
        {
            _rtb = rtb;

            // Create cut/copy/paste menu items
            _cut = new C1MenuItem() { Header = "Cut" };
            _cut.Click += (s, e) => _rtb.ClipboardCut();

            _copy = new C1MenuItem() { Header = "Copy" };
            _copy.Click += (s, e) => _rtb.ClipboardCopy();

            _paste = new C1MenuItem() { Header = "Paste" };
            _paste.Click += (s, e) => { _rtb.ClipboardPaste(); };

            // Create separators
            _separator1 = new C1Separator();
            _separator2 = new C1Separator();

            // Create default spell checker menu items
            _ignoreAll = new C1MenuItem() { Header = "Ignore All" };
            _ignoreAll.Click += (s, e) => _rtb.SpellChecker.IgnoreList.Add(((C1MenuItem)s).Tag.ToString());

            _add = new C1MenuItem() { Header = "Add" };
            _add.Click += (s, e) => _rtb.SpellChecker.UserDictionary.Add(((C1MenuItem)s).Tag.ToString());

            _spelling = new C1MenuItem() { Header = "Spelling" };
            _spelling.Click += (s, e) => { ((C1SpellChecker)_rtb.SpellChecker).CheckControlAsync(_rtb, true); };

            Opening += MyContextMenu_Opening;
        }

        // Update the context menu to show the spell checker suggestions
        // for the current word
        public void UpdateSuggestions(C1TextRange wordRange)
        {
            Items.Clear();
            _isWrongText = !((C1SpellChecker)_rtb.SpellChecker).CheckWord(wordRange.Text);
            _isWord = IsWord(wordRange);
            if (_isWrongText)
            {
                var suggestions = _rtb.SpellChecker.GetSuggestions(wordRange.Text, 10);
                if (suggestions != null)
                {
                    foreach (var suggestion in suggestions)
                    {
                        AddSuggestion(suggestion, wordRange);
                    }
                }
                _ignoreAll.Tag = _add.Tag = wordRange.Text;
            }
        }

        // Add a menu item containing a suggestion for the current word
        private void AddSuggestion(string suggestion, C1TextRange wordRange)
        {
            C1MenuItem item = new C1MenuItem();
            item.FontWeight = FontWeights.Bold;
            item.Header = suggestion;
            item.Click += (s, e) => wordRange.Text = suggestion;
            Items.Add(item);
        }

        // Add the default items (cut, copy, paste) and enable/disable the items.
        // Add the default spell checker options (Ignore All/Add/Spelling)
        private void MyContextMenu_Opening(object sender, CancelEventArgs e)
        {
            _copy.IsEnabled = _cut.IsEnabled = C1.Silverlight.Clipboard.IsEnabled && !string.IsNullOrEmpty(_rtb.Selection.Text);
            _paste.IsEnabled = C1.Silverlight.Clipboard.IsEnabled && !string.IsNullOrEmpty(C1.Silverlight.Clipboard.GetTextData());

            if (Items.Count > 0)
            {
                Items.Add(_separator1);
            }
            Items.Add(_cut);
            Items.Add(_copy);
            Items.Add(_paste);

            if (_isWrongText && _isWord)
            {
                Items.Add(_separator2);
                Items.Add(_ignoreAll);
                Items.Add(_add);
                Items.Add(_spelling);
            }
        }

        // Returns true if the given text range represents a word
        private bool IsWord(C1TextRange wordRange)
        {
            return wordRange.Start.IsWordStart && wordRange.End.IsWordEnd && !wordRange.Text.Contains(" ");
        }
    }
}
