/*************************************************************
Filename:       set.c
Author:		Eija Achren, Lauri Glad, Pekka Haara, Tuija Rinne, Sarianne Mykra
Date:           16.6.1992

Description:    This file contains functions which are used
                to change limits and value of widgets in 
		read_ABAQUS module. Main function is in file 
		main.c

Modifications:

**************************************************************/

#include "fem.h"
#include "defin.h"

#include <string.h>
#include <stdio.h>
#include <avs/avs.h>
#include <avs/flow.h>
#include <avs/field.h>

#include <sys/types.h>
#include <sys/time.h>
#include <time.h>

#include <sys/file.h>
#include <math.h>
#include <stdlib.h>
#include <errno.h>
#include <avs/ucd_defs.h>

extern void error_message(char *, char *, char *, int);


/*************************************************************
Function:	search_first_inc

Description:	searches the index of first increment of step

Input:		local_step: step number
		*inc_time: pointer to structure which holds
			times for steps & incs
Output:		-
Global variables: -

Return:		index of first increment of step in inc_time
		ERROR, if step not found
-------------------------------------------------------------*/

int search_first_inc(local_step, inc_time, msg_flag)

 int local_step;
 STime *inc_time;
 bool msg_flag;

{
  int *first_inc_ptr=NULL;
  
  /* is step number between first and last step */
  if(local_step >= inc_time->step[0] && local_step <= inc_time->step[inc_time->numincs-1])
  {
    first_inc_ptr = inc_time->step; 
    while(*first_inc_ptr < local_step) 
      first_inc_ptr++; 
  }

  if(first_inc_ptr == NULL || *first_inc_ptr != local_step) /* step not found */
  {
    if(msg_flag)
      AVSerror("The file does not contain step number %d.",local_step);
    return ERROR;
  }

  return first_inc_ptr - inc_time->step;
} /* search_first_inc */


/*************************************************************
Function:	search_last_inc

Description:	searches the index of last increment of step

Input:		local_step: step number
		*inc_time: pointer to structure which holds
			times for steps & incs
Output:		-
Global variables: -

Return:		index of last increment of step in inc_time
-------------------------------------------------------------*/

int search_last_inc(local_step, inc_time)

 int local_step;
 STime *inc_time;

{
  int last_inc_index,
  i=1;	/* counter */
  
  if(inc_time->step[inc_time->numincs-1] == local_step) /* last step */
    last_inc_index = inc_time->numincs-1;
  else /* not last step */
  {
    /* search begining of next step */
    while((last_inc_index = search_first_inc(local_step+i, inc_time, FALSE)) == ERROR)
      i++;
    last_inc_index--;
  }

  return last_inc_index;
} /* search_last_inc */


/*************************************************************
Function:	set_dial_limits

Description:	Sets dials to point first step and its first
		inc, time of that is set to Time-widget.

Input:		inc_time: structure contains incs and times
			for each step

Output:		-

Global variables: step_nr: will be set to number of first step
            	inc_nr: will be set to first inc of first step

Return:		-
-------------------------------------------------------------*/

void set_dial_limits(inc_time)

 STime *inc_time;

{
  char time_string[20];         /* string to hold time converted to string */
  int last_inc_index;	        /* index of last increment of first step   */
  int lower_limit;              /* lower limit of dial                     */
  
  step_nr = inc_time->step[0]; 	                /* first step              */
  inc_nr = inc_time->inc[0];	                /* first inc of first step */
  last_inc_index = search_last_inc(step_nr, inc_time);

  if(step_nr == inc_time->step[(inc_time->numincs)-1])
    lower_limit = 0;                            /* only one step           */
  else
    lower_limit = step_nr;
  AVSmodify_parameter("Step nr.",
	        AVS_VALUE|AVS_MINVAL|AVS_MAXVAL,
		step_nr, 	                   /* initial = first step */
		lower_limit,                       /* first step or 0      */
		inc_time->step[(inc_time->numincs)-1]);      /* last step  */

  if(inc_nr == inc_time->inc[last_inc_index])
    lower_limit = 0;                               /* only one inc in step */
  else 
    lower_limit = inc_nr;
  AVSmodify_parameter("Inc nr.",
		AVS_VALUE|AVS_MINVAL|AVS_MAXVAL,
		inc_nr, 		        /* first inc of first step */
		lower_limit,                    /* first inc or 0          */
		inc_time->inc[last_inc_index]); /* last inc of first step  */
  sprintf(time_string, "Time: %10.6f", inc_time->time[0]);
  AVSmodify_parameter("Time",AVS_VALUE, time_string, "", "");

} /* set_dial_limits */


/*************************************************************
Function:	set_inc_and_time

Description:	Sets inc dial to point first inc of step.
		Assigns time of inc to Time-widget.

Input:		inc_time: structure contains incs and times
			for each step
Output:		-

Global variables: step_nr: current step number

Return:		-
-------------------------------------------------------------*/


void set_inc_and_time(inc_time)

STime *inc_time;

