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

#define SIGN(x) ((x)<0.0?-1.0:((x)>0.0?1.0:0.0))
static double capstanSpeed,capstanAcceleration,inSpeed,inAcceleration,inRatio,outSpeed,outAcceleration,outRatio,
	      UAKK,CAPSTANACCELERATION,READSPEED,REWINDSPEED,secs,dsecs,INlength,OUTlength,MAXCHAMPERTAPELENGTH,
	      CHAMPERWIDTH,CHAMPERLENGTH,inTape,outTape,photo,maxSecs,inDiff,outDiff,total,inError,outError;
static int rewinding,singlestep,uakk,inSign,outSign;

static void headline()
{
  printf("   UAKK      photo     secs     capSpeed  inSpeed   outSpeed  inError   outError  inTape    outTape   inSign    outSign   total\n");
}

static void printout()
{
  printf("%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%10.4f%10d%10d%10.4f\n",
      UAKK,photo,secs,capstanSpeed,inSpeed,outSpeed,inError,outError,inTape,outTape,inSign,outSign,total);
}

static int step()
{
  singlestep++;
  secs=singlestep*dsecs;
  INlength-=inSpeed*dsecs;
  OUTlength-=outSpeed*dsecs;
  inTape+=inSpeed*dsecs;
  outTape+=outSpeed*dsecs;
  inTape-=capstanSpeed*dsecs;
  outTape+=capstanSpeed*dsecs;
  inSpeed+=inAcceleration*dsecs;
  outSpeed+=outAcceleration*dsecs;
  capstanSpeed+=capstanAcceleration*dsecs;
  if(rewinding)
  {
    if((-capstanSpeed)>REWINDSPEED)
    {
      capstanSpeed = -REWINDSPEED;
      capstanAcceleration = 0;
    }
  }
  else
  {
    if(fabs(capstanSpeed)>READSPEED)
    {
      capstanAcceleration=0;
      capstanSpeed=SIGN(capstanSpeed)*READSPEED;
    }
  }
  inRatio=inTape/MAXCHAMPERTAPELENGTH;
  outRatio=outTape/MAXCHAMPERTAPELENGTH;
  inDiff=(inSpeed-capstanSpeed);
  outDiff= -(outSpeed-capstanSpeed);
  if(inRatio<photo)
  {
    inAcceleration=capstanSpeed/inDiff*CAPSTANACCELERATION*UAKK;
  }
  else if(inRatio>(1-photo))
  {
    inAcceleration=-capstanSpeed/inDiff*CAPSTANACCELERATION*UAKK;
  }
  else
    inAcceleration=0;

  inAcceleration=inSign*capstanSpeed/inDiff*CAPSTANACCELERATION*UAKK;

  if(outRatio<photo)
  {
    outAcceleration=capstanSpeed/outDiff*CAPSTANACCELERATION*UAKK;
  }
  else if(outRatio>(1-photo))
  {
    outAcceleration=-capstanSpeed/outDiff*CAPSTANACCELERATION*UAKK;
  }
  else
    outAcceleration=0;

  outAcceleration=outSign*capstanSpeed/outDiff*CAPSTANACCELERATION*UAKK;
  inError=inSpeed-capstanSpeed;
  outError=outSpeed+capstanSpeed;
//inAcceleration = inSign*capstanAcceleration;
//outAcceleration = outSign*capstanAcceleration;
  inAcceleration = inSign*inError*UAKK;
  outAcceleration = outSign*outError*UAKK;

  total=INlength+OUTlength+inTape+outTape;

  if(fabs(inRatio)>1.0 || fabs(outRatio)>1.0 || OUTlength<0.0 || INlength<0.0)
  {
    if(secs>maxSecs)
    {
      maxSecs=secs;
    }
    printout();
    printf("inRatio: %g outRatio: %g INlength: %g OUTlength: %g\n",inRatio,outRatio,INlength,OUTlength);
    return(0);
  }
  printout();
  return(1);
}

static void reset()
{
  dsecs=1.0/600.0;
  /*
  36*0.0254 = 0.9144 m/s
  91.44 m/s|&2
  */
  CAPSTANACCELERATION=36.0*0.0254/dsecs;
  if(rewinding)
    capstanAcceleration=-CAPSTANACCELERATION;
  else
    capstanAcceleration=CAPSTANACCELERATION;
  READSPEED=36.0*0.0254;
  REWINDSPEED=180.0*0.0254;
  if(rewinding)
  {
    INlength=0;
    OUTlength=2400*12*0.0254;
  }
  else
  {
    OUTlength=0;
    INlength=2400*12*0.0254;
  }
  capstanSpeed=0.0;
  inSpeed=0;
  inAcceleration=0;
  inRatio=0;
  outSpeed=0;
  outAcceleration=0;
  outRatio=0;
  singlestep=0;
  CHAMPERLENGTH=0.3442;
  CHAMPERWIDTH=0.0513;
  MAXCHAMPERTAPELENGTH=2*CHAMPERLENGTH-CHAMPERWIDTH*0.5+CHAMPERWIDTH*M_PI;
  inTape=MAXCHAMPERTAPELENGTH*0.5;
  outTape=MAXCHAMPERTAPELENGTH*0.5;
}

void main(int argc, char **argv)
{
  maxSecs=0;
  rewinding=1;
  headline();
  if(rewinding)
  {
    inSign=-1;
    outSign=-1;
  }
  else
  {
    inSign=-1;
    outSign=-1;
  }
    UAKK=rewinding?12:4;
    reset();
    while(step());
  headline();
  printf("maxSecs: %.3f\n", maxSecs);
}




