/* info.c -- contains HEinfo */
#include "he.h"

struct {
    int tag;
    char *name;
} he_tNTab[] =
{
{DFTAG_NULL,	"Empty               (Utility)   "},
{DFTAG_FID,	"File Identifier     (Utility)   "},
{DFTAG_FD,	"File Description    (Utility)   "},
{DFTAG_TID,	"Tag Identifier      (Utility)   "},
{DFTAG_TD,	"Tag Description     (Utility)   "},
{DFTAG_DIL,	"Data Id Label       (Utility)   "},
{DFTAG_DIA,	"Data Id Annotation  (Utility)   "},
{DFTAG_NT,	"Number type         (Utility)   "},
{DFTAG_MT,	"Machine type        (Utility)   "},
{DFTAG_ID8,	"Image Dimensions-8  (Raster-8)  "},
{DFTAG_IP8,	"Image Palette-8     (Raster-8)  "},
{DFTAG_RI8,	"Raster Image-8      (Raster-8)  "},
{DFTAG_CI8,	"Compressed Image-8  (Raster-8)  "},
{DFTAG_II8,	"Imcomp Image-8      (Raster-8)  "},
{DFTAG_ID,	"Image Dimensions    (Raster)    "},
{DFTAG_LUT,	"Image Palette       (Raster)    "},
{DFTAG_RI,	"Raster Image        (Raster)    "},
{DFTAG_CI,	"Compressed Image    (Raster)    "},
{DFTAG_RIG,	"Raster Image Group  (Raster)    "},
{DFTAG_LD,	"Palette Dimension   (Raster)    "},
{DFTAG_MD,	"Matte Dimension     (Raster)    "},
{DFTAG_MA,	"Matte Data          (Raster)    "},
{DFTAG_CCN,	"Color Correction    (Raster)    "},
{DFTAG_CFM,	"Color Format        (Raster)    "},
{DFTAG_AR,	"Aspect Ratio        (Raster)    "},
{DFTAG_DRAW,	"Draw                (Composite) "},
{DFTAG_RUN,	"Run                 (Composite) "},
{DFTAG_XYP,	"X-Y position        (Composite) "},
{DFTAG_MTO,	"M/c-Type override   (Composite) "},
{DFTAG_T14,	"TEK 4014 Data       (Tektronix) "},
{DFTAG_T105,	"TEK 4105 data       (Tektronix) "},
{DFTAG_RLE,	"Run Length Encoding (Raster)    "},
{DFTAG_IMCOMP,	"IMCOMP Encoding     (Raster)    "},
{DFTAG_SDG,	"Scientific Data Group (SciData) "},
{DFTAG_SD,	"Scientific Data     (SciData)   "},
{DFTAG_SDD,	"SciData description (SciData)   "},
{DFTAG_SDL,	"SciData labels      (SciData)   "},
{DFTAG_SDU,	"SciData units       (SciData)   "},
{DFTAG_SDF,	"SciData formats     (SciData)   "},
{DFTAG_SDS,	"SciData scales      (SciData)   "},
{DFTAG_SDM,	"SciData max/min     (SciData)   "},
{DFTAG_SDC,	"SciData coordsys    (SciData)   "},
{-1,		"Unknown Tag                     "}
};

int HEinfo(cmd)
    HE_CMD *cmd;
{
    register int i;
    int all = NO;
    int longout = NO;
    int group = NO;
    int label = NO;

    for (i = 1; i < cmd->argc; i++)
	if (cmd->argv[i][0] == '-')
	    switch (findOpt(cmd->argv[i] + 1))
	    {
	    case HE_HELP:
		puts("info [-all] [-long] [-group] [-label]");
		puts("\t-all\t\tShow info for all elements in file");
		puts("\t-long\t\tShow more info");
		puts("\t-group\t\tOrganize info in group(s)");
		puts("\t-label\t\tShow label if any");
		return HE_OK;
	    case HE_LONGOUT:
		longout = YES;
		break;
	    case HE_ALL:
		all = YES;
		break;
	    case HE_LABEL:
		label = YES;
		break;
	    case HE_DOGROUP:
		group = YES;
		break;
	    case HE_NOTFOUND:
		unkOpt(cmd->argv[i]);
		return HE_FAIL;
	    case HE_AMBIG:
		ambigOpt(cmd->argv[i]);
		return HE_FAIL;
	    default:
		irrOpt(cmd->argv[i]);
		return HE_FAIL;
	    }
	else
	{
	    unkArg(cmd->argv[i]);
	    return HE_FAIL;
	}
    return info(all, longout, group, label);
}

