#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "../src/param.h"
#include "../src/tdef.h"
#include "../src/common.c"

#include "../src/libutility/utility.h"

double dw[8];
float  fw[8];

int main(argc,argv)
int argc;
char **argv;
{
   int           j, BUFSIZE;
   long unsigned i;
   double        x_fac, v_fac, m_fac, v_mean;
   long          np;
   FILE          *fpin, *fpout;
   char          outdata[MAXSTRING];
   int           SWAPBYTES;
   
   if(argc<2)
    {
      fprintf(stderr,"usage: %s AMIGAlightcone_file\n",*argv);
      exit(1);
    }
   if((fpin=fopen(argv[1],"rb"))==NULL)
    {
      printf("Cannot open %s", argv[1]);
      exit(1);
    }
   
   printf("=========================================================\n");
   printf("  Read AMIGA lightcone binary and convert to ASCII file\n");
   printf("=========================================================\n");
   strcpy(outdata,argv[1]);
   strcat(outdata,".ascii");
   fprintf(stderr,"writing ASCII file: %s\n\n",outdata);
   
   if((fpout=fopen(outdata,"w"))==NULL) 
    {
      printf("Cannot open %s", outdata);
      exit(1);
    }
   
   /* read AMIGA header */
   read_amiga_header(fpin, &io, &SWAPBYTES);
   
  /* print some information */
  printf("information on current output data:\n");
  printf("-----------------------------------\n");
  printf("%s\n\n",io.header.header);
  printf("multi-mass       = %d\n",io.header.multi_mass);
  printf("double precision = %d\n",io.header.double_precision);
  printf("no_part          = %ld\n",io.header.no_part);
  printf("boxsize          = %g\n",io.header.boxsize);
  printf("Omega0           = %g\n",io.header.omega0);
  printf("Lambda0          = %g\n",io.header.lambda0);
  printf("z_initial        = %g (a=%lf)\n",
		 1.0/io.header.a_initial-1.0,io.header.a_initial);
  printf("z_current        = %g (a=%lf)\n",
		 1.0/io.header.a_current-1.0,io.header.a_current);
  printf("no_timestep      = %d\n",io.header.no_timestep);
   
#ifdef HEADER 
  fprintf(fpout,"#%s\n",io.header.header);
  fprintf(fpout,"#no_part     = %ld\n",io.header.no_part);
  fprintf(fpout,"#boxsize     = %g\n",io.header.boxsize);
  fprintf(fpout,"#Omega0      = %g\n",io.header.omega0);
  fprintf(fpout,"#Lambda0     = %g\n",io.header.lambda0);
  fprintf(fpout,"#z_initial   = %g (a=%g)\n",
		  1.0/io.header.a_initial-1.0,io.header.a_initial);
  fprintf(fpout,"#z_current   = %g (a=%g)\n",
		  1.0/io.header.a_current-1.0,io.header.a_current);
  fprintf(fpout,"#no_timestep = %d\n",io.header.no_timestep);
#endif

  x_fac  = io.header.boxsize;
  v_fac  = io.header.boxsize * H0 / io.header.a_current;
#ifdef XDOT
  v_fac  = io.header.boxsize * H0 / io.header.a_current / io.header.a_current;
#endif
  m_fac  = io.header.pmass;
   
  if(io.header.multi_mass == 1)
	 BUFSIZE = 8;
  else
	 BUFSIZE = 7;
   
  np=0;
  v_mean = 0.0;
  while(1)
   {
	 if(io.header.double_precision == 1)
	  {		  
		for(j=0; j<BUFSIZE; j++)
		   ReadDouble(fpin,&(dw[j]),SWAPBYTES);
	  }
	 else
	  {
		for(j=0; j<BUFSIZE; j++)
		 {
		   ReadFloat(fpin,&(fw[j]),SWAPBYTES);
		   dw[j] = (double) fw[j];
		 }
	  }
	 if(feof(fpin)) break;
	 
	 /* get physical positions in Mpc/h */
	 dw[0] *= x_fac;
	 dw[2] *= x_fac;
	 dw[4] *= x_fac;
	 
	 /* get physical velocities in km/s */
	 dw[1] *= v_fac;
	 dw[3] *= v_fac;
	 dw[5] *= v_fac;
    
	 fprintf(fpout,"%.6g %.6g %.6g %.6g %.6g %.6g %.6g",
			 dw[0],dw[2],dw[4],dw[1],dw[3],dw[5],dw[6]);
	 
	 if(io.header.multi_mass == 1)
		fprintf(fpout," %.6g\n",dw[7]*m_fac);
	 else
		fprintf(fpout,"\n");
	 
	 np++;
	 v_mean += sqrt(pow2(dw[1]) + pow2(dw[3]) + pow2(dw[5]));
   }
	 
	 fprintf(stderr,"v_mean = %g (%ld particles)\n",v_mean/(double)np,np);
}

