/++
  object setter:
  setting of sisu objects for downstream processing
  ao_object_setter.d
+/
template ObjectSetter() {
  /+ structs +/
  struct HeadingAttrib {
    string lev                            = "9";
    int    lev_int_markup                 = 9;
    int    lev_int_collapsed              = 9;
    int[]  closes_lev_collapsed           = []; // TODO track
    int[]  closes_lev_markup              = []; // TODO track
    int    array_ptr                  = 0;
  // heading segments, 1~ lev4:
    int    heading_array_ptr_segments = 0; // TODO
  }
  struct ParaAttrib {
    int indent_start            = 0;
    int indent_rest             = 0;
    bool bullet                 = false;
  }
  struct BlockAttrib {
    string syntax               = "";
  }
  struct Comment {
    // no .attrib and no .obj_cite_number
  }
  struct Node {
    int ocn                            = 0;
    string seg_anchor_tag              = "";
  // parent
    int parent_lev_int_markup          = 0;
    int parent_ocn                     = 0;
    int[] ancestors                    = []; // TODO track
  // heading:
    int heading_lev_int_markup         = 0;
    int heading_lev_int_collapsed      = 0;
    int[] heading_closes_lev_collapsed = []; // TODO track
    int[] heading_closes_lev_markup    = []; // TODO track
    int heading_array_ptr          = 0;
  // heading segments, 1~ lev4:
    int heading_array_ptr_segments = 0; // TODO
  // node info json string:
    string[string][string] node;
  }
  struct ObjComposite {
    string use                  = "";
    string of                   = "";
    string is_a                 = "";
    string object               = "";
    string obj_cite_number      = "";  // not used for calculations? output only? else int
    string[] anchor_tags        = [];
    HeadingAttrib heading_attrib;
    ParaAttrib para_attrib;
    BlockAttrib block_attrib;
    Node node_structure;
  }
  struct ObjCompositeArr {
    ObjComposite[] oca;
  }
  /+ structs setter +/
  struct ObjectAbstractSet {
    import std.conv : to;
    auto contents_comment(in string object) {
      ObjComposite object_set;
      object_set.use                  = "comment";
      object_set.of                   = "comment";
      object_set.is_a                 = "comment";
      object_set.object               = object;
      return object_set;
    }
    auto contents_heading(
      in string object,
      in string attrib,
      in int obj_cite_number,
      in string[] tags,
      in string lev,
      in int lev_int_markup,
      in int lev_int_collapsed,
      in string[string][string] _node,
    ) {
      ObjComposite object_set;
      object_set.use                                 = "content";
      object_set.of                                  = "para";
      object_set.is_a                                = "heading";
      object_set.object                              = object;
      object_set.obj_cite_number                     = (obj_cite_number==0) ? "" : to!string(obj_cite_number);
      object_set.anchor_tags                         ~= tags;
      object_set.heading_attrib.lev                  = lev;
      object_set.heading_attrib.lev_int_markup       = lev_int_markup;
      object_set.heading_attrib.lev_int_collapsed    = lev_int_collapsed;
      return object_set;
    }
    auto contents_para(
      in string is_a,
      in string object,
      in string attrib,
      in int obj_cite_number,
      in int[string] indent,
      in bool bullet,
    ) {
      ObjComposite object_set;
      object_set.use                      = "content";
      object_set.of                       = "para";
      object_set.is_a                     = "para";
      object_set.object                   = object.strip;
      object_set.obj_cite_number          = (obj_cite_number==0) ? "" : to!string(obj_cite_number);
      object_set.para_attrib.indent_start = to!int(indent["hang_position"]);
      object_set.para_attrib.indent_rest  = to!int(indent["base_position"]);
      object_set.para_attrib.bullet       = false; // bullet;
      // object_set.node_structure.node   = _node;
      return object_set;
    }
    auto contents_toc(
      in string is_a,
      in string object,
      in string attrib,
      in int obj_cite_number,
      in int[string] indent,
      in bool bullet,
    ) {
      ObjComposite object_set;
      object_set.use                      = "content";
      object_set.of                       = "para";
      object_set.is_a                     = "toc";
      object_set.object                   = object.strip;
      object_set.obj_cite_number          = (obj_cite_number==0) ? "" : to!string(obj_cite_number);
      object_set.para_attrib.indent_start = to!int(indent["hang_position"]);
      object_set.para_attrib.indent_rest  = to!int(indent["base_position"]);
      object_set.para_attrib.bullet       = false; // bullet;
      return object_set;
    }
    auto contents_endnote(
      in string object,
      in string tag,
    ) {
      auto m = (matchFirst(object, rgx.note_ref));
      string notenumber = to!string(m.captures[1]);
      string anchor_tag = "note_" ~ notenumber;
      ObjComposite object_set;
      object_set.use                      = "content";
      object_set.of                       = "para";
      object_set.is_a                     = "endnote";
      object_set.object                   = object.strip;
      object_set.obj_cite_number          = "";
      object_set.anchor_tags              ~= [ tag ];
      object_set.para_attrib.indent_start = 0;
      object_set.para_attrib.indent_rest  = 0;
      object_set.para_attrib.bullet       = false;
      return object_set;
    }
    auto contents_block(
      in string type,
      in string object,
      in string attrib,
      in int obj_cite_number,
    ) {
      ObjComposite object_set;
      object_set.use                 = "content";
      object_set.of                  = "block";
      object_set.is_a                = type;
      object_set.object              = object;
      object_set.obj_cite_number     = (obj_cite_number==0) ? "" : to!string(obj_cite_number);
      // object_set.node_structure.node               = _node;
      return object_set;
    }
    auto contents_block_code(
      in string type,
      in string object,
      in string attrib_language_syntax,
      in int obj_cite_number,
    ) {
      ObjComposite object_set;
      object_set.use                 = "content";
      object_set.of                  = "block";
      object_set.is_a                = type;
      object_set.block_attrib.syntax = attrib_language_syntax;
      object_set.object              = object;
      object_set.obj_cite_number     = (obj_cite_number==0) ? "" : to!string(obj_cite_number);
      // object_set.node_structure.node               = _node;
      return object_set;
    }
    auto contents_block_obj_cite_number_string(
      in string type,
      in string object,
      in string obj_cite_number,
      in string[string][string] _node
    ) {
      ObjComposite object_set;
      object_set.use                               = "content";
      object_set.of                                = "block";
      object_set.is_a                              = type;
      object_set.object                            = object;
      object_set.obj_cite_number                   = obj_cite_number;
      object_set.node_structure.node               = _node;
      return object_set;
    }
  }
}