context: //
  // DO NOT REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  //
  // @Authors:
  //       christiank
  //
  // Copyright 2004-2013 by OM International
  //
  // This file is part of OpenPetra.org.
  //
  // OpenPetra.org is free software: you can redistribute it and/or modify
  // it under the terms of the GNU General Public License as published by
  // the Free Software Foundation, either version 3 of the License, or
  // (at your option) any later version.
  //
  // OpenPetra.org is distributed in the hope that it will be useful,
  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  // GNU General Public License for more details.
  //
  // You should have received a copy of the GNU General Public License
  // along with OpenPetra.org.  If not, see <http://www.gnu.org/licenses/>.
  //
  using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Drawing;
  using System.Linq;
  using System.Windows.Forms;
  
  namespace Ict.Common.Controls
  {
      /// <summary>
      /// A specialised RichTextBox that supports arbitrary 'Hyperlinks'. It supports multi-line text
      /// and a mix of plain text and 'hyperlinks'.
      /// </summary>
      /// <remarks>If one 'Hyperlink' is to be followed by another 'Hyperlink' without any
      /// plain text inbetween then valid separators are ',' (comma), ';' (semi-colon) and
      /// Environment.NewLine.
      /// </remarks>
      public partial class TRtbHyperlinks : UserControl
      {
          private List <string>SupportedLinkTypes = new List <string>();
          private SortedDictionary <int, string>FLinkPrefixes = new SortedDictionary <int, string>();
          private SortedDictionary <int, int>FLinkRanges = new SortedDictionary <int, int>();
          private DisplayHelper FDisplayHelper;
  
          /// <summary>
          /// Constructor.
          /// </summary>
          public TRtbHyperlinks()
          {
              //
              // The InitializeComponent() call is required for Windows Forms designer support.
              //
              InitializeComponent();
              #region CATALOGI18N
  
              // this code has been inserted by GenerateI18N, all changes in this region will be overwritten by GenerateI18N
              #endregion
  
              FDisplayHelper = new DisplayHelper(this);
  
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_EMAILLINK);
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_URLLINK);
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_URLWITHVALUELINK);
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_SECUREDURL);
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_FTPLINK);
              SupportedLinkTypes.Add(THyperLinkHandling.HYPERLINK_PREFIX_SKYPELINK);
  
              PlainRTFFormatting(rtbTextWithLinks);
              WriteLinkRTF(rtbTextWithLinks);
  
              rtbTextWithLinks.SelectionStart = 0;
              rtbTextWithLinks.DetectUrls = false;
  
              rtbTextWithLinks.Click += new System.EventHandler(rtbTextWithLinks_Click);
              rtbTextWithLinks.MouseMove += new System.Windows.Forms.MouseEventHandler(rtbTextWithLinks_MouseMove);
          }
  
          #region Delegates
  
          /// <summary>
          /// Delegate for building a Link where the Text of this Control is part of a hyperlink rather than it being the full hyperlink.
          /// </summary>
          public Func <string, string>BuildLinkWithValue;
  
          #endregion
  
          #region Properties
  
          /// <summary>
          /// Helper Class for handling the displaying, parsing and execution of certain types of HyperLinks
          /// </summary>
          public DisplayHelper Helper
          {
              get
              {
                  return FDisplayHelper;
              }
          }
  
          /// <summary>
          /// Sets the Text of the RichTextBox. Include keywords that are reserved for the Link Types
          /// to mark up text passages that should be rendered as Hyperlinks.
          /// </summary>
          public new string Text
          {
              get
              {
                  return rtbTextWithLinks.Text;
              }
  
              set
              {
                  rtbTextWithLinks.Text = value;
                  FLinkPrefixes.Clear();
                  FLinkRanges.Clear();
  
                  PlainRTFFormatting(rtbTextWithLinks);
                  WriteLinkRTF(rtbTextWithLinks);
              }
          }
  
          #endregion
  
          #region Events
  
          /// <summary>
          /// Contains data about a Link that got clicked by the user.
          /// </summary>
          public delegate void THyperLinkClickedArgs(string ALinkText, string ALinkType);
  
          /// <summary>Fired when a Link got clicked.</summary>
          public event THyperLinkClickedArgs LinkClicked;
  
          #endregion
  
          #region Private Methods
  
          private void PlainRTFFormatting(RichTextBox ARTFBox)
          {
              string text = ARTFBox.Text;
  
              ARTFBox.Rtf = @"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Verdana;}}" +
                            @"{\colortbl;\red0\green0\blue255;}" +
                            @"\viewkind4\uc1\pard\lang1033\b\f0\fs17\par}";
  
  //MessageBox.Show("ARTFBox.Text: " + text);
              string[] TextLines = text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
  
              // Ensure proper CR+LF handling
              for (int Counter = 0; Counter < TextLines.Length; Counter++)
              {
                  ARTFBox.AppendText(TextLines[Counter] + (Counter == TextLines.Length - 1 ? "" : "\u2028"));
              }
          }
  
          private void WriteLinkRTF(RichTextBox ARTFBox)
          {
              const string RtfSelectionReplacementStart =
                  @"{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fnil\fcharset0 Verdana;}}{\colortbl ;\red0\green0\blue255;}\uc1\pard\lang1033\b\f0\fs17";
              const string RtfSelectionReplacementEnd = "}";
  
              int TextPos = 0;
              int FoundPos;
              int NextFoundPos = 0;
              string Tmp;
              string TmpRepl;
  
  //            int NewlinePos;
  
  //MessageBox.Show(ARTFBox.Text);
              foreach (string SupportedLinkType in SupportedLinkTypes)
              {
                  FoundPos = ARTFBox.Find(SupportedLinkType);
  
                  while (FoundPos > -1)
                  {
                      TextPos = ARTFBox.Find(new char[] { ',', ';' }, FoundPos);
  
                      if (TextPos == -1)
                      {
                          for (int CounterForward = FoundPos; CounterForward < ARTFBox.Text.Length; CounterForward++)
                          {
  //                            int AsciiCode = Convert.ToInt32(ARTFBox.Text[CounterForward]);
                              if (Convert.ToInt32(ARTFBox.Text[CounterForward]) == 10)
                              {
                                  TextPos = CounterForward;
                                  break;
                              }
                          }
  
                          if (TextPos == -1)
                          {
                              TextPos = ARTFBox.Text.Length;
                          }
                      }
                      else
                      {
                          for (int CounterBackwards = TextPos; CounterBackwards > FoundPos; CounterBackwards--)
                          {
                              char TmpChar = ARTFBox.Text[CounterBackwards];
  //                            int TmpCharAscii = Convert.ToInt32(TmpChar);
  //                            NewlinePos = ARTFBox.Text.IndexOf("\\n", 0);
  
                              if (Convert.ToInt32(ARTFBox.Text[CounterBackwards]) == 10)
                              {
                                  TextPos = CounterBackwards;
                                  break;
                              }
                          }
                      }
  
                      ARTFBox.SelectionStart = FoundPos;
                      ARTFBox.SelectionLength = TextPos - FoundPos;
  
                      Tmp = @"\cf1 \ul " + ARTFBox.Text.Substring(FoundPos + SupportedLinkType.Length,
                          ARTFBox.SelectionLength - SupportedLinkType.Length) + @"\cf0\ulnone ";
  //                    MessageBox.Show("Tmp: " + Tmp);
  
                      TmpRepl = RtfSelectionReplacementStart + Tmp + RtfSelectionReplacementEnd;
                      ARTFBox.SelectedRtf = TmpRepl;
  
                      if ((NextFoundPos == 0)
  
gt:                         || (NextFoundPos == -1))