#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <io.h>
#include "g_lib.h"

double SetTime(double t, double *P, int iN);
double GetTime(int iYear, int iMonth, int iDay, int iMinute);
int GetYear(double *t);
int GetMonth(double *t, int Year);
int GetDay(double *t);
int GetHour(double *t);
int GetMinute(double *t);
void GetConst(int handle, tss1 *ss1);

void create_pattern_0(char *name); //without constants
void create_pattern_1(char *name1, char *name2, tss1 *ss1); //with constants

void simple_report(char *name, char *rep, int begr, int endr);
void simple_report_1(char *name, char *rep, int begr, int endr);



double SetTime(double t, double *P, int iN)
{
  t=t+(*(P+iN))/1800.0;
  return t;
}


double GetTime(int iYear, int iMonth, int iDay, int iMinute)
{
  double t,t1;
  int i=0,DayperYear=0,LeapYear=1;

  LeapYear = iYear%4;
  t1=floor(((double)iYear-1.0)/4);
  t=(((double)iYear-1.0)*365.0+t1)*24.0;
  while (++i!=iMonth)
  {
    if (i==4 || i==6 || i==9 || i==11) DayperYear+=30;
    else if (i==2) {
	 if (!LeapYear) DayperYear+=29;
	 else DayperYear+=28;
    }
    else DayperYear+=31;
  }
  t = t+((double)DayperYear+((double)iDay-1.0))*24.0+(double)iMinute/60.0;
  return t;
}


int GetYear(double *t)
{
  double t1;
  int LY,Year;

  t1=(*t)/24.0;                               /* кол-во дней */
  LY=floor(t1/(365.0*4.0+1.0));               /* кол-во полных 4-х летий */
  t1=t1-((double)LY*(365.0*4.0+1.0));
  Year=floor(t1/365.0);                       /* кол-во полных лет */
  if (Year == 4) Year=3;                      /* если год високосный */
  t1=t1-(double)Year*365.0;
  Year+=LY*4;
  *t=t1*24.0;
  return (Year+1);
}


int GetMonth(double *t, int Year)
{
  double t1,tL;
  int i=0;


  t1 = (*t)/24.0;
  while (t1>=0)
  {
    tL=t1;
    i++;
    if(i==4 || i==6 || i==9 || i==11) t1=t1-30.0;
    else if (i==2)
	 {
	   if (fmod(Year,4)==0) t1=t1-29.0;
	   else t1=t1-28.0;
	 }
    else t1=t1-31.0;
  }
  *t=tL*24.0;
  return (i);
}


int GetDay(double *t)
{
  int t1;

  t1=floor((*t)/24);
  *t=(*t)-(double)t1*24.0;
  return (t1+1);
}


int GetHour(double *t)
{
  int t1;

  t1=floor(*t);
  *t=(*t)-(double)t1;
  return t1;
}


int GetMinute(double *t)
{
  return (floor((*t)*60.0));
}


void GetConst(int handle, tss1 *ss1)
{
   lseek(handle,0L,0);
   _read(handle,ss1,sizeof(tss1));
}


