/+
- Name: SisuDoc Spine, Doc Reform [a part of]
  - Description: documents, structuring, processing, publishing, search
    - static content generator

  - Author: Ralph Amissah
    [ralph.amissah@gmail.com]

  - Copyright: (C) 2015 - 2024 Ralph Amissah, All Rights Reserved.

  - License: AGPL 3 or later:

    Spine (SiSU), a framework for document structuring, publishing and
    search

    Copyright (C) Ralph Amissah

    This program is free software: you can redistribute it and/or modify it
    under the terms of the GNU AFERO General Public License as published by the
    Free Software Foundation, either version 3 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, see [https://www.gnu.org/licenses/].

    If you have Internet connection, the latest version of the AGPL should be
    available at these locations:
    [https://www.fsf.org/licensing/licenses/agpl.html]
    [https://www.gnu.org/licenses/agpl.html]

  - Spine (by Doc Reform, related to SiSU) uses standard:
    - docReform markup syntax
      - standard SiSU markup syntax with modified headers and minor modifications
    - docReform object numbering
      - standard SiSU object citation numbering & system

  - Homepages:
    [https://www.sisudoc.org]
    [https://www.doc-reform.org]

  - Git
    [https://git.sisudoc.org/]

+/
/++
  object setter:
  setting of sisu objects for downstream processing
  metadoc_object_setter.d
+/
module sisudoc.meta.metadoc_object_setter;
@safe:
template ObjectSetter() {
  /+ structs +/
  struct DocObj_TxtAttrib_ {
    int                    indent_base                         = 0;
    int                    indent_hang                         = 0;
    bool                   bullet                              = false;
    string                 language                            = "";
  }
  struct DocObj_Has_ {
    bool                   inline_links                        = false;
    bool                   inline_notes_reg                    = false;
    bool                   inline_notes_star                   = false;
    bool                   images                              = false;
    bool                   image_without_dimensions            = false;
  }
  struct DocObj_Table_ {
    int                    number_of_columns                   = 0;
    double[]               column_widths                       = [];
    string[]               column_aligns                       = [];
    bool                   heading                             = false;
    bool                   walls                               = false;
  }
  struct DocObj_CodeBlock_ {
    string                 syntax                              = "";
    bool                   linenumbers                         = false;
  }
  struct DocObj_Stow_ {
    string[]               link                               = [];
  }
  struct DocObj_Pointer_ {
    int                    doc_object                          = 0;
    int                    html_segnames                       = 0;
    int                    heading                             = 0;
  }
  struct DocObj_Tags_ {
    string[]               heading_ancestors_text              = [ "", "", "", "", "", "", "", "", ];
    string                 anchor_tag_html                     = "";
    string                 in_segment_html                     = "";
    string                 segment_anchor_tag_epub             = "";
    string                 html_segment_anchor_tag_is          = "";
    string                 epub_segment_anchor_tag_is          = "";
    string                 heading_lev_anchor_tag              = "";
    string                 segname_prev                        = "";
    string                 segname_next                        = "";
    string[]               lev4_subtoc                         = [];
    string[]               anchor_tags                         = [];
  }
  struct DocObj_MetaInfo_ {
    string                 is_of_part                           = ""; // frontmatter, body, backmatter
    string                 is_of_section                        = ""; // toc, body, glossary, biography, book index, blurb
    string                 is_of_type                           = ""; // para, block ?
    string                 is_a                                 = ""; // heading, para, table, code block, group, verse/poem ...
    alias                  of_part                              = is_of_part;
    alias                  of_section                           = is_of_section;
    alias                  is_of                                = is_of_type;
    string                 attrib                               = "";
    string                 lang                                 = ""; // blocks: group, block, quote; not codeblock;
    string                 syntax                               = ""; // codeblock only
    /+ o_n +/
    int                    o_n_substantive                      = 0;
    int                    o_n_non_substantive                  = 0;
    int                    o_n_glossary                         = 0;
    int                    o_n_bibliography                     = 0;
    int                    o_n_book_index                       = 0;
    int                    o_n_blurb                            = 0;
     string object_number_substantive() const @property {
      return (o_n_substantive == 0) ? "" : o_n_substantive.to!string;
    }
    string object_number_non_substantive() const @property {
      return (o_n_non_substantive == 0) ? "" : o_n_non_substantive.to!string;
    }
    string object_number_glossary() const @property {
      return (o_n_glossary == 0) ? "" : o_n_glossary.to!string;
    }
    string object_number_bibliography() const @property {
      return (o_n_bibliography == 0) ? "" : o_n_bibliography.to!string;
    }
    string object_number_book_index() const @property {
      return (o_n_book_index == 0) ? "" : o_n_book_index.to!string;
    }
    string object_number_blurb() const @property {
      return (o_n_blurb == 0) ? "" : o_n_blurb.to!string;
    }
    string marked_up_level() const @property {
      string _out;
      switch (heading_lev_markup) {
      case 0  : _out = "A"; break;
      case 1  : _out = "B"; break;
      case 2  : _out = "C"; break;
      case 3  : _out = "D"; break;
      case 4  : _out = "1"; break;
      case 5  : _out = "2"; break;
      case 6  : _out = "3"; break;
      case 7  : _out = "4"; break;
      default : _out = "";  break; // "9";
      }
      return _out;
    }
    string object_number() const @property {
      return (ocn == 0) ? "" : ocn.to!string;
    }
    bool                   object_number_off                    = false;
    bool                   visible_object_number                = false;
    int                    object_number_type                   = 0; // { ocn, non, bkidx }
    /+ node +/
    string[string][string] node;
    int                    ocn                                  = 0;
    string                 identifier                           = "";
    int                    o_n_type                             = 0;
    int                    heading_lev_markup                   = 9;
    int                    heading_lev_collapsed                = 9;
    bool                   dummy_heading                        = false;
    int[]                  markedup_ancestors                   = [ 0, 0, 0, 0, 0, 0, 0, 0,];
    int[]                  collapsed_ancestors                  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
    int[]                  dom_structure_markedup_tags_status   = [ 0, 0, 0, 0, 0, 0, 0, 0,];
    int[]                  dom_structure_collapsed_tags_status  = [ 0, 0, 0, 0, 0, 0, 0, 0,];
    int                    parent_lev_markup                    = 0;
    int                    parent_ocn                           = 0;
    int                    last_descendant_ocn                  = 0;
    ubyte[32]              sha256;
  }
  struct ObjGenericComposite {
    string                 text                                = "";
    DocObj_MetaInfo_       metainfo;
    DocObj_TxtAttrib_      attrib;
    DocObj_Tags_           tags;
    DocObj_Has_            has;
    DocObj_Table_          table;
    DocObj_CodeBlock_      code_block;
    DocObj_Stow_           stow;
    DocObj_Pointer_        ptr;
  }
  struct _theDoc {
    ObjGenericComposite[] toc;
    ObjGenericComposite[] head;
    ObjGenericComposite[] body;
    ObjGenericComposite[] bibliography;
    ObjGenericComposite[] glossary;
    ObjGenericComposite[] bookindex;
    ObjGenericComposite[] blurb;
    ObjGenericComposite[] endnotes;
  }
  struct TheObjects {
    ObjGenericComposite[] oca;
  }
  ObjGenericComposite comp_obj_, comp_obj_location, comp_obj_poem_ocn, comp_obj_comment;
  ObjGenericComposite[] the_document_toc_section, the_document_head_section, the_document_body_section, the_document_endnotes_section, the_document_bibliography_section, the_document_bookindex_section, the_document_glossary_section, the_document_blurb_section, the_document_xml_dom_tail_section;
  struct OCNset {
    int digit;
    int object_number;
    bool off;
    string identifier;
    int bkidx;
    int type;
  }
  struct ST_endnotes {
    ObjGenericComposite[] endnotes;
    OCNset                ocn;
  }
  struct ST_bookindex {
    ObjGenericComposite[] bookindex;
    OCNset                ocn;
  }
  struct ST_biblio_section {
    ObjGenericComposite[]  bibliography_section;
    string[string][string] tag_assoc;
  }
  struct ST_ancestors {
    ObjGenericComposite[] the_document_body_section;
    ObjGenericComposite[] the_document_endnotes_section;
    ObjGenericComposite[] the_document_glossary_section;
    ObjGenericComposite[] the_document_bibliography_section;
    ObjGenericComposite[] the_document_bookindex_section;
    ObjGenericComposite[] the_document_blurb_section;
  }
  struct ST_segnames {
    string[][string]      segnames;
    int                   html_segnames_ptr_cntr;
    int                   html_segnames_ptr;
  }
  struct  ST_txtPlusHasFootnotes {
    string           obj_txt;
    bool             has_notes_reg;
    bool             has_notes_star;
    bool             has_notes_plus;
  }
  struct ST_txtPlusHasFootnotesUrlsImages {
    string           obj_txt;
    bool             has_notes_reg;
    bool             has_notes_star;
    bool             has_notes_plus;
    bool             has_urls;
    bool             has_images_without_dimensions;
  }
  struct ST_txtAndAnchorTagPlusHasFootnotesUrlsImages {
    string           obj_txt;
    string           anchor_tag;
    bool             has_notes_reg;
    bool             has_notes_star;
    bool             has_notes_plus;
    bool             has_links; // use same name
    bool             has_images_without_dimensions;
  }
  struct ST_the_section {
    ObjGenericComposite[]  comp_section_obj; // array: the heading has 2 members inserted, paras just 1
    uint[string]           pith;
    string[string][string] tag_assoc;        // only for headings: html & epub
  }
  // book index variables
  string book_idx_tmp;
  string[][string][string] bookindex_unordered_hashes;
  // node
  struct ST_txt_by_line_common_reset {
    int[string]     line_occur;
    string[string]  this_object;
    uint[string]    pith;
  }
  struct ST_txt_by_line_block_start {
    uint[string]    pith;
    uint[string]    dochas;
    string[string]  object_number_poem;
  }
  struct ST_txt_by_line_block_generic {
    uint[string]    pith;
    string[string]  this_object;
  }
  struct ST_txt_by_line_block_poem {
    int             cntr;
    uint[string]    pith;
    string[string]  this_object;
  }
  struct ST_txt_by_line_block_biblio {
    uint[string]    pith;
    int             bib_entry;
    string          biblio_entry_str_json;
    string[]        biblio_arr_json;
  }
  struct ST_flow_book_index {
    string[string]  this_object;
    uint[string]    pith;
    string          book_idx_tmp;
  }
  struct ST_flow_heading_found {
    string[string]       heading_match_str;
    Regex!(char)[string] heading_match_rgx;
    uint[string]         pith;
  }
  struct ST_flow_heading_make_set {
    char[]          line;
    uint[string]    pith;
    string[string]  this_object;
  }
  struct ST_flow_para_match {
    uint[string]    pith;
    string[string]  this_object;
    string          this_object_key;
    int[string]     indent;
    bool            bullet;
    int[string]     line_occur;
  }
  struct ST_flow_table_array_munge {
    ObjGenericComposite table_object;
    string[][]          table_array;
  }
  struct ST_flow_table_of_contents_gather_headings {
    ObjGenericComposite[] the_document_toc_section;
    string[][string]      lev4_subtoc;
  }
  struct ST_flow_bibliography {
    JSONValue[] biblio_sorted;
    JSONValue[] bib_arr_json;
    string[]    biblio_unsorted_incomplete;
  }
  struct ST_flow_table_closed_make_special_notation_table {
    string[string]        this_object;
    ObjGenericComposite[] the_document_body_section;
    OCNset                obj_cite_digits;
    ObjGenericComposite   comp_obj_;
    int                   cntr;
    uint[string]          pith;
  }
  struct ST_flow_block_flag_line_empty {
    string[string]           this_object;
    ObjGenericComposite[]    the_document_body_section;
    string[][string][string] bookindex_unordered_hashes;
    OCNset                   obj_cite_digits;
    ObjGenericComposite      comp_obj_;
    int                      cntr;
    uint[string]             pith;
  }
  struct ST_flow_table_substantive_munge {
    ObjGenericComposite  table_object;
    string               table_substantive;
  }
  struct _loopMarkupSrcByLineStruct {
    ObjGenericComposite[] toc;
    ObjGenericComposite[] body;
    ObjGenericComposite[] glossary;
    ObjGenericComposite[] blurb;
    string[string]        object_notes;
    string[][string]      segnames;
  }
  enum DocStructMarkupHeading {
    h_sect_A,
    h_sect_B,
    h_sect_C,
    h_sect_D,
    h_text_1,
    h_text_2,
    h_text_3,
    h_text_4,
    h_text_5, // extra level, drop
    content_non_header
  } // header section A-D; header text 1-4
  enum Status { off, on, }
  enum OCNtype { ocn, non, bkidx, }
  enum DomTags { none, open, close, close_and_open, open_still, }
  enum Substitute { match, markup, }
  static auto eN() {
    struct _e {
      enum bi {
        off,
        on,
      }
      enum ocn {
        off,
        on,
        closing,
        bkidx,
        reset,
      }
      enum sect {
        unset,
        head,
        toc,
        substantive,
        bibliography,
        glossary,
        book_index,
        blurb,
      }
      enum txt_is {
        off,
        para,
        heading,
      }
      enum blk_is {
        off,
        code,
        poem,
        block,
        group,
        table,
        quote,
      }
      enum blk_state {
        off,
        on,
        closing,
      }
      enum blk_delim {
        off,
        curly,
        tic,
        curly_special,
        tic_special,
      }
    }
    return _e();
  }
}