
/*******************************************************************************
*
* File blk_events.h
*
* Copyright (C) 2005, 2008 Martin Luescher
*
* This software is distributed under the terms of the GNU General Public
* License (GPL)
*
* Block events
*
*******************************************************************************/

#define BLK_EVENTS_H

#if (defined FLAGS_C)

static void (*blk_event_fcts[EVENTS])(int nb)={NULL};


static void GridBalanceFlags(void)
{
   int u,ud,iu,iud;
   int imu,isw,iswd,nt;
   blk_flags_t *bf,*bfm;
   
   bf=(*gf).bf;
   bfm=bf+(*gf).nb;

   u=(*bf).u;
   ud=(*bf).ud;
   iu=1;
   iud=1;
   imu=1;
   isw=1;
   iswd=1;

   for (;bf<bfm;bf++)
   {
      if ((*bf).u!=u)
         iu=0;

      if ((*bf).ud!=ud)
         iud=0;

      if ((*bf).u!=(*bf).ud)
         imu=0;

      if ((*bf).u!=(*bf).sw[0])
         isw=0;

      if ((*bf).ud!=(*bf).swd[0])
         iswd=0;
   }

   nt=next_tag();
   
   if ((iu==0)&&((*gf).shu==0))
   {
      bf=(*gf).bf;
      bfm=bf+(*gf).nb;

      for (;bf<bfm;bf++)
      {
         (*bf).u=nt;

         if (isw==1)
            (*bf).sw[0]=nt;
      }
   }

   nt=next_tag();
   
   if ((iud==0)&&((*gf).shud==0))
   {
      bf=(*gf).bf;
      bfm=bf+(*gf).nb;

      if ((imu==1)&&((*gf).shu==0))
         nt=(*bf).u;

      for (;bf<bfm;bf++)
      {
         (*bf).ud=nt;

         if (iswd==1)
            (*bf).swd[0]=nt;
      }
   }
}


static void GridAssignedU2ubgr(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      bf[n].u=lat.u;
      bf[n].ub=(*gf).ub;
      bf[n].bc=lat.bc;
   }
}


static void GridAssignedUd2ubgr(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      bf[n].u=lat.ud;
      bf[n].ub=(*gf).ubd;
      bf[n].bc=lat.bcd;
   }
}


static void GridAssignedUd2udbgr(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
      {
         bf[n].ud=lat.ud;
         bf[n].ubd=(*gf).ubd;
         bf[n].bcd=lat.bcd;
      }
      else if ((*gf).shud==1)
      {
         bf[n].ud=0;
         bf[n].ubd=0;
         bf[n].bcd=0;
      }
   }
}


static void GridSwappedActive(int nb)
{
   int n,nbf,ud;
   blk_flags_t *bf;

   GridBalanceFlags();
   
   nbf=(*gf).nb;
   bf=(*gf).bf;
   ud=(*bf).ud;

   for (n=0;n<nbf;n++)
      bf[n].ud=lat.ud;

   lat.ud=ud;

   for (n=0;n<BLK_GRIDS;n++)
   {
      if ((gfs+n)!=gf)
         gfs[n].ubd=ud;
   }
}


static void GridAssignedSwd2swbgr(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      bf[n].sw[0]=lat.swd[0];
      bf[n].sw[1]=lat.swd[1];
      bf[n].sw[2]=lat.swd[2];
   }
}


static void GridAssignedSwd2swdbgr(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
      {
         bf[n].swd[0]=lat.swd[0];
         bf[n].swd[1]=lat.swd[1];
         bf[n].swd[2]=lat.swd[2];
      }
      else if ((*gf).shud==1)
      {
         bf[n].swd[0]=0;
         bf[n].swd[1]=0;
         bf[n].swd[2]=0;
      }
   }
}