void create_pattern_0(char *name)
{
  FILE *f;

    if ((f=fopen(name,"w")) == NULL) {
      printf("\nCan't open file %s.\n",name);
    }
    else {
      fprintf(f,"#Format of the file:\n");
      fprintf(f,"$format\n1\n");
      fprintf(f,"#Constants:\n");
      fprintf(f,"$const\n");
      fprintf(f,"#Scheme of measurements c4:\n0\n");
      fprintf(f,"#Mass of the ball M(g):\n0\n");
      fprintf(f,"#Mass of the load m1(g):\n0\n");
      fprintf(f,"#Mass of the balance-beam m2(g):\n0\n");
      fprintf(f,"#Length of the load's arm L5(cm):\n0\n");
      fprintf(f,"#Length of the balance-beam's arm L6(cm):\n0\n");
      fprintf(f,"#Moment of inertia (body w/out balance-beam) J1(g*cm*cm):\n0\n");
      fprintf(f,"#Constant of the optical system c3:\n0\n");
      fprintf(f,"#Positions of the photodetectors c2{1(dissym.), 2(sym.)}:\n0\n");
      fprintf(f,"#Oscillation period without attracting masses T0(s):\n0\n");
      fprintf(f,"#Correction for residual squares of the amplitudes c11(s/(rad*rad)):\n0\n");
      fprintf(f,"#Correction for the 4-th difference of the amplitudes c12(s/(rad*rad*rad*rad)):\n0\n");
      fprintf(f,"#Correction for gradients of external field c8:\n0\n");
      fprintf(f,"#Number of the balance-beam's segments n:\n0\n");
      fprintf(f,"#Distance between centers of the attracting masses on vertical line h(cm):\n0\n");
      fprintf(f,"#Interval between measurements tau(ms):\n0\n");
      fprintf(f,"#Correction for diameter of the balance-beam c51:\n0\n");
      fprintf(f,"#Correction for length of the balance-beam c52:\n0\n");
      fprintf(f,"#Diameter of the balance-beam's ball d1(cm):\n0\n");
      fprintf(f,"#Diameter of the balance-beam d2(cm):\n0\n");
      fprintf(f,"#First integration step dt(s):\n0\n");
      fprintf(f,"#Number of the integration steps c6:\n0\n");
      fprintf(f,"#Value of the amplitude (choice of the calculation method) fi0:\n0\n");
      fprintf(f,"#Gravitational constant G*1e-8(cm*cm*cm/g*s*s):\n0\n");
      fprintf(f,"#Bound of G measurement:\n0\n");
      fprintf(f,"#Used apertures N:\n000000000000000\n");
      fprintf(f,"#Distance between axis of the revolution and centers of the apertures L1-15:\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n0\n");
      fprintf(f,"#Data of the expirement (0 - no, 1 - yes):\n$data\n0\n");
      fprintf(f,"#Date of the experiment (day month year):\n$date\n00 00 0000\n");
      fprintf(f,"#Time (hour minute):\n$time\n00 00\n");
      fprintf(f,"#NLast N:\n$nlast\n0\n$n\n0\n");
      fprintf(f,"#Data:\n$database\n");
      fprintf(f,"#  T1      T2      T3      T4      T5\n0000000 0000000 0000000 0000000 0000000\n");
      fclose(f);
      printf("\nConstants pattern was created in %s.\n",name);
    }
}


