/* ************************************************************
 * *                                                          *
 * *  IRIS MENU I/O related routines, for POM output options  *
 * *                                                          *
 * ************************************************************
 * File: libs/config/menu_load_pom.c
 *
 *                  COPYRIGHT (c) 2004, 2005 BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sigtypes.h"
#include "setup.h"
#include "headers.h"
#include "product.h"
#define LIM_DEFINITIONS
#define LIM_KERNEL menu_limits_kernel
#include "config_lib.h"
#include "user_lib.h"

static MESSAGE opt_limits
( const char *sname_a,		/* Name of structure */
  volatile void *item_a,	/* Pointer to structure */
  SINT4 ioper_a,		/* Operation to perform */
  void *file_a );		/* Diagnostic messages, or NULL */

static MESSAGE LIM_KERNEL
( const char *sname_a,		/* Name of structure */
  void *item_a,			/* Pointer to structure */
  SINT4 ioper_a,		/* Operation to perform */
  const char *spath_a,		/* Full path name of fields */
  void *ioarg_a ) ;		/* Diagnostic messages, or NULL */


/* =================================================================== 
 * This subroutine reads the saved values from the setup file.
 */
MESSAGE menu_load_pom_options
( const char *sName_a,                     /* File name to load */
  struct device_output_options pPomOptions_a[] )
{
  char sName[FILENAME_SIZE];

  strncpy( sName, sName_a, FILENAME_SIZE-20 );
  sName[FILENAME_SIZE-20]=0;
  strcat( sName, ".pom_options" );
  memset( pPomOptions_a, 0, MAX_OUT_DEVICES*sizeof(struct device_output_options) ) ;

  return( lim_loadFileDir( NULL, "IRIS_MENU", sName, "array", pPomOptions_a, opt_limits ) ) ;
}

/* =================================================================== 
 * This subroutine reads just the default values into the structure.
 */
MESSAGE menu_load_pom_defaults
( struct device_output_options pPomOptions_a[MAX_OUT_DEVICES] )
{

  memset( pPomOptions_a, 0, MAX_OUT_DEVICES*sizeof(struct device_output_options) ) ;

  return (*opt_limits)( "array", pPomOptions_a, SETUP_DEFVAL, NULL ) ;
      
}

/* =================================================================== 
 * This subroutine writes new values to the dsp file. 
 */
MESSAGE menu_save_pom_options
( const char *sName_a,                    /* File name to load */
  const struct device_output_options pPomOptions_a[] )
{
  char sName[FILENAME_SIZE];
  strncpy( sName, sName_a, FILENAME_SIZE-20 );
  sName[FILENAME_SIZE-20]=0;
  strcat( sName, ".pom_options" );

  return( lim_saveFileDir( NULL, "IRIS_MENU", sName, "array", pPomOptions_a, opt_limits ) ) ;
}

/* ======================================================================
 * Check limits on menu structures.
 */
static MESSAGE opt_limits
( const char *sname_a,		/* Name of structure */
  volatile void *item_a,	/* Pointer to structure */
  SINT4 ioper_a,		/* Operation to perform */
  void *file_a )		/* Diagnostic messages, or NULL */
{
  return( lim_toplevel( sname_a, item_a, ioper_a, file_a, LIM_KERNEL ) ) ;
}

/* ======================================================================
 * Internal routine to recursively descend the menu structures.
 */