static void GridAssignedSwdbgr2swd(int nb)
{
   blk_flags_t *bf;

   GridBalanceFlags();
   
   bf=(*gf).bf;
   lat.swd[0]=(*bf).swd[0];
   lat.swd[1]=(*bf).swd[1];
   lat.swd[2]=(*bf).swd[2];   
}


static void GridComputedSwb(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
      bf[n].swb=(*gf).ubd;
}


static void BlkNewActiveUd(int nb)
{
   int n,nbf,nt;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;
   nt=next_tag();

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
         bf[n].ud=nt;
      else if ((*gf).shud==1)
      {
         bf[n].ud=0;
         bf[n].ubd=0;
         bf[n].bcd=0;
      }
   }
}


static void BlkAssignedUd2u(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
      {
         bf[n].u=bf[n].ud;
         bf[n].ub=bf[n].ubd;
         bf[n].bc=bf[n].bcd;
      }
      else if ((*gf).shu==1)
      {
         bf[n].u=0;
         bf[n].ub=0;
         bf[n].bc=0;
      }
   }
}


static void BlkComputedSwd(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
      {
         bf[n].swd[0]=bf[n].ud;
         bf[n].swd[1]=0;
         bf[n].swd[2]=0;
      }
      else if ((*gf).shud==1)
      {
         bf[n].swd[0]=0;
         bf[n].swd[1]=0;
         bf[n].swd[2]=0;
      }
   }
}


static void BlkInvertedSwdE(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
         bf[n].swd[1]^=1;
   }
}


static void BlkInvertedSwdO(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
         bf[n].swd[2]^=1;
   }
}


static void BlkAssignedSwd2sw(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
      {
         bf[n].sw[0]=bf[n].swd[0];
         bf[n].sw[1]=bf[n].swd[1];
         bf[n].sw[2]=bf[n].swd[2];
      }
      else if ((*gf).shu==1)
      {
         bf[n].sw[0]=0;
         bf[n].sw[1]=0;
         bf[n].sw[2]=0;
      }
   }
}


static void BlkInvertedSwE(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
         bf[n].sw[1]^=1;
   }
}


static void BlkInvertedSwO(int nb)
{
   int n,nbf;
   blk_flags_t *bf;

   nbf=(*gf).nb;
   bf=(*gf).bf;

   for (n=0;n<nbf;n++)
   {
      if ((nb==nbf)||(nb==n))
         bf[n].sw[2]^=1;
   }
}


static void set_blk_events(void)
{
   blk_event_fcts[ASSIGNED_U2UBGR]=GridAssignedU2ubgr;
   blk_event_fcts[ASSIGNED_UD2UBGR]=GridAssignedUd2ubgr;
   blk_event_fcts[ASSIGNED_UD2UDBGR]=GridAssignedUd2udbgr;
   blk_event_fcts[SWAPPED_ACTIVE]=GridSwappedActive;
   blk_event_fcts[ASSIGNED_SWD2SWBGR]=GridAssignedSwd2swbgr;
   blk_event_fcts[ASSIGNED_SWD2SWDBGR]=GridAssignedSwd2swdbgr;
   blk_event_fcts[ASSIGNED_SWDBGR2SWD]=GridAssignedSwdbgr2swd;
   blk_event_fcts[COMPUTED_SWB]=GridComputedSwb;

   blk_event_fcts[NEW_ACTIVE_UD]=BlkNewActiveUd;
   blk_event_fcts[ASSIGNED_UD2U]=BlkAssignedUd2u;
   blk_event_fcts[COMPUTED_SWD]=BlkComputedSwd;
   blk_event_fcts[INVERTED_SWD_E]=BlkInvertedSwdE;
   blk_event_fcts[INVERTED_SWD_O]=BlkInvertedSwdO;
   blk_event_fcts[ASSIGNED_SWD2SW]=BlkAssignedSwd2sw;
   blk_event_fcts[INVERTED_SW_E]=BlkInvertedSwE;
   blk_event_fcts[INVERTED_SW_O]=BlkInvertedSwO;
}

#endif