void create_pattern_1(char *name1,char *name2, tss1 *ss1)
{
  FILE *f;
  int data_handle;
  int i;

    if ((data_handle=_open(name1,O_RDONLY)) == -1) {
      printf("\nCan't open file %s.\n",name1);
      return;
    }
    if ((f=fopen(name2,"w")) == NULL) {
      printf("\nCan't create file %s.\n",name2);
      return;
    }
    GetConst(data_handle,ss1);
    fprintf(f,"#Format of the file:\n");
    fprintf(f,"$format\n1\n");
    fprintf(f,"#Constants:\n");
    fprintf(f,"$const\n");
    fprintf(f,"#Scheme of measurements c4:\n%d\n",ss1->c4);
    fprintf(f,"#Mass of the ball M(g):\n%f\n",ss1->M);
    fprintf(f,"#Mass of the load m1(g):\n%f\n",ss1->m1);
    fprintf(f,"#Mass of the balance-beam m2(g):\n%f\n",ss1->m2);
    fprintf(f,"#Length of the load's arm L5(cm):\n%f\n",ss1->L5);
    fprintf(f,"#Length of the balance-beam's arm L6(cm):\n%f\n",ss1->L6);
    fprintf(f,"#Moment of inertia (body w/out balance-beam) J1(g*cm*cm):\n%f\n",ss1->J1);
    fprintf(f,"#Constant of the optical system c3:\n%f\n",ss1->c3);
    fprintf(f,"#Positions of the photodetectors c2{1(dissym.), 2(sym.)}:\n%d\n",ss1->c2);
    fprintf(f,"#Oscillation period without attracting masses T0(s):\n%f\n",ss1->T0);
    fprintf(f,"#Correction for residual squares of the amplitudes c11(s/(rad*rad)):\n%f\n",ss1->c11);
    fprintf(f,"#Correction for the 4-th difference of the amplitudes c12(s/(rad*rad*rad*rad)):\n%f\n",ss1->c12);
    fprintf(f,"#Correction for gradients of external field c8:\n%f\n",ss1->c8);
    fprintf(f,"#Number of the balance-beam's segments n:\n%d\n",ss1->n);
    fprintf(f,"#Distance between centers of the attracting masses on vertical line h(cm):\n%f\n",ss1->h);
    fprintf(f,"#Interval between measurements tau(ms):\n%f\n",ss1->tau);
    fprintf(f,"#Correction for diameter of the balance-beam c51:\n%f\n",ss1->c51);
    fprintf(f,"#Correction for length of the balance-beam c52:\n%f\n",ss1->c52);
    fprintf(f,"#Diameter of the balance-beam's ball d1(cm):\n%f\n",ss1->d1);
    fprintf(f,"#Diameter of the balance-beam d2(cm):\n%f\n",ss1->d2);
    fprintf(f,"#First integration step dt(s):\n%f\n",ss1->dt);
    fprintf(f,"#Number of the integration steps c6:\n%d\n",ss1->c6);
    fprintf(f,"#Value of the amplitude (choice of the calculation method) fi0:\n%f\n",ss1->fi0);
    fprintf(f,"#Gravitational constant G*1e-8(cm*cm*cm/g*s*s):\n%f\n",ss1->G*1e+8);
    fprintf(f,"#Bound of G measurement:\n%f\n",ss1->c7);
    fprintf(f,"#Used apertures N:\n");
    i=0;
    while (i++ < 15)
    {
      if (ss1->C[i-1]) fprintf(f,"1");
      else fprintf(f,"0");
    }
    fprintf(f,"\n");

    fprintf(f,"#Distance between axis of the revolution and centers of the apertures L1-15:\n");
    i=0;
    while (i++ < 15)
    {
      if (ss1->C[i-1]) fprintf(f,"%f\n",ss1->L[i-1]);
      else fprintf(f,"0\n");
    }

    fprintf(f,"#Data of the expirement (0 - no, 1 - yes):\n$data\n0\n");
    fprintf(f,"#Date of the experiment (day month year):\n$date\n00 00 0000\n");
    fprintf(f,"#Time (hour minute):\n$time\n00 00\n");
    fprintf(f,"#NLast N:\n$nlast\n0\n$n\n0\n");
    fprintf(f,"#Data:\n$database\n");
    fprintf(f,"#  T1      T2      T3      T4      T5\n0000000 0000000 0000000 0000000 0000000\n");
    fclose(f);
    printf("\nConstants pattern was created in %s.\n",name2);
}


