/*
* Copyright (C) 2007-2009, CompHEP Collaboration
* Author: Slava Bunichev
* ------------------------------------------------------
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#include "service2/include/chep_limits.h"
#include "service2/include/files.h"
#include "service2/include/unix_utils.h"
#include "service2/include/syst.h"
#include "chep_crt/include/chep_crt.h"

#include "roothisto.h"

static void
readtext (char *fname)
{
  FILE *txt;

  trim (fname);
  txt = fopen (fname, "r");
  if (txt == NULL)
    {
      warnanykey (10, 10, " File not found ");
      return;
    }
  showtext (28, 10, 70, 15, "", txt);
  fclose (txt);
}


static int
graphcolor (int first)
{
  int color;

  if (first == 1)
    color = 4;
  if (first == 2)
    color = 2;
  if (first == 3)
    color = 3;
  if (first == 4)
    color = 6;
  if (first == 5)
    color = 7;
  if (first == 6)
    color = 9;
  if (first == 7)
    color = 6;
  if (first == 8)
    color = 8;
  if (first == 9)
    color = 3;
  if (first == 10)
    color = 1;
  if (first == 11)
    color = 2;
  if (first == 12)
    color = 4;
  if (first == 13)
    color = 5;
  if (first == 14)
    color = 8;
  if (first == 15)
    color = 9;

  if (first > 15)
    color = 1;

  return (color);
}


static int
graphstyle (int first)
{
  int style;

  if (first == 1)
    style = 1;
  if (first == 2)
    style = 2;
  if (first == 3)
    style = 3;
  if (first == 4)
    style = 4;

  if (first == 5)
    style = 1;
  if (first == 6)
    style = 2;
  if (first == 7)
    style = 3;
  if (first == 8)
    style = 4;

  if (first == 9)
    style = 1;
  if (first == 10)
    style = 2;
  if (first == 11)
    style = 3;
  if (first == 12)
    style = 4;

  if (first == 13)
    style = 1;
  if (first == 14)
    style = 2;
  if (first == 15)
    style = 3;

  if (first > 15)
    style = 1;

  return (style);
}


static void
graph_identity (FILE * outfile, int first)
{
  if (first == 1)
    f_printf (outfile, "//solid, light blue\n");
  if (first == 2)
    f_printf (outfile, "//dashed, light red\n");
  if (first == 3)
    f_printf (outfile, "//doted, dark green\n");
  if (first == 4)
    f_printf (outfile, "//dots and dashes, dark magenta\n");

  if (first == 5)
    f_printf (outfile, "//solid, dark green and blue\n");
  if (first == 6)
    f_printf (outfile, "//dashed, medium blue\n");
  if (first == 7)
    f_printf (outfile, "//doted, light magenta\n");
  if (first == 8)
    f_printf (outfile, "//dots and dashes, medium green\n");

  if (first == 9)
    f_printf (outfile, "//solid, light green\n");
  if (first == 10)
    f_printf (outfile, "//dashed, grey\n");
  if (first == 11)
    f_printf (outfile, "//doted, dark red\n");
  if (first == 12)
    f_printf (outfile, "//dots and dashes, dark blue\n");

  if (first == 13)
    f_printf (outfile, "//solid, dark yellow\n");
  if (first == 14)
    f_printf (outfile, "//dashed, very dark green\n");
  if (first == 15)
    f_printf (outfile, "//doted, very dark blue\n");

  if (first > 15)
    f_printf (outfile, "//solid, black\n");
}

static void
writeroothist (char *menustr, int numstring)
{
  int i, k;
  int title = 0;
  int combine = 0;
  int dim;
  int old_dim;
  int first = 1;
  int color;
  int style;
  char c;
  char old_xstr[50] = { 0 };
  char upstr[50] = { 0 };
  char x_str[50] = { 0 };
  char y_str[50] = { 0 };
  char function[5] = { 0 };
  char units[5] = { 0 };
  double old_xMin;
  double old_xMax;
  double xMin, xMax, yMin, yMax;
  double dX;
  double totYMin = 0, totYMax = 0;

  char infname[STRSIZ];
  midstr outname_C;
  midstr outname_eps;
  midstr outname_jpg;
  midstr buff;
  FILE *outfile;

  nextFileName (outname_C, "combine_", ".C");
  strcpy (outname_eps, outname_C);
  strcpy (outname_jpg, outname_C);
  strcat (outname_C, ".C");
  strcat (outname_eps, ".eps");
  strcat (outname_jpg, ".jpg");

  first = 1;
  for (i = 1; i <= numstring; i++)
    {
      sprintf (infname, "%.14s", menustr + i * 15 - 14);
      trim (infname);
      if (menustr[i * 15] == '+')
	{
	  FILE *infile = fopen (infname, "r");
	  if (infile == NULL)
	    {
	      warnanykey (10, 10, " File not found ");
	      return;
	    }

	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      upstr[k] = c;
	      k++;
	    }
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      x_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//x-axis from %le to %le N_bins= %d\n", &xMin,
		  &xMax, &dim);
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      y_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//y-axis from %le to %le", &yMin, &yMax);
	  fscanf (infile, "//combine= %d", &combine);

	  if (first != 1)
	    {
	      if (combine != 0)
		{
		  warnanykey (10, 10, " Combined distribution ");
		  fclose (infile);
		  return;
		}
	      if (strncmp (x_str, old_xstr, 2) != 0)
		{
		  warnanykey (10, 10, " Different functions ");
		  fclose (infile);
		  return;
		}

	      if (xMin != old_xMin)
		{
		  warnanykey (10, 10, " Different range ");
		  fclose (infile);
		  return;
		}
	      if (xMax != old_xMax)
		{
		  warnanykey (10, 10, " Different range ");
		  fclose (infile);
		  return;
		}
	      if (dim != old_dim)
		{
		  warnanykey (10, 10, " Different binning ");
		  fclose (infile);
		  return;
		}
	    }
	  fclose (infile);

	  if (first == 1)
	    {
	      totYMin = yMin;
	      totYMax = yMax;
	    }

	  if (yMin < totYMin)
	    totYMin = yMin;
	  if (yMax > totYMax)
	    totYMax = yMax;

	  strcpy (old_xstr, x_str);

	  for (k = 0; k < 50; k++)
	    {
	      upstr[k] = 0;
	      x_str[k] = 0;
	      y_str[k] = 0;
	    }

	  old_xMin = xMin;
	  old_xMax = xMax;
	  old_dim = dim;
	  first++;
	}
    }

  outfile = fopen (outname_C, "w");
  if (NULL == outfile)
    {
      sprintf (buff, "Error! I can not open the file\n%s", outname_C);
      messanykey (10, 12, buff);
      return;
    }

  first = 1;
  for (i = 1; i <= numstring; i++)
    {
      sprintf (infname, "%.14s", menustr + i * 15 - 14);
      trim (infname);
      if (menustr[i * 15] == '+')
	{
	  FILE *infile = fopen (infname, "r");
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      upstr[k] = c;
	      k++;
	    }
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      x_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//x-axis from %le to %le N_bins= %d\n", &xMin,
		  &xMax, &dim);
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      y_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//y-axis from %le to %le", &yMin, &yMax);
	  fscanf (infile, "//combine= %d", &combine);
	  fclose (infile);

	  if (first == 1)
	    {
	      f_printf (outfile, "%s\n", upstr);
	      f_printf (outfile, "%s\n", x_str);
	      f_printf (outfile, "//x-axis from %e to %e N_bins= %d\n", xMin,
			xMax, dim);
	      f_printf (outfile, "%s\n", y_str);
	      f_printf (outfile, "//y-axis from %e to %e\n", yMin, yMax);
	      f_printf (outfile, "//combine= 1\n");
	    }

	  else
	    {
	      f_printf (outfile,
			"//---------------------GRAPH%d-----------------------\n",
			first);
	      f_printf (outfile, "%s\n", upstr);
	      f_printf (outfile, "%s\n", x_str);
	    }

	  graph_identity (outfile, first);

	  for (k = 0; k < 50; k++)
	    {
	      upstr[k] = 0;
	      x_str[k] = 0;
	      y_str[k] = 0;
	    }
	  first++;
	}
    }

  first = 1;
  for (i = 1; i <= numstring; i++)
    {
      sprintf (infname, "%.14s", menustr + i * 15 - 14);
      trim (infname);
      if (menustr[i * 15] == '+')
	{
	  FILE *infile = fopen (infname, "r");
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      upstr[k] = c;
	      k++;
	    }
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      x_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//x-axis from %le to %le N_bins= %d\n", &xMin,
		  &xMax, &dim);
	  k = 0;
	  while ((c = getc (infile)) != '\n')
	    {
	      y_str[k] = c;
	      k++;
	    }
	  fscanf (infile, "//y-axis from %le to %le", &yMin, &yMax);
	  fscanf (infile, "//combine= %d", &combine);

	  if (first == 1)
	    {
	      f_printf (outfile, "\n\n\n\n{\n");
	      f_printf (outfile, "gROOT->Reset();\n\n");
	      f_printf (outfile,
			"TCanvas *c1 = new TCanvas(\"c1\",\" \",200,100,700,500);\n");
	      f_printf (outfile, "c1->SetFillColor(0);\n");
	      f_printf (outfile, "c1->SetBorderMode(0);\n");
	      f_printf (outfile, "c1->SetFrameBorderMode(0);\n");
	      f_printf (outfile, "gStyle->SetOptTitle(kFALSE);\n\n");
	      f_printf (outfile,
			"//c1->SetLogy(1);  //Set Logarithmic Scale;\n\n\n");
	      if (dim != 0)
		dX = (xMax - xMin) / dim;
	      f_printf (outfile, "double Xarray[%d];\n", dim);
	      f_printf (outfile,
			"for(int i=0;i<%d;i++) Xarray[i]=%e+i*%e;\n\n", dim,
			xMin, dX);

	    }
	  f_printf (outfile, "// GRAPH %d ---\n", first);

	  while ((getc (infile) != 'Y') ||
		 (getc (infile) != 'a') ||
		 (getc (infile) != 'r') ||
		 (getc (infile) != 'r') ||
		 (getc (infile) != 'a') || (getc (infile) != 'y'))
	    {
	    }
	  while ((c = getc (infile)) != '{')
	    {
	    }

	  f_printf (outfile, "double Yarray%d[%d]={", first, dim);
	  while ((c = getc (infile)) != '}')
	    {
	      putc (c, outfile);
	    }
	  fclose (infile);

	  f_printf (outfile, "};\n");
	  f_printf (outfile,
		    "TGraph *gr%d = new TGraph(%d,Xarray,Yarray%d);\n", first,
		    dim, first);
	  if (first == 1)
	    f_printf (outfile, "TGaxis::SetMaxDigits(3);\n");
	  f_printf (outfile, "gr%d->SetLineWidth(2);\n", first);
	  color = graphcolor (first);
	  f_printf (outfile, "gr%d->SetLineColor(%d);\n", first, color);
	  style = graphstyle (first);
	  f_printf (outfile, "gr%d->SetLineStyle(%d);\n", first, style);

	  if (first == 1)
	    {
	      if (strncmp (x_str, "//Transverse momentum Pt%d", 23) == 0)
		{
		  strcpy (function, "P_{T}");
		  strcpy (units, "GeV");
		  title = 1;
		}
	      if (strncmp (x_str, "//Mass", 6) == 0)
		{
		  strcpy (function, "M");
		  strcpy (units, "GeV");
		  title = 1;
		}
	      if (strncmp (x_str, "//Energy E", 10) == 0)
		{
		  strcpy (function, "E");
		  strcpy (units, "GeV");
		  title = 1;
		}
	      if (strncmp (x_str, "//Angle", 7) == 0)
		{
		  strcpy (function, "#theta");
		  strcpy (units, "deg");
		  title = 1;
		}
	      if (strncmp (x_str, "//pseudo-rapidity_", 17) == 0)
		{
		  strcpy (function, "#eta");
		  title = 2;
		}
	      if (strncmp (x_str, "//Rapidity_", 11) == 0)
		{
		  strcpy (function, "#y");
		  title = 2;
		}
	      if (strncmp (x_str, "//Cosine", 8) == 0)
		{
		  strcpy (function, "cos(#theta)");
		  title = 2;
		}
	      if (strncmp (x_str, "//Sqrt", 6) == 0)
		{
		  strcpy (function, "#sqrt{s}");
		  title = 0;
		}

	      if (title == 0)
		{
		  f_printf (outfile, "gr1->GetXaxis()->SetTitle(\"%s\");\n",
			    x_str);
		  f_printf (outfile,
			    "gr1->GetYaxis()->SetTitle(\"#sigma, fb\");\n");
		}
	      if (title == 1)
		{
		  f_printf (outfile,
			    "gr1->GetXaxis()->SetTitle(\"%s, %s\");\n",
			    function, units);
		  f_printf (outfile,
			    "gr1->GetYaxis()->SetTitle(\"d#sigma/d%s, fb/%s\");\n",
			    function, units);
		}
	      if (title == 2)
		{
		  f_printf (outfile, "gr1->GetXaxis()->SetTitle(\"%s\");\n",
			    function);
		  f_printf (outfile,
			    "gr1->GetYaxis()->SetTitle(\"d#sigma/d%s, fb\");\n",
			    function);
		}

	      totYMax = totYMax + totYMax * 0.1;
	      f_printf (outfile, "gr1->SetMinimum(%e);\n", totYMin);
	      f_printf (outfile, "gr1->SetMaximum(%e);\n", totYMax);
	      f_printf (outfile, "gr1->Draw(\"AC\");\n\n");
	    }
	  else
	    {
	      f_printf (outfile, "gr%d->Draw(\"C\");\n\n", first);
	    }
	  first++;
	}
    }

  f_printf (outfile, "c1->Print(\"%s\");\n", outname_eps);
  f_printf (outfile, "c1->Print(\"%s\");\n", outname_jpg);
  f_printf (outfile, "}\n");
  fclose (outfile);
  sprintf (buff, " You can find results in the file\n%s", outname_C);
  messanykey (10, 12, buff);
}


void
combine_root (void)
{
  int i, k, numstring = 0;
  int doserror;
  char f_name[STRSIZ];
  char menustr[2016];
  void *pscr2 = NULL;
  searchrec s;

  menustr[0] = 15;

  k = 1;
  strcpy (f_name, "*.C");
  doserror = find_first (f_name, &s, anyfile);
  while (doserror == 0 && k <= 2000)
    {
      for (i = 1; (i <= strlen (s.name)) && (i <= 15); i++)
	menustr[k++] = s.name[i - 1];
      for (i = strlen (s.name) + 1; i <= 15; i++)
	menustr[k++] = ' ';
      doserror = find_next (&s);
      numstring++;
    }
  menustr[k] = 0;
  if (0 == menustr[1])
    {
      messanykey (10, 15, "directory  is empty");
      return;
    }

  k = 1;
  do
    {
      menu1 (10, 10, "", menustr, "", &pscr2, &k);
      if (k > 0)
	{
	  sprintf (f_name, "%.14s", menustr + k * 15 - 14);
	  readtext (f_name);
	  if (menustr[k * 15] == ' ')
	    menustr[k * 15] = '+';
	  else
	    menustr[k * 15] = ' ';
	}
    }
  while (k != 0);
  writeroothist (menustr, numstring);
}
