#include "header.i"


/*********************************************************/
/* Creates the global arrays used during the computation */
/*********************************************************/

void InitializeData()
/*   --------------   */
{
     ClassNo c;
     ItemNo i, l;
     
     
     /* ContinArrays */
     
     Error_L = (ItemCount *) calloc(MaxItem+1, sizeof(ItemCount));
     Error_U = (ItemCount *) calloc(MaxItem+1, sizeof(ItemCount));
     
     Att_L = (Attribute *) calloc(MaxItem+1, sizeof(Attribute));
     Att_U = (Attribute *) calloc(MaxItem+1, sizeof(Attribute));
     
     IntSpl_L = (IntervalSplit *) calloc(MaxItem+1, sizeof(IntervalSplit)); 
     IntSpl_U = (IntervalSplit *) calloc(MaxItem+1, sizeof(IntervalSplit)); 
     
     ForEach(i, 0, MaxItem)
     {
        IntSpl_L[i].Split = (Segment *) calloc((MAXINTERVALS+1), sizeof(Segment));
        IntSpl_U[i].Split = (Segment *) calloc((MAXINTERVALS+1), sizeof(Segment));
	ForEach(l, 0, MAXINTERVALS)
	{
	   IntSpl_L[i].Split[l].Freq = 0;
	   IntSpl_L[i].Split[l].Error = 0;
	   IntSpl_L[i].Split[l].BestClass = 0;
	   IntSpl_L[i].Split[l].Threshold = 0;
	   IntSpl_U[i].Split[l].Freq = 0;
	   IntSpl_U[i].Split[l].Error = 0;
	   IntSpl_U[i].Split[l].BestClass = 0;
	   IntSpl_U[i].Split[l].Threshold = 0;
        }
     }   
               
     Freq_L = (ItemCount *) calloc(MaxClass+1, sizeof(ItemCount));
     Freq_U = (ItemCount *) calloc(MaxClass+1, sizeof(ItemCount));

     /* Frequency arrays */
          
     BEST = (ClassNo *) calloc(MaxDiscrVal+1, sizeof(ClassNo));
     
     FREQ = (ItemCount *) calloc(MaxDiscrVal+1, sizeof(ItemCount));
     ERROR = (ItemCount *) calloc(MaxDiscrVal+1, sizeof(ItemCount));
     
     _FreqA = (ItemCount *) calloc(MaxClass+1, sizeof(ItemCount));
     _Freq = (ItemCount **) calloc((MaxClass+1), sizeof(ItemCount *));
     ForEach(c, 0, MaxClass) _Freq[c] = (ItemCount *) calloc (MaxDiscrVal+1, sizeof(ItemCount));
     
     _Freq_L = (ItemCount **) calloc((MaxClass+1), sizeof(ItemCount *));
     ForEach(c, 0, MaxClass) _Freq_L[c] = (ItemCount *) calloc (MaxDiscrVal+1, sizeof(ItemCount));
     
     LIST_ALRecord = Nil;
     LIST_ILRecord = Nil;
     LIST_SLRecord = Nil;
}     
     

     
/*************************************************************************/
/*	Return a copy of tree T						 */
/*************************************************************************/


Tree CopyTree(Tree T)
/*   --------  */
{
    Tree New;
    int k;

    New = (Tree) calloc(1, sizeof(TreeRec));
    *New = *T;
    
    if( T->NodeType == BrIntervals )
    {
       New->Cut = (float *) calloc(T->Forks, sizeof(float));
       ForEach(k, 1, T->Forks-1) New->Cut[k] = T->Cut[k];
    }

    if ( T->NodeType != BrNone )
    {
	New->Branch = (Tree *) calloc(T->Forks + 1, sizeof(Tree));
	ForEach(k, 0, T->Forks)
	{
	    New->Branch[k] = CopyTree(T->Branch[k]);
	}
    }

    return New;
}



/*************************************************************************/
/*	Free up space taken up by tree Node				 */
/*************************************************************************/


void ReleaseTree( Tree Node)
/*   -------   */
{
    int k;

    if( Node == Nil ) return;
    
    if( Node->NodeType == BrIntervals )   cfree(Node->Cut);
    
    if( Node->NodeType != BrNone )
    {
	ForEach(k, 0, Node->Forks)
	{
	    ReleaseTree(Node->Branch[k]);
	}

	cfree(Node->Branch);
    }
    cfree(Node);
}


     
/***********************************/
/* Returns an initialized ALRecord */
/***********************************/

AllList MakeALRecord()
/*      ------------   */
{
     AllList L;
     ClassNo c1, c2;
     int k;
     
     
     if( LIST_ALRecord == Nil )
     {
        LIST_ALRecord = (AllList) calloc(1, sizeof(ALRecord));
	LIST_ALRecord->next = Nil;
        LIST_ALRecord->allint_L = MakeAllIntervals();
        LIST_ALRecord->allint_U = MakeAllIntervals();
     }

     {
        L = LIST_ALRecord;
	LIST_ALRecord = LIST_ALRecord->next;
        L->y_val = 0;
        L->next = Nil;
	ForAllIntervals(c1, k, c2)
	{
	   L->allint_L[c1][k][c2].Split[0].Freq = 0;
	   L->allint_L[c1][k][c2].Split[0].Error = 0;
	   L->allint_U[c1][k][c2].Split[0].Freq = 0;
	   L->allint_U[c1][k][c2].Split[0].Error = 0;
        }
        return L;
     }
}    



/*********************************************/
/* Returns an initialized AllIntervals array */
/*********************************************/

AllIntervals MakeAllIntervals()
/*           ----------------   */
{
           AllIntervals P;
	   ClassNo c1, c2;
	   int k, l;
	   
	   
           P = (IntervalSplit ***) calloc(MaxClass+1, sizeof(IntervalSplit **));
	   ForEach(c1, 0, MaxClass)
	   {
	      P[c1] = (IntervalSplit **) calloc(MAXINTERVALS+1, sizeof(IntervalSplit *));
	      ForEach(k, 0, MAXINTERVALS)
	         P[c1][k] = (IntervalSplit *) calloc(MaxClass+1, sizeof(IntervalSplit));
	   }
	   ForAllIntervals(c1, k, c2) 	    
	   {
	      P[c1][k][c2].Freq = 0;
	      P[c1][k][c2].Error = 0;
	      P[c1][k][c2].NoIntervals = k;
	      P[c1][k][c2].Split = (Segment *) calloc((MAXINTERVALS+1), sizeof(Segment));
	      ForEach(l, 0, MAXINTERVALS)
	      {
	         P[c1][k][c2].Split[l].Freq = 0;
	         P[c1][k][c2].Split[l].Error = 0;
	         P[c1][k][c2].Split[l].BestClass = 0;
	         P[c1][k][c2].Split[l].Threshold = 0;
	      }
	   }
	   return P;
}	   



/************************************************************************************/
/* Removes the first element of Superlist SL, SL != Nil, returns the remaining list */
/************************************************************************************/

SuperList RemoveElSL(SuperList SL)
/*        ----------   */
{
          SuperList SH;
	  
	  
	  SH = SL->next;
	  SL->next = LIST_SLRecord;
	  LIST_SLRecord = SL;
	  
	  return SH;
}	  

