context: using System;
  using System.Collections.Generic;
  using System.Linq;
  using CgmInfo.Commands.Attributes;
  using CgmInfo.Commands.Enums;
  using CgmInfo.Utilities;
  
  namespace CgmInfo.TextEncoding
  {
      internal static class AttributeReader
      {
          public static LineBundleIndex LineBundleIndex(MetafileReader reader)
          {
              return new LineBundleIndex(reader.ReadIndex());
          }
  
          public static LineType LineType(MetafileReader reader)
          {
              return new LineType(reader.ReadIndex());
          }
  
          public static LineWidth LineWidth(MetafileReader reader)
          {
              return new LineWidth(reader.ReadSizeSpecification(reader.Descriptor.LineWidthSpecificationMode));
          }
  
          public static LineColor LineColor(MetafileReader reader)
          {
              return new LineColor(reader.ReadColor());
          }
  
          public static MarkerBundleIndex MarkerBundleIndex(MetafileReader reader)
          {
              return new MarkerBundleIndex(reader.ReadIndex());
          }
  
          public static MarkerType MarkerType(MetafileReader reader)
          {
              return new MarkerType(reader.ReadIndex());
          }
  
          public static MarkerSize MarkerSize(MetafileReader reader)
          {
              return new MarkerSize(reader.ReadSizeSpecification(reader.Descriptor.MarkerSizeSpecificationMode));
          }
  
          public static MarkerColor MarkerColor(MetafileReader reader)
          {
              return new MarkerColor(reader.ReadColor());
          }
  
          public static TextBundleIndex TextBundleIndex(MetafileReader reader)
          {
              return new TextBundleIndex(reader.ReadIndex());
          }
  
          public static TextFontIndex TextFontIndex(MetafileReader reader)
          {
              return new TextFontIndex(reader.ReadIndex());
          }
  
          public static TextPrecision TextPrecision(MetafileReader reader)
          {
              return new TextPrecision(ParseTextPrecision(reader.ReadEnum()));
          }
  
          public static CharacterExpansionFactor CharacterExpansionFactor(MetafileReader reader)
          {
              return new CharacterExpansionFactor(reader.ReadReal());
          }
  
          public static CharacterSpacing CharacterSpacing(MetafileReader reader)
          {
              return new CharacterSpacing(reader.ReadReal());
          }
  
          public static TextColor TextColor(MetafileReader reader)
          {
              return new TextColor(reader.ReadColor());
          }
  
          public static CharacterHeight CharacterHeight(MetafileReader reader)
          {
              return new CharacterHeight(reader.ReadVdc());
          }
  
          public static CharacterOrientation CharacterOrientation(MetafileReader reader)
          {
              return new CharacterOrientation(reader.ReadPoint(), reader.ReadPoint());
          }
  
          public static TextPath TextPath(MetafileReader reader)
          {
              return new TextPath(ParseTextPath(reader.ReadEnum()));
          }
  
          public static TextAlignment TextAlignment(MetafileReader reader)
          {
              return new TextAlignment(ParseHorizontalAlignment(reader.ReadEnum()), ParseVerticalAlignment(reader.ReadEnum()), reader.ReadReal(), reader.ReadReal());
          }
  
          public static CharacterSetIndex CharacterSetIndex(MetafileReader reader)
          {
              return new CharacterSetIndex(reader.ReadIndex());
          }
  
          public static AlternateCharacterSetIndex AlternateCharacterSetIndex(MetafileReader reader)
          {
              return new AlternateCharacterSetIndex(reader.ReadIndex());
          }
  
          public static FillBundleIndex FillBundleIndex(MetafileReader reader)
          {
              return new FillBundleIndex(reader.ReadIndex());
          }
  
          public static InteriorStyle InteriorStyle(MetafileReader reader)
          {
              return new InteriorStyle(ParseInteriorStyle(reader.ReadEnum()));
          }
  
          public static FillColor FillColor(MetafileReader reader)
          {
              return new FillColor(reader.ReadColor());
          }
  
          public static HatchIndex HatchIndex(MetafileReader reader)
          {
              return new HatchIndex(reader.ReadIndex());
          }
  
          public static PatternIndex PatternIndex(MetafileReader reader)
          {
              return new PatternIndex(reader.ReadIndex());
          }
  
          public static EdgeBundleIndex EdgeBundleIndex(MetafileReader reader)
          {
              return new EdgeBundleIndex(reader.ReadIndex());
          }
  
          public static EdgeType EdgeType(MetafileReader reader)
          {
              return new EdgeType(reader.ReadIndex());
          }
  
          public static EdgeWidth EdgeWidth(MetafileReader reader)
          {
              return new EdgeWidth(reader.ReadSizeSpecification(reader.Descriptor.EdgeWidthSpecificationMode));
          }
  
          public static EdgeColor EdgeColor(MetafileReader reader)
          {
              return new EdgeColor(reader.ReadColor());
          }
  
          public static EdgeVisibility EdgeVisibility(MetafileReader reader)
          {
              return new EdgeVisibility(TextEncodingHelper.GetOnOffValue(reader.ReadEnum()));
          }
  
          public static FillReferencePoint FillReferencePoint(MetafileReader reader)
          {
              return new FillReferencePoint(reader.ReadPoint());
          }
  
          public static PatternTable PatternTable(MetafileReader reader)
          {
              int index = reader.ReadIndex();
              int nx = reader.ReadInteger();
              int ny = reader.ReadInteger();
              // TODO: not really used in text encoding; but in case we ever need it,
              //       the same check for zero as in binary encoding needs to happen.
              //       intentionally unused until that time comes.
              int localColorPrecision = reader.ReadInteger();
              var colors = new List<MetafileColor>();
              int count = nx * ny;
              while (reader.HasMoreData(3) && count --> 0)
                  colors.Add(reader.ReadColor());
  
              return new PatternTable(index, nx, ny, colors.ToArray());
          }
  
          public static PatternSize PatternSize(MetafileReader reader)
          {
              // NOTE: Pattern size may only be 'absolute' (VDC) in Version 1 and 2 metafiles. In Version 3 and 4 metafiles it may be
              //       expressed in any of the modes which can be selected with INTERIOR STYLE SPECIFICATION MODE.
              var specificationMode = reader.Properties.Version < 3 ? WidthSpecificationModeType.Absolute : reader.Descriptor.InteriorStyleSpecificationMode;
              return new PatternSize(
                  new MetafilePoint(reader.ReadSizeSpecification(specificationMode), reader.ReadSizeSpecification(specificationMode)),
                  new MetafilePoint(reader.ReadSizeSpecification(specificationMode), reader.ReadSizeSpecification(specificationMode)));
          }
  
          public static ColorTable ColorTable(MetafileReader reader)
          {
              int startIndex = reader.ReadColorIndex();
              var colors = new List<MetafileColor>();
              while (reader.HasMoreData())
                  colors.Add(reader.ReadDirectColor());
              return new ColorTable(startIndex, colors.ToArray());
          }
  
          public static AspectSourceFlags AspectSourceFlags(MetafileReader reader)
          {
              var asf = new Dictionary<AspectSourceFlagsType, AspectSourceFlagsValue>();
              while (reader.HasMoreData(2))
                  SetASFValue(asf, reader.ReadEnum(), reader.ReadEnum());
              return new AspectSourceFlags(asf);
          }
  
          public static PickIdentifier PickIdentifier(MetafileReader reader)
          {
              return new PickIdentifier(reader.ReadName());
          }
  
          public static LineCap LineCap(MetafileReader reader)
          {
              return new LineCap(reader.ReadIndex(), reader.ReadIndex());
          }
  
          public static LineJoin LineJoin(MetafileReader reader)
          {
              return new LineJoin(reader.ReadIndex());
          }
  
          public static LineTypeContinuation LineTypeContinuation(MetafileReader reader)
          {
              return new LineTypeContinuation(reader.ReadIndex());
          }
  
          public static LineTypeInitialOffset LineTypeInitialOffset(MetafileReader reader)
          {
  
gt:             return new LineTypeInitialOffset(reader.ReadReal());