#include <stdio.h>
#include "datamat.h"
#include "block.h"
#include "valcnt.h"
#include "logical.h"

static char *printutilsid = "$Id: printutils.c,v 1.10 1996/12/30 23:39:32 galway Exp galway $";

/* ***************************************************************** */
/* 

    printutils.c

    Copyright (C) 2004  Lionel A. Galway

    This program 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 2 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.

    For a copy of the GNU General Public License write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


   A set of utilities for printing out various data structures.

   print_imat  Prints integer array with "." for negative elements.
   print_mat   Prints out an integer array
   print_labmat   Similar to print_datamat, but nicer format.
   print_ilabmat   Similar to print_labmat, but with "." for negative 
                elements.
   print_datamat Also prints out data matrix, labels, block indicators,
                etc. in basic format.
   print_blkind  Prints out just a block indicator matrix, with or without
                labels (using print_imat or print_ilabmat).
   print_block    Prints out a block structure. (primarily for debugging).
   print_valcnt   Prints out a single valcnt data structure
   print_valcnts  Prints out valcnt data structure array

   L. Galway 30-DEC-1996 */
/* ***************************************************************** */

void print_imat(mat,nr,nc)
int **mat,nr,nc;
/*  Prints out the values of an integer matrix on stdout, but with "."
    for negative numbers */
/*  L. Galway  1-DEC-1996 */
{
  int i,j;
  for (i=0;i<nr;i++) {
    for (j=0;j<nc;j++) 
      if (mat[i][j] < 0) printf(" . ");
      else printf("%2d ",mat[i][j]);
    printf("\n");
  };
  return;
}

void print_mat(mat,nr,nc)
int **mat,nr,nc;
/*  Prints out the values of an integer matrix on stdout */
/*  L. Galway  1-DEC-1995 */
{
  int i,j;
  for (i=0;i<nr;i++) {
    for (j=0;j<nc;j++) printf("%d ",mat[i][j]);
    printf("\n");
  };
  return;
}

void print_labmat(mat,nr,nc,rlab,clab)
int **mat,nr,nc;char **rlab, **clab;
{
  int i,j,k,mxc,mxr; char fmt[100];

  /* Compute max length of column labels and row labels */
  mxc=0;for (i=0;i<nc;i++)
    if (mxc < strlen(clab[i])) mxc=strlen(clab[i]);
  mxr=0;for (i=0;i<nr;i++)
    if (mxr < strlen(rlab[i])) mxr=strlen(rlab[i]);

  /* Print column labels vertically (skipping space for row labels) */
  for (j=0;j<mxc;j++) {
    for (i=0;i<mxr;i++) printf(" ");printf("  ");
    for (k=0;k<nc;k++) {
      if (j<strlen(clab[k])) printf("%c  ",(clab[k])[j]);
      else printf("   ");
    };
    printf("\n");
  };
  printf("\n");

  /* Print out matrix rows, leaving enough space for row labels */
  sprintf(fmt,"%%%ds ",mxr);
  for (i=0;i<nr;i++){
    printf(fmt,rlab[i]);
    for (j=0;j<nc;j++) printf("%2d ",mat[i][j]);
    printf("\n");
  }

}

void print_ilabmat(mat,nr,nc,rlab,clab)
int **mat,nr,nc;char **rlab, **clab;
{
  int i,j,k,mxc,mxr; char fmt[100];

  /* Compute max length of column labels and row labels */
  mxc=0;for (i=0;i<nc;i++)
    if (mxc < strlen(clab[i])) mxc=strlen(clab[i]);
  mxr=0;for (i=0;i<nr;i++)
    if (mxr < strlen(rlab[i])) mxr=strlen(rlab[i]);

  /* Print column labels vertically (skipping space for row labels) */
  for (j=0;j<mxc;j++) {
    for (i=0;i<mxr;i++) printf(" ");printf("  ");
    for (k=0;k<nc;k++) {
      if (j<strlen(clab[k])) printf("%c  ",(clab[k])[j]);
      else printf("   ");
    };
    printf("\n");
  };
  printf("\n");

  /* Print out matrix rows, leaving enough space for row labels */
  sprintf(fmt,"%%%ds ",mxr);
  for (i=0;i<nr;i++){
    printf(fmt,rlab[i]);
    for (j=0;j<nc;j++) {
      if (mat[i][j] < 0) printf(" . ");
      else printf("%2d ",mat[i][j]);
    };
    printf("\n");
  }

}

void print_datamat(d)
struct datamat *d;
/*  Prints out the values of a block clustering data matrix on stdout */
/*  L. Galway  1-DEC-1995 */
{
  int i,j,k,mxc,mxr;char fmt[100];

  printf("rows=%d columns=%d\n",d->nrows,d->ncols);
  printf("\n\n");
  print_labmat(d->data,d->nrows,d->ncols,d->rowlabs,d->collabs);
  printf("\n");
  print_imat(d->blkind,d->nrows,d->ncols);
  printf("\n\n");
  for (i=0;i<d->ncols;i++) {
    for (j=0;j<d->colvals[i]->nvals;j++) {
      printf("%d ",d->colvals[i]->vals[j]);
    };
  printf("\n");
  };
}

void print_blkind(d,plab)
struct datamat *d;enum logical plab;
{
  if (plab==TRUE) {
    print_ilabmat(d->blkind,d->nrows,d->ncols,d->rowlabs,d->collabs);
  } else {
    print_imat(d->blkind,d->nrows,d->ncols);
  };
  return;
}

print_block(blk,d)
struct block *blk;struct datamat *d;
{
  int i,j;
  printf("Block code: %d\n",blk->bcode);

  printf ("Rows(%d): ",blk->nr);
  printf("%1d ",blk->irow[0]);
  for (i=1;i<blk->NR;i++) {
    printf("%1d",blk->irow[i]);
    if (i%5==0) printf(" ");
    };
  printf("\n");
  if (d != NULL) {
    for (i=0;i<blk->NR;i++) if (blk->irow[i]==1) printf("%s ",d->rowlabs[i]);
    printf("\n");
  };

  printf ("Cols(%d): ",blk->nc);
  printf("%1d ",blk->icol[0]);
  for (i=1;i<blk->NC;i++) {
    printf("%1d",blk->icol[i]); 
    if (i%5==0) printf(" ");
    };
  printf("\n");
  if (d != NULL) {
    for (i=0;i<blk->NC;i++) if (blk->icol[i]==1) printf("%s ",d->collabs[i]);
    printf("\n");
  };

  printf("blkcds: ");
  for (i=0;i<blk->NC;i++) {
    if (blk->icol[i]==0) printf("* ");
    else printf("%d ",blk->blkcd[i]);
  };
  printf("\n");
  printf("blkcnt: %d\n",blk->blkcnt);
  return;
}

void print_valcnt(vcnt,lab)
struct valcnt *vcnt;char *lab;
{
  int j;

    printf("(%s) nvals=%d",lab,vcnt->nvals);
    for (j=0;j<vcnt->nvals;j++) 
      printf(" %d (%d)",vcnt->vals[j],vcnt->cnts[j]);
    printf("\n");
    return;
}


void print_valcnts(vcnt,n,labs)
struct valcnt **vcnt;int n;char **labs;
{
  /* Prints vals in one line, with number of values, then values in
     increasing order with count in parentheses */

  int i;
  for (i=0;i<n;i++) {
    print_valcnt(vcnt[i],labs[i]);
  };
}