/* Show info about data elements
 */
int info(all, longout, group, label)
    int all;			/* select all elements */
    int longout;		/* long output */
    int group;			/* arrange output in groups */
    int label;			/* show labels */
{
    int idx;
    int empty = 0;
    int start, end;
    int d;
    int *mark;
    register int i, j;

    if (!fileOpen())
    {
	noFile();
	return HE_OK;
    }
    if (!group || (!isGrp(currTag()) && !all))
    {
	if (all)
	{
	    start = 0;
	    end = he_numDesc - 1;
	}
	else
	    start = end = he_currDesc;

	for (i = start; i <= end; i++)
	    if (he_desc[i].tag == DFTAG_NULL)
		empty++;
	    else
	    {
		if (all && i == he_currDesc)
		    printf("*");
		printf("(%d) ", i+1); /* 1 based */
		infoDesc(i, longout, label);
	    }

	if (empty > 0)
	    printf("Empty (tag %d) : %d slots.\n", DFTAG_NULL, empty);
    }
    else
    {
	mark = (int *) calloc(he_numDesc, sizeof(int));

	if (all)
	{
	    start = 0;
	    end = he_numGrp - 1;
	}
	else
	{
	    if (he_numGrp == 0)
	    {
		fprintf(stderr, "There is no group in this file.\n");
		return HE_FAIL;
	    }
	    start = end = currGrpNo();
	}
	for (i = start; i <= end; i++)
	{
	    printf("**Group %d:\n", i+1); /* 1 based */
	    idx = he_grp[i].desc;
	    infoDesc(idx, longout, label);

	    mark[idx] = YES;

	    for (j = 0; j < he_grp[i].size; j ++)
		if ((d = findDesc(he_grp[i].ddList + j)) >= 0)
		{
		    mark[d] = 1;
		    infoDesc(d, longout, 0);
		}
		else
		    fprintf(stderr,
			    "**Tag: %d, Ref: %d not in descriptors list!\n",
			    he_grp[i].ddList[j].tag,
			    he_grp[i].ddList[j].ref);
	}
	if (all)
	{
	    puts("\n**These do not belong to any group:");
	    for (i = 0; i < he_numDesc; i++)
		if (!mark[i])
		    if (he_desc[i].tag == DFTAG_NULL)
			empty++;
		    else
			infoDesc(i, longout, label);

	    if (empty > 0)
		printf("Empty (tag %d) : %d slots.\n", DFTAG_NULL, empty);
	}
    }
    return HE_OK;
}

void infoDesc(desc, longout, label)
    int desc;
    int longout;
    int label;
{
    register int i;
    char *s;

    /* search table for the entry */
    for (i = 0;
	 (he_tNTab[i].tag != he_desc[desc].tag) && (he_tNTab[i].tag >= 0);
	 i++)
	;

    printf("%s: (tag %d)", he_tNTab[i].name, he_desc[desc].tag);

    if (longout)
	printf("\n\tRef: %d, Offset: %d, Length: %d (bytes)\n",
	       he_desc[desc].ref, he_desc[desc].offset, he_desc[desc].length);
    else
	printf(", Ref: %d\n", he_desc[desc].ref);
    if (label)
    {
	getAnn(HE_LABEL, he_desc[desc].tag, he_desc[desc].ref, &s);
	if (s != NULL) printf("\tLabel: %s\n",s);
    }
}

/* end of info.c */
