#include "thinfilm_BLS.h"
#include "build.h"

#define INVCURSORSPEED 10

void copylayer(tf_Layer *source, tf_Layer *dest); 
void copyglobal(tf_Global *source,tf_Global *dest);
void build_eutfa(tf_Global *g, tf_Global *g2, tf_Layer *l,  tf_Layer *l2);

int ramp_start;

int main(int argc, char *argv[])
{
int i,j,k;
tf_Global g,g2;
tf_Layer l[MAXLAYERS],l2[MAXLAYERS];
double x1, x2;
int n_Freq;
double Freq[MAXFREQS+1];

char cursor[] = "\\|/-";

init(&g, l);
init(&g2, l2);

fprintf (stderr, "\nthinfilm-BLS %s by m.buchmeier@fz-juelich.de\nbuild: %s\n\n",VERSION, build);

if (argc < 2)
    {fprintf (stderr, "usage: thinfilm-BLS input-file\n\n"); 
      help(); return(1);}

scanfile(argv[1], &g, l);

showval(g,l);

build_eutfa(&g, &g2, l,  l2);

/*
fprintf (stderr, "\nEUTFA settings:\n");
showval(g2,l2);
*/

ramp_start = 1;

fprintf(g.outp,"# input-file: \"%s\"\n",argv[1]);
fprintf(g.outp,"# processed by:\n");
fprintf (g.outp, "#\n#\tthinfilm-BLS %s by m.buchmeier@fz-juelich.de\n#\tbuild: %s\n#\n",VERSION,
build);
switch(g.output_type)
{
case 0:
fprintf(g.outp, "\
#%15s %15s \
   frequency \
\n#\n",g.ramp_1_label, g.ramp_2_label);
break;

case 1:
case 2:
case 3:
fprintf(g.outp, "#load this file from gnuplot to plot the modeprofiles\n");
break;
}
fprintf(stderr,"\ncalculating ");

for(j=0; j<=g.ramp_2_steps; j++) {
for(i=0; i<=g.ramp_1_steps; i++)
{
x1 = g.ramp_1_start
        + i*(g.ramp_1_stop-g.ramp_1_start)/(g.ramp_1_steps+TINY_VAL);
x2 = g.ramp_2_start
        + j*(g.ramp_2_stop-g.ramp_2_start)/(g.ramp_2_steps+TINY_VAL);

for(k=0; k<MAXRAMPPTR; k++) {
        if(g.ramp1[k] != NULL) *(g.ramp1[k]) = x1;
        if(g.ramp2[k] != NULL) *(g.ramp2[k]) = x2;
        }
//build eutfa layer stack 
//needed here as copyglobal cannot deal with pointers at the moment 
build_eutfa(&g, &g2, l,  l2);

//now calculate frequencies or modeprofiles
n_Freq = tf_findfreq (l2, &g2, Freq);

if(g.output_type == 0) //output frequencies
for(k=0;k<=n_Freq;k++)
        fprintf(g.outp, " %15e %15e %15g\n", x1, x2, Freq[k]);

if(g.output_type >= 1) {				 //output modeprofiles -spectra only
	if(ramp_start == 1 && g.output_type >= 3) {      //calculation for first x-value
        get_mocoeff(l2,&g2); }
	printmodeprofiles(l2, g2, Freq, n_Freq);	}

fflush(g.outp);

if(i%INVCURSORSPEED==0) {
//fprintf(stderr,"\r%c",cursor[(i/INVCURSORSPEED)%4]);
fprintf(stderr,"\b.%c",cursor[(i/INVCURSORSPEED)%4]);
fflush(stderr); }

ramp_start = 0;
}
fprintf(g.outp,"\n");
}

fprintf(g.outp,"\n");
fprintf(stderr,"\n");

return(0);
}

double
sqr (double value)
{
  return (value * value);
}

void copylayer(tf_Layer *source, tf_Layer *dest) {
memcpy (dest, source, sizeof (tf_Layer)); }

void copyglobal(tf_Global *source,tf_Global *dest)
{
int i;
memcpy (dest, source, sizeof (tf_Global));
//all ramps will be lost at the moment !!
for(i=0;i<MAXRAMPPTR;i++)
        dest->ramp1[i]=dest->ramp2[i]=NULL;
}


void build_eutfa(tf_Global *g, tf_Global *g2, tf_Layer *l,  tf_Layer *l2)
//process fmlayer_subdivision information
{
int destlayer ,sourcelayer;
int i;

copyglobal(g,g2);

destlayer=1;
for(sourcelayer=1; sourcelayer<=g->n_layers; sourcelayer++) {

for(i=0;i<l[sourcelayer].fmlayer_subdivisions;i++) {
copylayer(&l[sourcelayer],&l2[destlayer]);
l2[destlayer].d = l[sourcelayer].d /l[sourcelayer].fmlayer_subdivisions;
if(l[sourcelayer].fmlayer_subdivisions > 1)
l2[destlayer].S = l[sourcelayer].S/2;
l2[destlayer].fmlayer_subdivisions = 1;

if(i<l[sourcelayer].fmlayer_subdivisions -1) {
l2[destlayer].j2 = l2[destlayer].j3 = 0;
l2[destlayer].j1 = l[sourcelayer].D *l[sourcelayer].M /l2[destlayer].d;
l2[destlayer].s = 0;
if(i>0) l2[destlayer].S = 0;
}

destlayer++;
}	//end destlayer loop
}	//end sourcelayer loop

g2->n_layers=destlayer-1;
//showval(*g2,l2);
} //end fmlayer_subdivision code

//OSX already has buildin fmax
#ifndef OSX
//find maximum of doubles
double fmax (double f1, double f2)
{
  if (f1 > f2) return (f1);
  else
    return (f2);
}
#endif
