#include <stdio.h>
#include <math.h>
#include <signal.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "lin.h"

#ifndef O_RDONLY
#define O_RDONLY 00
#endif
#ifndef O_WRONLY
#define O_WRONLY 01
#endif

#define A_2 0.0000821
#define B 0.0017
#define EPS 1.e-3

static double tmp1,tmp2,tmp3,suma;


CLIENT *cl;
int *result;
static int i;
static remote_o_struct ros[] = {{"/dev/lc0",O_RDONLY,2},
				  {"/dev/lc1",O_RDONLY,2},
				  {"/dev/lc2",O_RDONLY,2},
				  {"/dev/lc3",O_RDONLY,2},
				  {"/dev/lc4",O_RDONLY,2},
				  {"/dev/lc5",O_RDONLY,2},
				  {"/dev/lc6",O_RDONLY,2},
				  {"/dev/lc7",O_RDONLY,2},
				  {"/dev/lc16",O_WRONLY,2}};
  
static remote_r_w_struct rrws[9],*res;
static char server[]="air.vm.stuba.sk";

void open_termo()
{
  
  if((cl = clnt_create(server,REMOTEDEVICE,REMOTEVERS,"tcp")) == NULL)
    {
      clnt_pcreateerror(server);
      exit(1);
    }
  for(i=0; i < 8; i++)
    {
      if((result=remote_open_1(&ros[i],cl)) == NULL)
	{
	  clnt_perror(cl,server);
	  exit(1);
	}
      if(*result == -1)
	{
	  printf("bad open\n");
	  exit(1);
	}
      rrws[i].fd = *result;
      rrws[i].bytes = 2;
    }
  if((result=remote_open_1(&ros[8],cl)) == NULL)
    {
      clnt_perror(cl,server);
      exit(1);
    }
  if(*result == -1)
    {
      printf("bad open\n");
      exit(1);
    }
      rrws[8].fd = *result;
      rrws[8].bytes = 2;
}


void read_termo(a)
     char **a;
{
  double *resu;

  resu = (double *)a[0];
  
  for(i=0; i < 8; i++)
    {
      if((res=remote_read_1(&rrws[i],cl)) == NULL)
	{
	  clnt_perror(cl,server);
	  exit(1);
	}
      if(res->bytes == -1)
	{
	  printf("bad read\n");
	  exit(1);
	}
      *(short *)rrws[i].buf = *(short *)res->buf;
      resu[i] = 5*((double)*(short *)rrws[i].buf-2048)/1024;
/*      printf("%g %d\n",resu[i],*(short *)rrws[i].buf);*/
    }
}


void write_termo(a)
     char **a;
{
  short pom;
  double dat;


  dat = *(double *)a[0];
  
  pom = (short)(2048 * dat/5);

  *(short *)rrws[8].buf = pom;
    
  if((result=remote_write_1(&rrws[8],cl)) == NULL)
    {
      clnt_perror(cl,server);
      exit(1);
    }
  if(*result == -1)
    {
      printf("bad write\n");
      exit(1);
    }
}


void close_termo()
{
  for(i=0; i < 9; i++)
    {
      if((result=remote_close_1(&rrws[i].fd,cl)) == NULL)
	{
	  clnt_perror(cl,server);
	  exit(1);
	}
    }
}


void mysig_handler()
{
}

void init_wait(a)
     char **a;
{
  struct itimerval cas_new, cas_old;
  long milisec;

  milisec = *(int *)a[0];
  
  cas_new.it_interval.tv_sec=milisec/1000;
  cas_new.it_interval.tv_usec=(milisec % 1000)*1000;
  cas_new.it_value.tv_sec=milisec/1000;
  cas_new.it_value.tv_usec=(milisec % 1000)*1000;

  setitimer(ITIMER_REAL,&cas_new,&cas_old);
  signal(SIGALRM,mysig_handler);
}


double green_func(a)
     char **a;
{
  int n=0;
  double periodic = 0;
  double lambda = 0.;
  double majorant = 0.;
  double x,t,l,tk;
  
  x = *(double *)a[0];
  t = *(double *)a[1];
  l = *(double *)a[2];
  tk = *(double *)a[3];
  
  suma = 0.;

  while(1)
    {
      periodic = (2*n + 1) * M_PI / (2 * l);
      tmp1 = sin(periodic * x);
      lambda = pow(periodic,(double)2) * A_2;
      tmp2 = exp(-lambda * (tk-t))/(2 * n + 1);
#ifdef DEBUG
      printf("tmp2 %g\n",tmp2);
#endif
      if(n == 0)
	{
	  if(tmp2 == 0.)
	    {
	      majorant = 1.;
	    }
	  else
	    {
	      majorant = fabs(tmp2);
	    }
	}
      if (fabs(tmp2) < majorant)
	{
	  if(suma == 0. && n > 5)
	    {
	      break;
	    }
	  if(fabs(suma/majorant) > 1/EPS)
	    {
	      break;
	    }
	  else
	    {
	      majorant = majorant / 10.;
	    }
	}
      tmp3 = tmp1 * tmp2 ;
      suma = suma + tmp3;
      n += 1;
    }
#ifdef DEBUG
  printf(" suma %g\n",suma);
#endif

  suma = 4. / M_PI * exp(-B * (tk-t)) * suma;
  return(suma);
}

void csigpause(a)
     char **a;
{
  sigpause(*(int *)a[0]);
}