void simple_report(char *name, char *rep, int begr, int endr)
{
   int y=0,mon=0,day=0,hour=0,min=0,hFile;
   long k=0;
   double t=0,p1=0,p2=0,a1=0,a2=0;
   div_t x;
   FILE *fre;
   tss1 ss1;
   tss2 ss2;

   hFile = _open(name,O_RDONLY);
   if (begr<endr)
   {
     GetConst(hFile,&ss1);
     fre = fopen(rep,"w");
     fprintf(fre,"$format\n2\n");
     fprintf(fre,"# N    Data   Time  n1 n2  t1,ms   t2,ms   t3,ms   t4,ms   t5,ms   t6,ms   t7,ms   t8,ms   t9,ms   t10,ms   T1,s      T2,s    a, 0.01 rad  G,b\n");
     while ((!eof(hFile)) && (begr++<=endr))
     {
       k = ((long)(sizeof ss1)+(long)(begr-2)*((long)(sizeof ss2)));
       lseek(hFile,k,0);
       _read(hFile,&ss2,sizeof(tss2));
       t=ss2.time;
       y=GetYear(&t);
       mon=GetMonth(&t,y);
       day=GetDay(&t);
       hour=GetHour(&t);
       min=GetMinute(&t);
       p1=(((double)ss2.T[0]+(double)ss2.T[4])/2+(double)ss2.T[1]+(double)ss2.T[2]+(double)ss2.T[3]+ss1.tau*4)*0.001;
       a1=ss1.c3/ss1.c2/sin(M_PI*((double)ss2.T[1]+(double)ss2.T[3]+ss1.tau*2)/p1/(ss1.c2*1000));
       p2=(((double)ss2.T[5]+(double)ss2.T[9])/2+(double)ss2.T[6]+(double)ss2.T[7]+(double)ss2.T[8]+ss1.tau*4)*0.001;
       a2=ss1.c3/ss1.c2/sin(M_PI*((double)ss2.T[6]+(double)ss2.T[8]+ss1.tau*2)/p2/(ss1.c2*1000));
       x=div(y,100);
       fprintf(fre,"%.4d %.2d.%.2d.%.2d %.2d.%.2d %2d %2d %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %8.4f %8.4f %4.3f %4.3f %5.4f\n",
	       begr-1,day,mon,x.rem,hour,min,ss2.NLast,ss2.N,ss2.T[0],ss2.T[1],
	       ss2.T[2],ss2.T[3],ss2.T[4],ss2.T[5],ss2.T[6],
	       ss2.T[7],ss2.T[8],ss2.T[9],p1,p2,a1*100,a2*100,ss2.G*1e+8);
     }
    fclose(fre);
    _close(hFile);
   }
}


void simple_report_1(char *name,char *rep,int begr,int endr)
{
   int y=0,mon=0,day=0,hour=0,min=0,hFile;
   long k=0;
   double t=0,p1=0,p2=0,a1=0,a2=0;
   div_t x;
   FILE *fre;
   tss1 ss1;
   tss2 ss2;

   hFile = _open(name,O_RDONLY);
   if (begr<endr)
   {
     GetConst(hFile,&ss1);
     fre = fopen(rep,"w");
     fprintf(fre,"$format\n2\n");
     fprintf(fre,"# N    Data   Time  n1 n2  t1,ms   t2,ms   t3,ms   t4,ms   t5,ms   t6,ms   t7,ms   t8,ms   t9,ms   t10,ms   T1,s      T2,s    a, 0.01 rad    G,b\n");
     while ((!eof(hFile)) && (begr++<=endr))
     {
       k = ((long)(sizeof ss1)+(long)(begr-2)*((long)(sizeof ss2)));
       lseek(hFile,k,0);
       _read(hFile,&ss2,sizeof(tss2));
       t=ss2.time;
       y=GetYear(&t);
       mon=GetMonth(&t,y);
       day=GetDay(&t);
       hour=GetHour(&t);
       min=GetMinute(&t);
       p1=(((double)ss2.T[0]+(double)ss2.T[4])/2+(double)ss2.T[1]+(double)ss2.T[2]+(double)ss2.T[3]+ss1.tau*4)*0.001;
       a1=ss1.c3/ss1.c2/sin(M_PI*((double)ss2.T[1]+(double)ss2.T[3]+ss1.tau*2)/p1/(ss1.c2*1000));
       p2=(((double)ss2.T[5]+(double)ss2.T[9])/2+(double)ss2.T[6]+(double)ss2.T[7]+(double)ss2.T[8]+ss1.tau*4)*0.001;
       a2=ss1.c3/ss1.c2/sin(M_PI*((double)ss2.T[6]+(double)ss2.T[8]+ss1.tau*2)/p2/(ss1.c2*1000));
       x=div(y,100);
       fprintf(fre,"%.4d %.2d.%.2d.%.2d %.2d.%.2d %2d %2d %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %7ld %8.4f %8.4f %4.3f %4.3f %8.7f\n",
	       begr-1,day,mon,x.rem,hour,min,ss2.NLast,ss2.N,ss2.T[0],ss2.T[1],
	       ss2.T[2],ss2.T[3],ss2.T[4],ss2.T[5],ss2.T[6],
	       ss2.T[7],ss2.T[8],ss2.T[9],p1,p2,a1*100,a2*100,ss2.G*1e+8);
     }
    fclose(fre);
    _close(hFile);
   }
}
