/*
 * Title: readind.c
 * Author: Jed Marti KI7NNP
 * Description: Read test inductor descriptions created by perm/indbuild.ja
 * Format:
 *   henrys,radius-meters,wire-radius-meters,wire-gauge,number-turns,length-meters,fname
 * Revision History: (Created Tue Jan 24 07:21:46 2023)
 */


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "compare.h"

#define inches2meters(x) ((x) * 0.0254)
#define meters2inches(x) ((x) / 0.0254)

// The list of inductors to test against. Of course this is shared by all processes and must
// be filled before run.
anInductor *theInductors;



anInductor *newInductor(void)
{
  anInductor *i;
  if ((i = (anInductor *) malloc(sizeof(anInductor))) == NULL)
  {
    fprintf(stderr, "Out of space newInductor\n");
    exit(-1);
  }
  return i;
}



void readTestInductors(char *fname)
/*     Read the test inductor file - sort of a CSV.
 * Parmaters:
 *   fname: The file name to read from. 
 * External References:
 *   theInductors: A list of them. See storage.c for creating. Once the file is read, the list
 *     doesn't change order.
 * returned values: none
 * Errors Detected: Format errors, file can't be opened.
 */
{
  FILE *fh;
  char       iline[80];
  char       *tok;
  anInductor *i;
  int32_t    lineno = 0;
  
  if ((fh = fopen(fname, "rb")) == NULL)
  {
    fprintf(stderr, "%s (%s:%d) Couldn't open %s\n", __FILE__, __func__, __LINE__, fname);
    exit(-1);
  }

 loop:
  if (fgets(iline, 80, fh) == NULL)
  {
    fclose(fh);
    return;
  }
  ++lineno;

  // Check for comments or the CSV first line. We ignore the first line (dangerous).
  if (iline[0] == '/' ||
      (iline[0] >= 'A' && iline[0] <= 'Z') ||
      (iline[0] >= 'a' && iline[0] <= 'z')) goto loop;

  i = newInductor();

  // Measured inductance (mean of all measurements) in henrys.
  tok = strtok(iline, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, no data\n", __FILE__, __func__, __LINE__, lineno,
            fname);
    fclose(fh);
    exit(-1);
  }
  i->L = atof(tok);
  //  printf("H = %g", i->L);

  // The coil radius in meters and inches.
  tok = strtok(NULL, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing radius\n", __FILE__, __func__, __LINE__,
            lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->R = atof(tok);
  i->Ri = meters2inches(i->R);
  if (i->R <= 0.0)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, radius %g bad\n", __FILE__, __func__, __LINE__,
            lineno, fname, i->R);
    fclose(fh);
    exit(-1);
  }
  //  printf(", r=%g", i->R);

  // The coil wire radius in meters.
  tok = strtok(NULL, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing wire radius\n", __FILE__, __func__,
            __LINE__, lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->W = atof(tok);
  if (i->W <= 0.0)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, wire radius %g bad\n", __FILE__, __func__,
            __LINE__, lineno, fname, i->W);
    fclose(fh);
    exit(-1);
  }

  // The coil wire gauge (mostly for show).
  tok = strtok(NULL, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing wire gauge\n", __FILE__, __func__,
            __LINE__, lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->G = atoi(tok);
  if (i->W <= 0 || i->W > 32)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, wire gauge %d bad\n", __FILE__, __func__,
            __LINE__, lineno, fname, i->G);
    fclose(fh);
    exit(-1);
  }

  // The number of turns.
   tok = strtok(NULL, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing number of turns\n", __FILE__, __func__,
            __LINE__, lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->N = atoi(tok);
  //  printf(", N=%d", i->N);
  if (i->N <= 0)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, number of turns  %d bad\n", __FILE__, __func__,
            __LINE__, lineno, fname, i->N);
    fclose(fh);
    exit(-1);
  }

  // The coil length in meters and inches.
  tok = strtok(NULL, ",\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing length\n", __FILE__, __func__,
            __LINE__, lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->LENi = meters2inches(i->LEN  = atof(tok));
  if (i->LEN <= 0.0)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, length %g bad\n", __FILE__, __func__,
            __LINE__, lineno, fname, i->LEN);
    fclose(fh);
    exit(-1);
  }
  //  printf(", l=%g\n", i->LEN);

  // The file name.
  tok = strtok(NULL, " ,\n");
  if (tok == NULL)
  {
    fprintf(stderr, "%s (%s:%d) At line %d in %s, missing file name\n", __FILE__, __func__,
            __LINE__, lineno, fname);
    fclose(fh);
    exit(-1);
  }
  i->FN = strdup(tok);

  //  printf("%3d: %10g %10g %10g %2d %10g %3d %s\n", lineno, i->L*1.0e6, i->R*1000.0, i->W*1000.0,
  //         i->G, i->LEN*1000.0, i->N, i->FN);

  i->next = theInductors;
  theInductors = i;
  goto loop;
}


// EOF
