/*
* Copyright (C) 2001-2008, CompHEP Collaboration
* Copyright (C) 1997, Alexander Pukhov 
* Made by      S.Shichanin
* at           03 April 1991
* Last update  26 June  1991
* ------------------------------------------------------
* $Id$
*
* $Log$
*/
#include <math.h>

#include "service2/include/chep_limits.h"
#include "service2/include/tptcmac.h"
#include "service2/include/4_vector.h"
#include "chep_crt/include/chep_crt.h"

#include "plot/include/plot.h"

#include "err_code.h"
#include "num_serv.h"
#include "const.h"
#include "out_ext.h"
#include "param.h"
#include "width_12.h"

static double totcoef;



typedef struct canal_12
  {
    char prtclnames[2][6];
    double width;
  }
canal_12;


static canal_12 *allcanal;
static double width12, mm1, mm2, mm3;


static void 
sortcanals (void)
{
  int i;
  canal_12 buff;

  i = 0;
  while (i < nprc_ - 1)
    {
      if (allcanal[i].width < allcanal[i + 1].width)
	{
	  buff = allcanal[i];
	  allcanal[i] = allcanal[i + 1];
	  allcanal[i + 1] = buff;
	  if (i != 0)
	    i--;
	}
      else
	i++;
    }
}


static void 
decay12information (void)
{
  byte xcount, ycount;
  int i;

  clrbox (1, 16, 80, 24);
  goto_xy (1, 16);
  scrcolor (Red, BGmain);
  print (" Total width : ");
  scrcolor (FGmain, BGmain);
  if (err_code == 0)
    print ("%13E GeV", width12);
  else
    print (" incorrect       ");
  if (width12 > 1.E-20 && err_code == 0)
    {
      sortcanals ();
      goto_xy (1, 17);
      scrcolor (Red, BGmain);
      print (" Modes and fractions :");
      xcount = 31;
      ycount = 18;
      for (i = 0; i < nprc_; i++)
	{
	  if (ycount < maxRow ())
	    {
	      goto_xy (xcount, ycount - 1);
	      scrcolor (Blue, BGmain);
	      print ("%s %s -  ", allcanal[i].prtclnames[0],
		     allcanal[i].prtclnames[1]);

	      scrcolor (FGmain, BGmain);
	      print ("  %5.2lG%%", 100 * allcanal[i].width / width12);
	      xcount += 30;
	      if (xcount > maxCol ())
		{
		  xcount = 1;
		  ++(ycount);
		}
	    }
	}
    }
  scrcolor (FGmain, BGmain);
}


static void 
calcwidth12 (void)
{
  int i, nsub;
  double pmass[3];
  double pRestOut;

  err_code = 0;
  width12 = 0.0;

  for (nsub = 1; nsub <= nprc_; nsub++)		/* err_code == 0 */
    {

      for (i = 0; i <= 2; i++)
	pinf_ (nsub, i + 1, NULL, pmass + i);

      if (pmass[0] <= pmass[1] + pmass[2])
	allcanal[nsub - 1].width = 0.0;
      else
	{


	  mm1 = pmass[0] * pmass[0];
	  mm2 = pmass[1] * pmass[1];
	  mm3 = pmass[2] * pmass[2];

	  pRestOut = sqrt ((mm1 - (mm2 + mm3 + 2. * pmass[1] * pmass[2])) *
			   (mm1 - (mm2 + mm3 - 2. * pmass[1] * pmass[2]))
	    ) / (2 * pmass[0]);
	  totcoef = pRestOut / (8. * M_PI * mm1);

	  for (i = 1; i < 12; i++)
	    pvect[i] = 0;
	  pvect[0] = pmass[0];
	  pvect[7] = pRestOut;
	  pvect[4] = sqrt (pvect[7] * pvect[7] + mm2);
	  pvect[11] = -pvect[7];
	  pvect[8] = sqrt (pvect[7] * pvect[7] + mm3);

	  allcanal[nsub - 1].width = totcoef * sqme_ (nsub, pvect, &err_code);
	}
      width12 += allcanal[nsub - 1].width;
      for (i = 1; i <= 2; i++)
	pinf_ (nsub, i + 1, allcanal[nsub - 1].prtclnames[i - 1], NULL);
    }
  if (err_code != 0)
    errormessage ();
}


static double 
totwidth (void)
{
  calcwidth12 ();
  return width12;
}


void 
decay12 (void)
{
  int k;
  void *pscr = NULL;
  allcanal = (canal_12 *) malloc (sizeof (canal_12) * nprc_);

  k = 1;
  calcwidth12 ();
  decay12information ();
  do
    {
      menu1 (56, 6, "", "\026"
	     " Model parameters     "
	     " Parameter dependence ", "n_13_*", &pscr, &k);
      switch (k)
	{
	case 1:		/*  ******* Change parameter ********  */
	  if (change_parameter (55, 10))
	    {
	      calcwidth12 ();
	      decay12information ();
	    }
	  break;

	case 2:
	  paramdependence (totwidth, processch, "Width  [GeV]");
	}			/*  switch  */
    }
  while (k != 0);
  free (allcanal);
  clrbox (1, 16, 80, 24);
}
