
/* prram.c */

#define PRINT_UPREF_FROM_RAM_LEVEL_1 0
#define STR_SEE_NONE                 "(no references)"

#include "prram.h"
#include "conv.h"
#include "argp.h"
#include "color.h"
#include "utf8.h"
#include "datum.h"
#include "prdeb.h"
#include "gen.h"

#define STR_SEE_ALSO                 INDIC_XREF

/* Prepare a string containing an ascii-art rule.  */
static int  first_call = 1    ;
static char rule[TTY_WIDTH2+1];
void rule_init( void ) {
  if ( first_call ) {
    int width = opt.wide ? TTY_WIDTH2 : TTY_WIDTH1;
    memset( rule, '-', TTY_WIDTH2+1 );
    rule[width] = '\0';
    first_call = 0;
  }
}

void print_title( /*const*/ struct xram *const xram ) {
  if ( !opt.no_title ) {
    char title_uc[WIDTH_DATA+1];
    title_uc[WIDTH_DATA] = '\0';
    uc( strncpy( title_uc, xram->title, WIDTH_DATA ) );
    if ( opt.no_count ) printf(
      "%s%s%s%s%s %s%s%s%s%s%s",
      UTF82( COLOR_AB( rule     , RULE  ) ), NEWLN,
      COLOR_AB       ( xram->ram, RAMNO )  ,
      UTF82( COLOR_AB( title_uc , TITLE ) ), NEWLN,
      UTF82( COLOR_AB( rule     , RULE  ) ), NEWLN
    );
    else                printf(
      "%s%s%s%s%s %s%s %s%s%s%s%d%s%s%s%s%s%s",
      UTF82( COLOR_AB( rule     , RULE  ) ), NEWLN,
      COLOR_AB       ( xram->ram, RAMNO )  ,
      UTF82( COLOR_AB( title_uc , TITLE ) ),
      COLOR_AB       ( "("      , PAREN )  ,
      COLOR_AB       ( ""       , COUNT )  , xram->n_deb,
      COLOR_AB       ( ")"      , PAREN )  , NEWLN,
      UTF82( COLOR_AB( rule     , RULE  ) ), NEWLN
    );
    if (!( xram->sref || opt.wide || opt.no_desc ))
      printf( "%s", NEWLN );
  }
}

static inline void print_xref1(
  /*const*/ char *const ram,
  /*const*/ char *const title
) {
  if ( opt.expand_xref ) printf(
    "%s%s %s%s %s%s%s",
    UTF82( COLOR( INDIC_XREF, XINDIC  ) ),
    COLOR       ( ram       , RAMNO_X )  ,
    UTF82( COLOR( title     , TITLE_X ) ),
    NEWLN
  );
  else                   printf(
    " %s%s",
    COLOR       ( ram       , RAMNO_X )
  );
}

void print_xref( const struct xram *const xram ) {
  int none = 1;
  if ( opt.no_xref ) return;
  if ( !opt.expand_xref ) printf(
    "%s%s",
    UTF82( COLOR( STR_SEE_ALSO, XINDIC ) )
  );
  if (
    xram->up && (
      xram->ram_level > 1
      || ( (PRINT_UPREF_FROM_RAM_LEVEL_1) && xram->ram_level == 1 )
    )
  ) {
    none = 0;
    print_xref1( xram->up->ram, xram->up->title );
  }
  {
    /*const*/ struct xref *xref;
    if ( xram->xref ) none = 0;
    for ( xref = xram->xref; xref; xref = xref->next )
      print_xref1( xref->ram, xref->xram->title );
  }
  if ( !opt.expand_xref ) printf(
    "%s%s%s",
    UTF82( COLOR( none ? " " STR_SEE_NONE : "", RAMNO_X ) ),
    NEWLN
  );
}

void print_ram_foot( const struct xram *const xram ) {
  if (
    !opt.no_title
    && ( xram->sref || opt.wide || opt.no_desc || !opt.no_xref )
  ) printf( "%s", NEWLN );
}

void print_ram( void ) {

  struct xram *xram;
  rule_init();
  rewind_data();

  for ( xram = first_selected(0); xram; xram = next_selected(xram) ) {

    /* metaramification (subramification table) */
    if ( xram->sref ) {
      if ( !opt.no_subram ) {
        print_title(xram);
        {
          /*const*/ struct xref *sref;
          for ( sref = xram->sref; sref; sref = sref->next ) printf(
            "%s%s %s%s%s",
            COLOR       ( sref->ram        , RAMNO_C )  ,
            UTF82( COLOR( sref->xram->title, TITLE_C ) ),
            NEWLN
          );
        }
        print_xref    (xram);
        print_ram_foot(xram);
      }
    }

    /* end-branch (.deb table) */
    else {
      for (
        datum.type = 0;
        datum.type != TITLE
          || strncmp( datum.ram, xram->ram, N_DIG );
        get_datum(0)
      ) if ( doc_part > DEB_X ) error(
        EIO, 0,
        "cannot find ram %s in sequence in the data file's main body",
        xram->ram
      );
      if ( !opt.no_deb ) print_title(xram);
      for ( ; doc_part < DEB_X; get_datum(0) ) if (
        !opt.no_deb && datum.type == DEB
      ) print_deb( 0, 0 );
      if ( !opt.no_deb ) {
        print_xref    (xram);
        print_ram_foot(xram);
      }
    }

  }

}

