#include "ArbreCL.h"


ArbreCL::ArbreCL()
  //constructeur
{
  racine.fils=NULL;racine.pere=NULL;racine.frere=NULL;
  cardinal=0;
}


CL* ArbreCL::AdresseRacine()
  //
{
  return(&racine);
}


CL* ArbreCL::AdresseFrerePuine(CL *elem)
  //
{
  return(elem->frere);
}


CL* ArbreCL::AdressePere(CL *elem)
  //
{
  return(elem->pere);
}


CL* ArbreCL::AdressePremierFils(CL *elem)
  //
{
  return(elem->fils);
}


CL* ArbreCL::AdresseFilsSuivant(CL *pere,CL *elem)
  //si elem=pere: on renvoie l'adresse du premier fils
  //sinon, on renvoie l'adresse du frere puiné
{
  //cout<<elem<<endl<<pere<<endl;
  if (pere==NULL)
    {cout<<"Erreur classe ArbreCL: adresse pere nulle"<<endl;return(NULL);}
  if (elem==NULL) 
    {cout<<"Erreur classe ArbreCL: adresse elem nulle"<<endl;return(NULL);}

  if (elem==pere) {return(pere->fils);}
  else {return(elem->frere);}
   
}



/*void ArbreCL::InsererPremierFils(CL *pere,CL *elem)
  //
  {
  if (pere->fils==NULL) { pere->fils=elem; }
  else
  {
      elem->frere=pere->fils;
      pere->fils=elem;
      }
      elem->pere=pere;elem->fils=NULL;cardinal++;
      }
      */



void ArbreCL::InsererPremierFils(CL *pere,int &coup)
  //insère un coup légal en tant que premier fils du pere de la liste
{
  CL *elem;
  elem=new(CL);
  assert(elem!=NULL);
  if (pere->fils==NULL) { pere->fils=elem;elem->frere=NULL; }
  else
    {
      elem->frere=pere->fils;
      pere->fils=elem;
    }
  elem->pere=pere;elem->fils=NULL;
  elem->coup=coup;elem->valeur=-1000000;
  //MODIF AB
  elem->cond=0;
  cardinal++;
}



void ArbreCL::SupprimerPremierFils(CL *pere)
  //
{
  if (pere->fils==NULL) 
    {cout<<"Erreur:"<<endl<<"On ne peut supprimer un 1er fils qui n'existe pas"<<endl;}
  else
    {
      if (pere->fils->fils!=NULL) 
	{cout<<"Erreur:"<<endl<<"Ce premier fils possède des fils qui deviendraient orphelins"<<endl;}
      else
	{
	  CL *suivant;
	  suivant=pere->fils->frere;
	  delete(pere->fils);cardinal--;
	  pere->fils=suivant;
	}
    }
}



void ArbreCL::AfficherFils(CL *pere)
  //Affiche les valeurs de tous les fils 
{
  int i;
  CL *courant;
  courant=pere->fils;
  cout<<endl<<"Affichage Liste coups légaux:"<<endl;
  while(courant!=NULL)
    {
      {cout<<courant->coup+1;}
      cout<<" ; ";
      courant=courant->frere;
    }
}




void ArbreCL::ViderFils(CL *pere)
   //A n'employer QUE SI on est sur que les fils n'ont pas de fils
{
  CL *courant,*suivant;
  courant=pere->fils;
  while(courant!=NULL)
    {
      suivant=courant->frere;
      delete(courant);cardinal--;
      courant=suivant;
    }
  pere->fils=NULL;
}


void ArbreCL::Fratricide(CL *elem)
  //Efface tous les frères d'un sommet sélectionné qui devient le premier fils
{
  CL *courant,*suivant;
  courant=elem->pere->fils;
  while(courant!=NULL)
    {
      suivant=courant->frere;
      if (courant!=elem) {delete(courant);cardinal--;}
      courant=suivant;
    }
  elem->pere->fils=elem;
  elem->frere=NULL;elem->fils=NULL;
  //cout<<endl<<"Plus de freres"<<endl;
}


void ArbreCL::Elaguer(CL *elem)
  //
{
  CL *courant,*prec;
  if (elem->pere!=NULL)
    {
      //si on supprime le premier fils, on réactualise le pointeur du pere 
      if (elem->pere->fils==elem) {elem->pere->fils=elem->frere;delete(elem);}
      else //cas général: on trouve le frere precedent
	//on le chaine avec le frere puine de l'element
	{
	  courant=elem->pere->fils;prec=courant;
	  while (courant!=elem) {prec=courant;courant=courant->frere;}
	  prec->frere=elem->frere;
	  delete(elem);
	}
    }  
}



int ArbreCL::Cardinal()
  //renvoie la nombre total de sommets
{
  return(cardinal);
}








