/***********************************************************************************
 * Chaga string arithmetic library                                                 *
 * Copyright (C) 2026 Robert James Bruce                                           *
 *                                                                                 *
 * This file is part of the Chaga string arithmetic library.                       *
 *                                                                                 *
 * The Chaga string arithmetic library is free software: you can redistribute it   * 
 * and/or modify it under the terms of the GNU General Public License as published *
 * by the Free Software Foundation, either version 3 of the License, or (at your   *
 * option) any later version.                                                      *
 *                                                                                 *
 * The Chaga string arithmetic library 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 the Chaga compiler. If not, see <https://www.gnu.org/licenses/>.     *
 ***********************************************************************************/
#include "include/libchaga-diagnostic_tools.h"

void display_packed_string_integer_structure (psint *packed_string_integer)
{
  size_t i;
  psnc *packed_string_number_component;

  if (packed_string_integer != NULL)
  {
    printf ("\nNUMBER BLOCK:\n");
    printf ("address:               %p\n", packed_string_integer);
    printf ("sign:                  ");
    switch (packed_string_integer->sign)
    {
      case negative:
        printf ("negative");
      break;
      case positive:
        printf ("positive");
      break;
      case zero:
        printf ("zero");
      break;
      case undefined:
        printf ("undefined");
      break;
      default:
        printf ("ERROR: unknown sign\n");
      break;
    }
    putchar ('\n');
    printf ("status flag:           ");
    switch (packed_string_integer->status_flag)
    {
      case NONE:
        printf ("none");
      break;
      case INTERNAL_ERROR:
        printf ("internal error");
      break; 
      case DIVIDE_BY_ZERO:
        printf ("divide by zero");
      break; 
      case REPEATING_NONTERMINATING:
        printf ("repeating nonterminating");
      break; 
      case IMAGINARY:
        printf ("imaginary");
      break; 
      default:
        printf ("ERROR: UNDEFINED STATUS FLAG VALUE!\n");
      break;
    }
    printf ("\n");
    packed_string_number_component = packed_string_integer->left_of_decimal;
    while (packed_string_number_component != NULL)
    {
      printf ("highest digit position:  %lld\n", packed_string_number_component->highest_digit_position);
      printf ("highest nibble position: ");
      switch (packed_string_number_component->highest_nibble_position)
      {
        case lo:
          printf ("lo\n");
        break;
        case hi:
          printf ("hi\n");
        break;
        default:
          printf ("ERROR: unknown value\n");
        break;
      }
      printf ("PACKED NUMBER BLOCK:\n");
      for (i = 0; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
      {
        printf ("%p, value: %02x\n", &packed_string_number_component->packed_number_block[i], packed_string_number_component->packed_number_block[i]);
      }
      printf ("first_number_block:    %p\n", packed_string_number_component->first_number_block);
      printf ("last_number_block:     %p\n", packed_string_number_component->last_number_block);
      printf ("previous number block: %p\n", packed_string_number_component->previous_number_block);
      printf ("next number block:     %p\n", packed_string_number_component->next_number_block);
      packed_string_number_component = packed_string_number_component->next_number_block;
      putchar ('\n');
    }
  }
}




void display_packed_string_float_structure (psflt *packed_string_float)
{
  psnc *left_of_decimal, *right_of_decimal;
  size_t i;

  left_of_decimal  = NULL;
  right_of_decimal = NULL;
  if (packed_string_float != NULL)
  {
    left_of_decimal  = packed_string_float->left_of_decimal;
    right_of_decimal = packed_string_float->right_of_decimal;
    printf ("left_of_decimal:       %p\n", left_of_decimal);
    printf ("right_of_decimal:      %p\n", right_of_decimal);
    printf ("sign:                  ");
    switch (packed_string_float->sign)
    {
      case negative:
        printf ("negative");
      break;
      case positive:
        printf ("positive");
      break;
      case zero:
        printf ("zero");
      break;
      case undefined:
        printf ("undefined");
      break;
      default:
        printf ("ERROR: unknown sign\n");
      break;
    }
    putchar ('\n');
    printf ("status flag:           ");
    switch (packed_string_float->status_flag)
    {
      case NONE:
        printf ("none");
      break;
      case INTERNAL_ERROR:
        printf ("internal error");
      break; 
      case DIVIDE_BY_ZERO:
        printf ("divide by zero");
      break; 
      case REPEATING_NONTERMINATING:
        printf ("repeating nonterminating");
      break; 
      case IMAGINARY:
        printf ("imaginary");
      break; 
      default:
        printf ("ERROR: UNDEFINED STATUS FLAG VALUE!\n");
      break;
    }
    printf ("\n");
  }
  if (left_of_decimal != NULL)
  {
    printf ("LEFT OF DECIMAL:\n");
  }
  while (left_of_decimal != NULL)
  {
    printf ("\nNUMBER BLOCK:\n");
    printf ("address:                %p\n", left_of_decimal);
    printf ("highest digit position: %lld\n", left_of_decimal->highest_digit_position);
    printf ("highest nibble position: ");
    switch (left_of_decimal->highest_nibble_position)
    {
      case lo:
        printf ("lo\n");
      break;
      case hi:
        printf ("hi\n");
      break;
      default:
        printf ("ERROR: unknown value\n");
      break;
    }
    printf ("STRING FLOAT BUFFER:\n");
    for (i = 0; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
    {
      printf ("%p, value: %02x\n", &left_of_decimal->packed_number_block[i], left_of_decimal->packed_number_block[i]);
    }
    printf ("first_number_block:    %p\n", left_of_decimal->first_number_block);
    printf ("last_number_block:     %p\n", left_of_decimal->last_number_block);
    printf ("previous number block: %p\n", left_of_decimal->previous_number_block);
    printf ("next number block:     %p\n", left_of_decimal->next_number_block);
    left_of_decimal = left_of_decimal->next_number_block;
    putchar ('\n');
  }
  if (right_of_decimal != NULL)
  {
    printf ("RIGHT OF DECIMAL:\n");
  }
  while (right_of_decimal != NULL)
  {
    printf ("\nNUMBER BLOCK:\n");
    printf ("address:                %p\n", right_of_decimal);
    printf ("highest digit position: %lld\n", right_of_decimal->highest_digit_position);
    printf ("highest nibble position: ");
    switch (right_of_decimal->highest_nibble_position)
    {
      case lo:
        printf ("lo\n");
      break;
      case hi:
        printf ("hi\n");
      break;
      default:
        printf ("ERROR: unknown value\n");
      break;
    }
    printf ("PACKED_NUMBER_BLOCK:\n");
    for (i = 0; i < MAX_PACKED_NUMBER_BLOCK_SIZE; i++)
    {
      printf ("%p, value: %02x\n", &right_of_decimal->packed_number_block[i], right_of_decimal->packed_number_block[i]);
    }
    printf ("first_number_block:    %p\n", right_of_decimal->first_number_block);
    printf ("last_number_block:     %p\n", right_of_decimal->last_number_block);
    printf ("previous number block: %p\n", right_of_decimal->previous_number_block);
    printf ("next number block:     %p\n", right_of_decimal->next_number_block);
    right_of_decimal = right_of_decimal->next_number_block;
    putchar ('\n');
  }
}