static MESSAGE LIM_KERNEL
( const char *sname_a,		/* Name of structure */
  void *item_a,			/* Pointer to structure */
  SINT4 ioper_a,		/* Operation to perform */
  const char *spath_a,		/* Full path name of fields */
  void *ioarg_a )		/* Diagnostic messages, or NULL */
{
  char spath[PATHNAME_SIZE], *sItem ; struct lim_inLine **pLine ;
  SINT4 idim1=0, idim2=0 ; MESSAGE istatus = SS_NORMAL ;
  UINT1 lActualSizes = USEACTUALSIZES( ioper_a ) ;

  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  if( 0 == strcmp( "apo_spec", sname_a ) ) 
    {
      struct apo_spec *item = item_a ;
      
      /* Use product type to disable unused fields */
      if( (!lActualSizes) || item->iptype )
	{
	  SCALAR(  iptype,   0, NUM_DEFINED_PRODUCTS,   0 ) ;
	  STRING(  spname,   "" ) ;
	}
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "array", sname_a ) )
    {
      struct product_inventory *item = item_a ;
      
      SUBSTRUCTURE_1D( device_output_options, device, MAX_OUT_DEVICES ) ;
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "common_options", sname_a ) ) 
    {
      struct common_options *item = item_a ;
      
      SCALAR(         iunits,   0,      3, UNITS_METRIC );
      SCALAR(      iComFlags,   0, 0xFFFF,            0 );
      SCALAR(   iRingSpacing,   0,   1000,            0 );
      STRING(    sRingCenter,   "" ) ;
      SUBSTRUCTURE( ForecastOptions, Forecast ) ;
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "device_output_options", sname_a ) ) 
    {
      struct device_output_options *item = item_a ;
      
      /* We always write out the full array.  Not sure how to effectively limit.
       */
      SUBSTRUCTURE_1D(         output_options,       ptype, NUM_DEFINED_PRODUCTS );
      SUBSTRUCTURE(      vvp_specific_options,  VvpOptions );
      SUBSTRUCTURE(     wind_specific_options, WindOptions );
      SUBSTRUCTURE(     warn_specific_options, WarnOptions );
      SUBSTRUCTURE_1D( server_color_scale_def,      scales, SERVER_DTYPE_COUNT );
      /* Update field intentionally left out */
      SUBSTRUCTURE(            common_options,     Common );
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "ForecastOptions", sname_a ) ) 
    {
      struct ForecastOptions *item = item_a ;
      
      /* iDeviceIndex field intentionally left out */
      STRING(     sPName,   "" ) ;
      SCALAR(      iTime,   0,    24*3600, 5*60 );
      SCALAR(     iSpeed,   0,     100000,    0 );
      SCALAR( iDirection,   0, 0xFFFFFFFF,    0 );
      SCALAR(     iFlags,   0,          3,    0 );
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "output_options", sname_a ) ) 
    {
      struct output_options *item = item_a ;
      
      SUBSTRUCTURE_1D( apo_spec, apo, 3 ) ;
      SCALAR(         iSepFlags,   0, 0xFFFF,   OP_OVERLAY  ) ;
      SCALAR(        irangering,   0,      3,   RING_NUMS_P ) ;
      SCALAR( ilayer_mask_index,   0,   0xFF,   0           ) ;
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "server_color_scale_def", sname_a ) ) 
    {
      struct server_color_scale_def *item = item_a ;
      UINT1 lNonZero=FALSE;
      SINT4 iIndex;
      for (iIndex=0; iIndex<16; iIndex++)
	{
	  if (item->ilevel_seams[iIndex]) lNonZero=TRUE;
	}
      
      /* Intentionally skipping idevice_index and idtype which are not used*/
      /* SCALAR(   idevice_index,      0,     MAX_OUT_DEVICES,   0 ) ; */
      /* SCALAR(          idtype,      1,  NUM_DEFINED_DATA-1,   1 ) ; */
      SCALAR(          iflags,      0,              0xFFFF,   0 ) ;
      SCALAR(          istart,  -1000,               +1000,   0 ) ;
      SCALAR(           istep,      0,                1000,   0 ) ;
      SCALAR(         icolcnt,      2,                  16,  16 ) ;
      SCALAR(     iset_number,      1,     COLOR_SET_COUNT,   1 ) ;

      /* Skip if all zero (default value) */
      if( (!lActualSizes) || lNonZero )
	SCALAR_1D( ilevel_seams,      0,              0xFFFF,   0, 16 ) ;
      SCALAR(   iscale_number,      0, COLOR_SCALE_COUNT-1,   0 ) ;
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "vvp_specific_options", sname_a ) ) 
    {
      struct vvp_specific_options *item = item_a ;
      
      /* iptype field intentionally left out */
      /* idevice_index field intentionally left out */
      SCALAR(         iflags,         0,  0x0000003,      0 ) ;
      SCALAR(    iheight_max, -10000000,   10000000,      0 ) ;
      SCALAR(   iheight_step,         0,    1000000, 100000 ) ;
      SCALAR(     ithreshold,         0,        100,      0 ) ;
      SCALAR(  igr_plot_mask,         0, 0xFFFFFFFF,      0 ) ;
      SCALAR(   igr_max_hvel,         0,     0xFFFF,      0 ) ;
      SCALAR( igr_max_diverg,         0,     0xFFFF,      0 ) ;
      SCALAR(   igr_max_vvel,         0,     0xFFFF,      0 ) ;
      SCALAR( igr_max_deform,         0,     0xFFFF,      0 ) ;
      SCALAR(    igr_max_dbz,         0,     0xFFFF,      0 ) ;
      SCALAR(  ith_time_span,        60,    24*3600,   3600 ) ;
      SCALAR(  ith_time_step,         0,       3600,     60 ) ;
      SCALAR( ith_under_plot,    DB_DBT, NUM_DEFINED_DATA-1, DB_DBZ ) ;
      SCALAR(  ith_over_plot,         0,          3, VVP_WIND_BARBS ) ;
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "warn_specific_options", sname_a ) ) 
    {
      struct warn_specific_options *item = item_a ;
      
      /* iptype field intentionally left out */
      /* idevice_index field intentionally left out */
      SCALAR( iForecastSeconds,         0,      60*60,                      0 );
      SCALAR(   iCentroidLabel,         0,          3, CENTROID_LABEL_AVERAGE );
      SCALAR(    iCentroidFill,         0,          2,        CENTROID_FILLED );
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else if( 0 == strcmp( "wind_specific_options", sname_a ) ) 
    {
      struct wind_specific_options *item = item_a ;
      
      /* iptype field intentionally left out */
      /* idevice_index field intentionally left out */
      SCALAR(         iflags,         0,  0x0000003,      0 );
      SCALAR(        iHeight, -10000000,   10000000, 100000 );
      SCALAR(       iMaxHVel,         0,     0xFFFF,      0 );
      SCALAR(     iThreshold,         0,        100,      0 );
    }
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  else
    istatus = iMessageMod_va( CONFIG_LIM_BADSTRUCT, 1, sname_a ) ;

  return( istatus ) ;
}