{
  int first_inc_index;	/* index of first increment of step        */
  int last_inc_index;	/* index of last increment of step         */
  char time_string[20];	/* string to hold time converted to string */
  int lower_limit;      /* lower limit of dial                     */

  if(inc_time->step[0] == inc_time->step[(inc_time->numincs)-1]) /* only one step */
  {
    if(step_nr != inc_time->step[0])
    {
      step_nr = inc_time->step[0];
      AVSmodify_parameter("Step nr.", AVS_VALUE, inc_time->step[0], 0, inc_time->step[0]);
    }
  }
  else    /* more than one step */
  {
    /* search the first increment of step */
    if((first_inc_index = search_first_inc(step_nr, inc_time, TRUE)) != ERROR)
    {
      /* search the last increment of step */
      last_inc_index = search_last_inc(step_nr, inc_time);

      if(inc_time->inc[first_inc_index] == inc_time->inc[last_inc_index])
	lower_limit = 0;                   /* only one inc in step    */
      else
	lower_limit = inc_nr;

      /* set minimum and maximum values of increment widget */
      AVSmodify_parameter("Inc nr.",
	      AVS_VALUE|AVS_MINVAL|AVS_MAXVAL,
	      inc_time->inc[first_inc_index], /* initial=first inc of step */
	      lower_limit,                    /* first inc of step or 0    */
	      inc_time->inc[last_inc_index]); /* last inc of step          */

      /* set time */
      sprintf(time_string, "Time: %10.6f", inc_time->time[first_inc_index]);
      AVSmodify_parameter("Time",AVS_VALUE, time_string, "", "");
    }   /* if step found */
  }     /* more than one step */
} /* set_inc_and_time */


/*************************************************************
Function:	set_step_and_inc

Description: 	Adds new steps to inc_time and updates dials.
		Dials are set to point last inc of last step.

Input:		inc_time: structure contains incs and times
			for each step

Output:         inc_time: new steps & incs will be added

Global variables: step_nr: current step number. If auto_update,
			then will be set to number of last step.
		inc_nr: If auto_update, then will be set to number
			of last inc of last step.

Return:		TRUE (1), if new increments found
                FALSE (0), if no new increments
-------------------------------------------------------------*/

bool set_step_and_inc(inc_time)

 STime *inc_time;

{
  int first_inc_index;   /* first increment of last step                         */
  char time_string[20];	 /* string to hold time converted to string              */
  bool new_incs = FALSE; /* is new steps & increments found                      */
  STime temp_inc_time;

  /* read  time data from file*/
  ABAQUS_Time_Data(&temp_inc_time);
  new_incs = (inc_time->numincs < temp_inc_time.numincs);

  if(new_incs) /* new incs ready */
   {
     /* free old time data structure */
     free(inc_time->step);
     free(inc_time->inc);
     free(inc_time->time);
   
     /* new data to inc_time */
     inc_time->step = temp_inc_time.step;
     inc_time->inc = temp_inc_time.inc;
     inc_time->time = temp_inc_time.time;
     inc_time->numincs = temp_inc_time.numincs;

     /* widgets to point last inc of last step */
     first_inc_index = search_first_inc(inc_time->step[inc_time->numincs-1], inc_time, TRUE); 
     step_nr = inc_time->step[inc_time->numincs-1];            /* last step  */
     inc_nr = inc_time->inc[inc_time->numincs-1];   /* last inc of last step */
     AVSmodify_parameter("Step nr.", AVS_VALUE|AVS_MAXVAL,
		         step_nr, 	            /* last step=current step */
			 inc_time->step[0],                     /* first step */
			 inc_time->step[inc_time->numincs-1]);  /* last step  */
     AVSmodify_parameter("Inc nr.", AVS_VALUE|AVS_MAXVAL,
		         inc_nr, 	             /* last inc of last step=current inc */
			 inc_time->inc[first_inc_index],         /* first inc of last step */
			 inc_time->inc[(inc_time->numincs)-1]);  /* last inc of last step  */
     sprintf(time_string,"Time: %10.6f", inc_time->time[inc_time->numincs-1]);
     AVSmodify_parameter("Time",AVS_VALUE, time_string, "", "");
  }  /* new incs found */
  else
    { 
      free(temp_inc_time.step);
      free(temp_inc_time.inc);
      free(temp_inc_time.time);
    }
return new_incs;
} /* set_step_and_inc */


/*************************************************************
Function:	set_time

Description:	Assigns time of inc to Time-widget.

Input:		inc_time: structure contains incs and times
			for each step

Output:		-

Global variables: step_nr: current step number
		inc_nr: current increment number, changed

Return:		-
-------------------------------------------------------------*/

void set_time(inc_time)

 STime *inc_time;

{
  int index;		/* index of increment */
  char time_string[20];	/* string to hold time converted to string */

  /* search step_nr from inc_time->step */
  if((index = search_first_inc(step_nr, inc_time, TRUE)) != ERROR) /* step found */
  {
    if(search_last_inc(step_nr, inc_time) == index)  /* only one inc in step */
    {
      if(inc_nr != inc_time->inc[index])
      {
	inc_nr = inc_time->inc[index];
	AVSmodify_parameter("Inc nr.", AVS_VALUE, inc_nr, 0, inc_nr);
      }
    }
    else     /* more than one inc in step */
    {
      /* search inc from inc_time->inc */
      while(inc_time->inc[index] <  inc_nr && inc_time->step[index] == step_nr) 
	index++;

      if(inc_time->step[index] == step_nr && inc_time->inc[index] == inc_nr)
      {
	sprintf(time_string, "Time: %10.6f", inc_time->time[index]);
	AVSmodify_parameter("Time",AVS_VALUE, time_string, "", "");
      }
      else   /* no inc_nr found in step step_nr */
	AVSerror("The step number %d does not contain increment number %d.", step_nr, inc_nr);
    }    /* more than one inc in step */
  }      /* step found */
  else   /* no step step_nr */
    AVSerror("The file does not contain step number %d.", step_nr);

} /* set_time */











