context: using System.Collections.Generic;
  using System.Linq;
  using VisioAutomation.Extensions;
  using IVisio = Microsoft.Office.Interop.Visio;
  
  namespace VisioAutomation.Scripting.Commands
  {
      public class TextCommands: CommandSet
      {
          internal TextCommands(Client client) :
              base(client)
          {
  
          }
  
         public void Set(IList<IVisio.Shape> target_shapes, IList<string> texts)
         {
             this.Client.Application.AssertApplicationAvailable();
             this.Client.Document.AssertDocumentAvailable();
  
             if (texts == null || texts.Count < 1)
             {
                 // do nothing
                 return;
             }
  
             var shapes = this.GetTargetShapes(target_shapes);
             if (shapes.Count < 1)
             {
                 return;
             }
  
             var application = this.Client.Application.Get();
             using (var undoscope = this.Client.Application.NewUndoScope("Set Shape Text"))
             {
                 int numtexts = texts.Count;
  
                 int up_to = System.Math.Min(numtexts, shapes.Count);
  
                 for (int i = 0; i < up_to; i++)
                 {
                     var text = texts[i % numtexts];
                     if (text != null)
                     {
                         var shape = shapes[i];
                         shape.Text = text;
                     }
                 }
             }
         }
  
          public IList<string> Get(IList<IVisio.Shape> target_shapes)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
              
              var shapes = this.GetTargetShapes(target_shapes);
              if (shapes.Count < 1)
              {
                  return new List<string>(0);
              }
  
              var texts = shapes.Select(s => s.Text).ToList();
              return texts;
          }
  
          public void ToogleCase(IList<IVisio.Shape> target_shapes)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
              
              var shapes = this.GetTargetShapes(target_shapes);
  
              if (shapes.Count < 1)
              {
                  return;
              }
  
              var application = this.Client.Application.Get();
              using (var undoscope = this.Client.Application.NewUndoScope("Toggle Shape Text Case"))
              {
                  var shapeids = shapes.Select(s => s.ID).ToList();
  
                  var page = application.ActivePage;
                  // Store all the formatting
                  var formats = Text.TextFormat.GetFormat(page, shapeids);
  
                  // Change the text - this will wipe out all the character and paragraph formatting
                  foreach (var shape in shapes)
                  {
                      string t = shape.Text;
                      if (t.Length < 1)
                      {
                          continue;
                      }
                      shape.Text = TextCommandsUtil.toggle_case(t);
                  }
  
                  // Now restore all the formatting - based on any initial formatting from the text
  
                  var update = new ShapeSheet.Update();
                  for (int i = 0; i < shapes.Count; i++)
                  {
                      var format = formats[i];
  
                      if (format.CharacterFormats.Count>0)
                      {
                          var fmt = format.CharacterFormats[0];
                          update.SetFormulas((short) shapeids[i], fmt, 0);
                      }
  
                      if (format.ParagraphFormats.Count > 0)
                      {
                          var fmt = format.ParagraphFormats[0];
                          update.SetFormulas((short)shapeids[i], fmt, 0);
                      }
                  }
  
                  update.Execute(page);
              }
          }
  
          public void SetFont(IList<IVisio.Shape> target_shapes, string fontname)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
  
              var shapes = this.GetTargetShapes(target_shapes);
              if (shapes.Count < 1)
              {
                  return;
              }
              var application = this.Client.Application.Get();
              var active_document = application.ActiveDocument;
              var active_doc_fonts = active_document.Fonts;
              var font = active_doc_fonts[fontname];
              IVisio.VisGetSetArgs flags=0;
              var srcs = new[] {ShapeSheet.SRCConstants.CharFont};
              var formulas = new[] { font.ID.ToString() };
              this.Client.ShapeSheet.SetFormula(target_shapes, srcs, formulas, flags);
          }
  
          public IList<Text.TextFormat> GetFormat(IList<IVisio.Shape> target_shapes)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
  
              var shapes = this.GetTargetShapes(target_shapes);
              if (shapes.Count < 1)
              {
                  return new List<Text.TextFormat>(0);
              }
  
              var selection = this.Client.Selection.Get();
              var shapeids = selection.GetIDs();
              var application = this.Client.Application.Get();
              var formats = Text.TextFormat.GetFormat(application.ActivePage, shapeids);
              return formats;
          }
  
          public void MoveTextToBottom(IList<IVisio.Shape> target_shapes)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
  
              var shapes = this.GetTargetShapes(target_shapes);
              if (shapes.Count < 1)
              {
                  return ;
              }
  
              var update = new ShapeSheet.Update();
              foreach (var shape in shapes)
              {
                  if (0 ==
                      shape.RowExists[
                          (short) IVisio.VisSectionIndices.visSectionObject, (short) IVisio.VisRowIndices.visRowTextXForm,
                          (short) IVisio.VisExistsFlags.visExistsAnywhere])
                  {
                      shape.AddRow((short)IVisio.VisSectionIndices.visSectionObject, (short)IVisio.VisRowIndices.visRowTextXForm, (short)IVisio.VisRowTags.visTagDefault); 
                      
                  }
              }
  
              var application = this.Client.Application.Get();
              var shapeids = shapes.Select(s=>s.ID);
              foreach (int shapeid in shapeids)
              {
                  update.SetFormula((short)shapeid, ShapeSheet.SRCConstants.TxtHeight, "Height*0"); 
                  update.SetFormula((short)shapeid, ShapeSheet.SRCConstants.TxtPinY, "Height*0"); 
                  update.SetFormula((short)shapeid, ShapeSheet.SRCConstants.VerticalAlign, "0");
              } 
              var active_page = application.ActivePage; 
              update.Execute(active_page);
          }
  
          public void SetTextWrapping(IList<IVisio.Shape> target_shapes,bool wrap)
          {
              this.Client.Application.AssertApplicationAvailable();
              this.Client.Document.AssertDocumentAvailable();
  
              var shapes = this.GetTargetShapes2D(target_shapes);
              if (shapes.Count < 1)
              {
                  return;
              }
  
  
gt:             var shapeids = shapes.Select(s => s.ID).ToList();