/* delete.c -- routines to delete elements */
#include "he.h"

/* HEdelete -- 'stub' function for delete */
int HEdelete(cmd)
    HE_CMD *cmd;
{
    if (cmd->argc < 2)
	return delete(he_currDesc);
    else
    {
	if (cmd->argv[1][0] != '-')
	    unkArg(cmd->argv[1]);
	else
	    switch (findOpt(cmd->argv[1] + 1))
	    {
	    case HE_HELP:
		puts("delete");
		puts("\tDelete this element or group.");
		return HE_OK;
	    case HE_NOTFOUND:
		unkOpt(cmd->argv[1]);
		return HE_FAIL;
	    case HE_AMBIG:
		ambigOpt(cmd->argv[1]);
		return HE_FAIL;
	    default:
		irrOpt(cmd->argv[1]);
		return HE_FAIL;
	    }
    }
}

/* delete -- deletes a group and its elts or an elt from current hdf file */
int delete(curr)
    int curr;
{
    int ret;

    /* check if any file is open */
    if (!fileOpen())
    {
	noFile();
	return HE_FAIL;
    }

    /* call the actual routine to do it, the update the descriptor list */
    ret = recurseDel(curr);
    updateDesc();

    return ret;
}

/* recurseDel -- this function recursively tries to delete some elts from
   a file. if the current elt is a group, it will call itself on the elts
   of the group. else, it will check if any group references the elt, and
   actually deletes it if there is no other references */
int recurseDel(curr)
    int curr;
{
    int d, currGrp;
    register int i;

    if (isGrp(he_desc[curr].tag))
    {
	/* if this is a group, do its elts then itself */

	/* find the index of the group */
	currGrp = desc2Grp(curr);

	/* step through the elts of this group */
	for ( i = 0; i < he_grp[currGrp].size ; i++)
	{
	    d =  findDesc(he_grp[currGrp].ddList + i);
	    if (d >= 0)
	    {
		/* null this so it will not report that this is a multiple
		 * copy of itself */
		he_grp[currGrp].ddList[i].tag = DFTAG_NULL;
		he_grp[currGrp].ddList[i].ref = 0;

		/* Try to delete this component */
		if (recurseDel(d) < 0) return HE_FAIL;
	    }
	}
	/* tried all components, now delete self */
	if (!hasReference(curr))
	    if (deleteDesc(curr) < 0)
		return HE_FAIL;
    }
    else
	/* not a group, actually delete this only if there is no group
	   referencing it */
	if (!hasReference(curr))
	    if (deleteDesc(curr) < 0)
		return HE_FAIL;
    return HE_OK;
}

/* end of delete.c */
