context: /*
      Derived from Autowikibrowser
      Copyright (C) 2007 Martin Richards
  
      This program 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 2 of the License, or
      (at your option) any later version.
  
      This program 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 this program; if not, write to the Free Software
      Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
  
  using System;
  using System.Collections.Generic;
  using System.Drawing;
  using System.Text;
  using System.Xml;
  using System.Windows.Forms;
  
  namespace WikiFunctions.ReplaceSpecial
  {
      //TODO: Use IArticleComparer derivatives where possible
  
      public partial class ReplaceSpecial : Form, IRuleControlOwner
      {
          #region contextmenu
          private void NewRuleContextMenuItem_Click(object sender, EventArgs e)
          {
              NewRule();
          }
  
          private void NewSubruleContextMenuItem_Click(object sender, EventArgs e)
          {
              NewSubrule();
          }
  
          private void CutMenuItem_Click(object sender, EventArgs e)
          {
              CutCmd();
          }
  
          private void CopyMenuItem_Click(object sender, EventArgs e)
          {
              CopyCmd();
          }
  
          private void PasteMenuItem_Click(object sender, EventArgs e)
          {
              PasteCmd();
          }
  
          #endregion
  
          IRule CurrentRule;
          Control ruleControl_;
          private readonly RuleTreeHistory History;
  
          public void Clear()
          {
              if (NoOfRules > 0)
                  RulesTreeView.Nodes.Clear();
          }
  
          public ReplaceSpecial()
          {
              InitializeComponent();
  
              History = new RuleTreeHistory(RulesTreeView);
  
              UpdateEnabledStates();
          }
  
          private void OkButton_Click(object sender, EventArgs e)
          {
              SaveCurrentRule();
              Hide();
          }
  
          private void ReplaceSpecial_FormClosing(object sender, FormClosingEventArgs e)
          {
              SaveCurrentRule();
              e.Cancel = true;
              Hide();
          }
  
          private void RulesTreeView_AfterSelect(object sender, TreeViewEventArgs e)
          {
              if (RulesTreeView.SelectedNode == null)
                  return;
  
              SaveCurrentRule();
              RestoreSelectedRule();
              UpdateEnabledStates();
          }
  
          private void SaveCurrentRule()
          {
              if (CurrentRule == null)
                  return;
  
              CurrentRule.Save();
              SetTreeViewColours();
          }
  
          private void RestoreSelectedRule()
          {
              if (RulesTreeView.SelectedNode == null)
              {
                  if (CurrentRule != null)
                  {
                      CurrentRule.DisposeControl();
                      CurrentRule = null;
                      NoRuleSelectedLabel.Show();
                  }
              }
              else
              {
                  NoRuleSelectedLabel.Hide();
  
                  IRule oldrule = CurrentRule;
  
                  CurrentRule = (IRule)RulesTreeView.SelectedNode.Tag;
  
                  SuspendLayout();
  
                  ruleControl_ = CurrentRule.CreateControl(this, RuleControlSpace.Controls, new Point());
                  ruleControl_.Size = RuleControlSpace.Size;
  
                  CurrentRule.Name = RulesTreeView.SelectedNode.Text;
  
                  CurrentRule.Restore();
  
                  if (oldrule != null)
                  {
                      if (!CurrentRule.Equals(oldrule))
                          oldrule.DisposeControl();
                  }
  
                  ruleControl_.Visible = true;
  
                  ResumeLayout();
              }
              UpdateEnabledStates();
              SetTreeViewColours();
          }
  
          private void UpButton_Click(object sender, EventArgs e)
          {
              MoveSelectedUp();
          }
  
          private void MoveSelectedUp()
          {
              TreeNode tn = RulesTreeView.SelectedNode;
  
              if (tn == null)
                  return;
  
              RulesTreeView.Select();
  
              TreeNodeCollection col = GetOwningNodes(tn);
  
              if (col.Count < 2)
                  return;
  
              TreeNode p = tn.PrevNode;
              if (p == null)
                  return;
  
              History.Save();
  
              col.Remove(tn);
              int i = col.IndexOf(p);
              col.Insert(i, tn);
  
              RulesTreeView.SelectedNode = tn;
              RulesTreeView.Select();
              //RulesTreeView.ExpandAll();
              RestoreSelectedRule();
          }
  
          private TreeNodeCollection GetOwningNodes(TreeNode t)
          {
              TreeNode p = t.Parent;
              return p != null ? p.Nodes : RulesTreeView.Nodes;
          }
  
          private void DownButton_Click(object sender, EventArgs e)
          {
              TreeNode tn = RulesTreeView.SelectedNode;
  
              if (tn == null)
                  return;
  
              RulesTreeView.Select();
  
              TreeNodeCollection col = GetOwningNodes(tn);
  
              if (col.Count < 2)
                  return;
  
              TreeNode p = tn.NextNode;
              if (p == null)
                  return;
  
              History.Save();
  
              int i = col.IndexOf(p);
              col.Remove(tn);
              col.Insert(i, tn);
  
              RulesTreeView.SelectedNode = tn;
              //RulesTreeView.ExpandAll();
              RestoreSelectedRule();
          }
  
          private void NewRuleButton_Click(object sender, EventArgs e)
          {
              NewRule();
              SetTreeViewColours();
          }
  
          private void NewSubruleButton_Click(object sender, EventArgs e)
          {
              NewSubrule();
              SetTreeViewColours();
          }
  
          public void NameChanged(Control rc, string name)
          {
              if (RulesTreeView.SelectedNode == null
                  || string.IsNullOrEmpty(name)
                  || RulesTreeView.SelectedNode.Text == name)
                  return;
  
              RulesTreeView.SelectedNode.Text = name;
          }
  
          private void UpdateEnabledStates()
          {
              bool hasSelection = RulesTreeView.SelectedNode != null;
  
              if (ruleControl_ != null)
                  ruleControl_.Enabled = hasSelection;
  
              DeleteButton.Enabled = hasSelection;
              UpButton.Enabled = hasSelection;
              DownButton.Enabled = hasSelection;
              NewSubruleButton.Enabled = hasSelection;
  
              DeleteMenuItem.Enabled = hasSelection;
              DeleteContextMenuItem.Enabled = hasSelection;
  
              NewSubruleMenu.Enabled = hasSelection;
              NewSubruleContextMenuItem.Enabled = hasSelection;
  
              NewSubruleMenuItem.Enabled = hasSelection;
              NewSubruleInTemplateCallMenuItem.Enabled = hasSelection;
              NewSubruleTemplateParameterMenuItem.Enabled = hasSelection;
  
              PasteMenuItem.Enabled = PasteContextMenuItem.Enabled = true;
  
              CutMenuItem.Enabled = hasSelection;
              CutContextMenuItem.Enabled = hasSelection;
  
              CopyMenuItem.Enabled = hasSelection;
              CopyContextMenuItem.Enabled = hasSelection;
  
              UndoMenuItem.Enabled = History.CanUndo;
              RedoMenuItem.Enabled = History.CanRedo;
          }
  
          private void DeleteButton_Click(object sender, EventArgs e)
          {
              DeleteCmd();
          }
  
          private void DeleteCmd()
          {
              TreeNode st = RulesTreeView.SelectedNode;
              if (st == null)
                  return;
  
              SaveCurrentRule();
  
              History.Save();
  
              TreeNode nt = st.NextNode;
  
              RulesTreeView.Nodes.Remove(st);
  
              RulesTreeView.SelectedNode = nt;
              RulesTreeView.Select();
              RestoreSelectedRule();
              SetTreeViewColours();
          }
  
          private void ReplaceSpecial_VisibleChanged(object sender, EventArgs e)
          {
              SaveCurrentRule();
          }
  
          private void ReplaceSpecial_Leave(object sender, EventArgs e)
          {
              SaveCurrentRule();
          }
  
          private void ReplaceSpecial_Deactivate(object sender, EventArgs e)
          {
              SaveCurrentRule();
          }
  
          /// <summary>
          /// 
          /// </summary>
          public int NoOfRules { get { return RulesTreeView.Nodes.Count; } }
  
          /// <summary>
          /// 
          /// </summary>
          public bool HasRules { get { return NoOfRules != 0; } }
  
          /// <summary>
          /// Applys the Replace Special Rules
          /// </summary>
          /// <param name="text">Article title</param>
          /// <param name="title">Article text</param>
          /// <returns>Amended text</returns>
          public string ApplyRules(string text, string title)
          {
              foreach (TreeNode tn in RulesTreeView.Nodes)
              {
  
gt:                 IRule r = (IRule)tn.Tag;