/*  tally_delta.c is part of Statnet */
/* Statnet is protected under the GNU Public License (GPL2). */
/* Author: Jeroen Baekelandt (jeroenb@igwe.vub.ac.be)        */
/* 15FEB98: Scot E. Wilcoxon (sewilco@fieldday.mn.org)       */

#include "stat.h"

/* Deal with overflow/restart in simpleminded way */
#define DIFFZERO(a,b)	( ( a > b ) ? ( a - b ) : 0 )

void
tally_delta ( struct Tally *New_t, 
	struct Tally *Prev_t, 
	struct Tally *Delta_t )
{
  unsigned	temp_int, search;

  if( New_t != (struct Tally *)0 &&
      Prev_t != (struct Tally *)0 &&
      Delta_t != (struct Tally *)0 )
  {  /* if pointers initialized */

    Delta_t->types = Prev_t->types;
    Delta_t->t_count = Prev_t->t_count;

    if (New_t->type_code != disabled)
    {  /* if type not disabled */
      if( New_t->c_max > 0 &&
          New_t->count != (unsigned int *)0 &&
          Prev_t->count != (unsigned int *)0 &&
          Delta_t->count != (unsigned int *)0 )
      {  /* if using array of counters */
	for (temp_int = 0; temp_int <= New_t->c_max; temp_int++ )
	{  /* for all in the array of counters */
		if( New_t->count[temp_int] > 0 )
			Delta_t->count[temp_int] = DIFFZERO( New_t->count[temp_int], Prev_t->count[temp_int] );
		else
			Delta_t->count[temp_int] = 0;
	}  /* for all in the array of counters */
      }  /* if using array of counters */

      if( New_t->t_max > 0 &&
          New_t->types != (unsigned int *)0 &&
          Prev_t->types != (unsigned int *)0 &&
          Delta_t->types != (unsigned int *)0 &&
          New_t->t_count != (unsigned int *)0 &&
          Prev_t->t_count != (unsigned int *)0 &&
          Delta_t->t_count != (unsigned int *)0 )
      {  /* if using array of types */
	for (temp_int = 0; temp_int <= New_t->t_max; temp_int++ )
	{  /* for all types in the array */
		if( New_t->t_count[temp_int] > 0 )
		{  /* if counter is in use */
			if( New_t->types[temp_int] == Prev_t->types[temp_int] )
			{  /* if the protocol type has not moved */
				Delta_t->t_count[temp_int] = DIFFZERO( New_t->t_count[temp_int], Prev_t->t_count[temp_int] );
			}  /* if the protocol type has not moved */
			else
			{  /* else protocol type not in same order */
				for (search = 0; search <= New_t->t_max; search++ )
				{  /* for all protocol types */
					if( temp_int != search && New_t->types[temp_int] == Prev_t->types[search] )
					{  /* if found same protocol type */
						Delta_t->t_count[temp_int] = DIFFZERO( New_t->t_count[temp_int], Prev_t->t_count[search] );
						break;  /* found, stop searching */
					}  /* if found same protocol type */
				}  /* for all protocol types */
				if (search > New_t->t_max)
				{  /* if did not find same protocol */
					Delta_t->t_count[temp_int] = 0;
				}  /* if did not find same protocol */
			}  /* else protocol type not in same order */

		}  /* if counter is in use */
		else
			Delta_t->t_count[temp_int] = 0;
	}  /* for all types in the array */
      }  /* if using array of types */
    }  /* if type not disabled */
  }  /* if pointers initialized */
}
