/**C*
 *
 * Vaisala software source code file
 *
 * Copyright (c) Vaisala Oyj 2009, 2011. All rights reserved.
 *
 *
 *
 **C*/

/** @file rawprod_io.h
 *  IRIS  \b ingest and \b rawproduct file I/O API 
 */

#ifndef RAW_PRODUCT_IO_H
#define RAW_PRODUCT_IO_H

#ifdef __cplusplus
extern "C" {
#endif

/** @defgroup gr_rawprodio IRIS ingest and RAW product file I/O
 * 
 *
 *  @ingroup gr_radar_scan
 *  @{
 */

/* IRIS/RDA specific per-scan (hybrid/non-hybrid) metadata keys */
#define SCC_IRIS_TASK_NAME "IRIS Scan Task Name"
#define SCC_IRIS_LOCAL_TIME_OFFSET "IRIS Scan Local Time Offset"
#define SCC_IRIS_LOCAL_TIME_NAME "IRIS Scan Local Time Name"
#define SCC_IRIS_ISOTHERM_0C "isotherm_0C"

/* IRIS/RDA specific sweep configuration (non-hybrid scan) metadata
 * keys */

#define SWC_IRIS_INGEST_HDR "IRIS Sweep Ingest Header"
#define SWC_IRIS_MAJOR_TSK_ID "IRIS Sweep Major Task ID"
#define SWC_IRIS_MINOR_TASK_ID "IRIS Sweep Minor Task ID"
#define SWC_IRIS_SCAN_SPEED "IRIS Sweep Scan Speed"

/* IRIS/RDA specific ray(or DSP) configuration metadata keys */
#define RAC_IRIS_LOG_THRESH "IRIS Ray Log Threshold"
#define RAC_IRIS_SQI_THRESH "IRIS Ray SQI Threshold"

#define MAX_SUFFIX_LEN 10
#define MAX_IRIS_STRING_LEN (512)
//#define FD_CLOSED (-1)

enum raw_file_type {
    RAW_FULL,         /**< rawproduct file with all executed sweeps */
    RAW_SINGLE_SWEEP  /**< rawproduct file with just one of the
                       * executed sweeps */
};

/** Create new radar_scan from the sequence of ingest files. Caller
 *  must provide file handle(s) via call back.  Type RD_ANY
 *  corresponds to ingest header file. Both sweep and scan_config are
 *  zero based. If  scan_config = -1, then there is only one scan configuration.
 */
struct radar_scan *
rscan_new_from_ingest(void * handle,
                      FILE * (*next_ingest_file)(void * handle,
                                                 enum raw_data_type type,
                                                 enum data_format format,
                                                 int sweep,
                                                 int scan_config),
                      void (*error_report)(const char *message));  /**< Optional error function */

/** Save radar scan into a sequence of ingest files. Caller must
 *  provide file handle(s) via call back. Type RD_ANY corresponds to
 *  ingest header file. Both sweep and scan_config are zero based. If
 *  scan_config = -1, then there is only one scan configuration.
 */
int rscan_save_ingest(struct radar_scan * scan, void * handle,
                      FILE * (*next_ingest_file)(void * handle,
                                                 enum raw_data_type type,
                                                 enum data_format format,
                                                 int sweep,
                                                 int scan_config));


/** Read in raw product file starting from the second record (Record[1])
 * containing ingest header. The first record (Record[0]) with the product
 * header is assumed to be read already. */
struct radar_scan *
rscan_new_from_raw(void * handle,
                   FILE * (*next_raw_file)(void * handle),
                   void (*error_report)(const char *message));  /**< Optional error function */


/** Tell us how many IRIS hybrid scans will be required for this radar scan */
    int rscan_get_iris_hybrid_count (struct radar_scan * scan);

/** Save radar scan into a sequence of raw files. Caller must
 *  provide file handle(s) via call back.
 */
int rscan_save_raw(struct radar_scan * scan, void * handle,
		   const char *product_gen_site_a,
                   enum raw_file_type ftype,
                   enum data_format bin_format,
                   FILE * (*next_raw_file)(void * hdl,
                                           int hybrid_scan_index,
                                           enum raw_file_type t,
                                           int sweep_index));

/** @defgroup gr_io_iterators Input/Output iterators/callbacks
 * 
 *  Input/Output source/destination iterators for a few most common
 *  cases.
 *
 *  @ingroup gr_rawprodio
 *  @{
 */

/** @defgroup gr_ingest_file_iterator Ingest file iterator/callbacks
 * 
 *
 *  @ingroup gr_io_iterators
 *  @{
 */
/** Create default_ingest_io handle */  
void * default_ingest_io_new(const char * base_name);

/** Create default_ingest_io handle for hybrid scan */  
void * default_ingest_io_new_hybrid(const char ** base_names,
                                    size_t count);

/** Free default_ingest_io handle */  
void default_ingest_io_delete(void * handle);

/** Default ingest input file callback */
FILE * default_ingest_input(void * handle,
                            enum raw_data_type type,
                            enum data_format format,
                            int sweep,
                            int scan_config);

/** Default ingest output file callback */
FILE * default_ingest_output(void * handle,
                             enum raw_data_type type,
                             enum data_format format,
                             int sweep,
                             int scan_config);

/** @}  gr_ingest_file_iterator */

/** @defgroup gr_raw_file_iterator RAW product file iterator/callbacks
 * 
 *
 *  @ingroup gr_io_iterators
 *  @{
 */

/** Create default_raw_io handle */  
void * default_raw_io_new(const char * file_name);

/** Create default_raw_io handle for a hybrid scan or a list
 * of single sweep raw files.
 */  
void * default_raw_io_new_hybrid(const char ** file_names,
                                 size_t count);

/** Free default_raw_io handle */  
void default_raw_io_delete(void * handle);

/** Default raw input file callback */
FILE * default_raw_input(void * handle);

/** Default raw output file callback */
FILE * default_raw_output(void * h, /**< Handle created with default_raw_io_new() */
			  int hybrid_scan_index, /**<  -1 if it is not a hybrid scan */
			  enum raw_file_type type, /**<  RAW_FULL or RAW_SINGLE_SWEEP */
			  int sweep_index); /**< Ignored if RAW_FULL */

/** The raw output file callback which does not create  meta file */
FILE * nometa_raw_output(void * h, int scan_config,
                         enum raw_file_type type,
                         int sweep_index);

/** Return the number of filenames used */
int default_raw_output_count(void * h);

/** Return one of the used filenames */
const char * default_raw_output_name(void * h, int i);

/** Return the base filename */
    const char * default_raw_output_base(void * h);

/** Gets the raw data suffix for an ingest file */
const char * raw_data_suffix(enum raw_data_type t, enum data_format f);

/** @}  gr_raw_file_iterator */
/** @}  gr_io_iterators */
/** @}  gr_rawprodio */

#ifdef __cplusplus
}
#endif
#endif /* RAW_PRODUCT_IO_H */
