/*
 *
 * Copyright (c) Vaisala Group 2009. All rights reserved.
 *
 * The terms "Vaisala" and "Vaisala Group" are defined as
 * "Vaisala Oyj and all its subsidiaries".
 *
 */

/** @file radar_scan.h
 *  API of the radar volume scan data container.
 */

#ifndef RADAR_SCAN_H
#define RADAR_SCAN_H

#ifdef __cplusplus
extern "C" {
#endif

/** @defgroup gr_radar_scan Radar Scan Data Container
 * 
 *  Contains sweeps with rays of one volume scan.
 *
 *  @ingroup gr_polar_data
 *  @{
 */

/* Forward declarations */
struct radar_scan;

struct radar_scan * rscan_new(const char * name,
                              const char * info,
                              const char * site_name,
                              const char * site_info,
                              enum platform_type radar_type,
                              const struct fixed_platform * position);

/** Copy-create new scan with a given base name */
struct radar_scan * rscan_new_copy(const struct radar_scan * rs);

/** Copy task name into provided buffer. Copy max n characters. */
char * rscan_get_name(const struct radar_scan * rs, char * buf, size_t n);

/** Set scan name (AKA task name). Some formats can not handle
    task names longer then 12 characters */
int rscan_set_name(struct radar_scan * rs, const char * new_name);

/** Copy task info/comment into provided buffer. Copy max n characters. */
char * rscan_get_info(const struct radar_scan * rs, char * buf, size_t n);

/** Set scan info (AKA task info string). Some formats can not handle
    task info strings longer then 80 characters */
int rscan_set_info(struct radar_scan * rs, const char * new_info);

/** Copy site name into provided buffer. Copy max n characters. */
char * rscan_get_site_name(const struct radar_scan * rs, char * buf, size_t n);

/** Set site name. Some formats can not handle
    site names longer  then 16 characters */
int rscan_set_site_name(struct radar_scan * rs, const char * new_name);

/** Copy site info text into provided buffer. Copy max n characters. */
char * rscan_get_site_info(const struct radar_scan * rs, char * buf, size_t n);

/** Set site info text. */
int rscan_set_site_info(struct radar_scan * rs, const char * new_name);

/** Get scan's time stamp (not a real start/stop time) */
struct timeval * rscan_get_time_stamp(const struct radar_scan * rs,
                                      struct timeval * tv);

/** Set scan's time stamp (not a real start/stop time) */
int rscan_set_time_stamp(struct radar_scan * rs,  const struct timeval * tv);

  /** Shift all time stamps inside this sweep by shift, expressed as timeval struct */
int rscan_shift_time_stamp(struct radar_scan * scan,  const struct timeval * shift);

/** Get the scheduled/expected number of sweeps */
int rscan_get_scheduled_sweeps(const struct radar_scan * rs);

/** Get the scheduled/expected number of sweeps */
void rscan_set_scheduled_sweeps(struct radar_scan * rs, int count);

/** Get the actual number of sweeps */
int rscan_get_sweeps_count(const struct radar_scan * rs);

/** Get next sweep. If sweep is NULL, get first sweep.
    Return NULL when ran out of sweeps. */ 
struct radar_sweep * rscan_get_next_sweep(const struct radar_scan * rs,
                                          struct radar_sweep * sweep);

struct radar_sweep * rscan_add_sweep(struct radar_scan * rs,
                                     struct radar_sweep * new_sweep);

/** Remove sweep from the scan 
    Return NULL when there is no such sweep in the scan.
    Sweep is not destroyed, call rsweep_delete(), to discard it */
struct radar_sweep * rscan_eject_sweep(struct radar_scan * rs,
                                       struct radar_sweep * sweep_to_eject);

/** Remove sweep from the scan by its schedule index
    Return NULL when there is no such sweep in the scan.
    Sweep is not destroyed, call rsweep_delete(), to discard it */
struct radar_sweep * rscan_eject_sweep_n(struct radar_scan * rs,
                                         int index_in_schedule);

/** Remove sweep from the scan by its fixed angle
    Return NULL when there is no such sweep in the scan.
    Sweep is not destroyed, call rsweep_delete(), do discard it */
struct radar_sweep * rscan_eject_sweep_a(struct radar_scan * rs,
                                         double fixed_angle);

/**  Get number of shared ray configuration. Usually there is only one. */
int rscan_get_rayconf_count(const struct radar_scan * rs);

/** Get next ray config. If current conf is NULL, get the first configuration.
    Return NULL when ran out of configuration. */ 
struct radar_ray_conf * rscan_get_next_rayconf(const struct radar_scan * rs,
                                               struct radar_ray_conf *rconf);

/** Get number of shared sweep configuration. Usually there is only one. */
int rscan_get_sweepconf_count(const struct radar_scan * rs);

/** Get next sweep config. If current conf is NULL, get the first configuration.
    Return NULL when ran out of configuration. */ 
struct radar_sweep_conf * rscan_get_next_sweepconf(const struct radar_scan * rs,
                                                   struct radar_sweep_conf *sconf);

struct radar_position * rscan_get_position(const struct radar_scan * rs);
int rscan_set_position(struct radar_scan * rs, struct radar_position * position);


    int rscan_add_int(struct radar_scan * rs, const char * name, int val);

    int rscan_add_u64(struct radar_scan * rs, const char * name, uint64_t val);

    int rscan_add_double(struct radar_scan * rs, const char * name, double val);

    int rscan_add_string(struct radar_scan * rs,
                         const char * name, const char * val);

    int rscan_add_buf(struct radar_scan * rs,
                      const char * name, const void * buf, size_t len);

    int rscan_is_defined(const struct radar_scan * rs, const char * name);

    int rscan_get_int(const struct radar_scan * rs, const char * name);

    uint64_t rscan_get_u64(const struct radar_scan * rs, const char * name);

    double rscan_get_double(const struct radar_scan * rs, const char * name);

    char * rscan_get_string(const struct radar_scan * rs,
                            const char * name, char * buf, size_t len);

    char * rscan_get_buf(const struct radar_scan * rs,
                         const char * name, void * buf, size_t * len);


/** Unmap and close all asociated files and free all data structures */
int rscan_delete(struct radar_scan * rs);

int rscan_dump_brief(const struct radar_scan * rss, FILE *stream);
int rscan_dump_verbose(const struct radar_scan * rss, FILE *stream);
int rscan_dump_timestamps(const struct radar_scan * rss, FILE *stream);
int rscans_find_nearest(struct radar_scan ** rscans, size_t len, const char * task_name,
                        struct timeval * tval, struct radar_scan ** res, size_t res_cnt);

/** @}  gr_radar_scan */

#ifdef __cplusplus
}
#endif
#endif // RADAR_SCAN_H
