/** \file
 *
 *  Contains the SimInitStruct class declaration.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef SIMINITSTRUCT_H_
#define SIMINITSTRUCT_H_

#include <math.h>
#include <cstring>
#include <stdint.h>

/**
 *  A struct of values that is passed from the LRAUV to the Simulator, to
 *  initialize the simulator.
 *
 *  \ingroup modules_simulator
 */
struct SimInitStruct
{
    // Initial Position Vector
    double initLat_;   //  arcdeg  // Initial latitude
    double initLon_;   //  arcdeg  // Initial longitude
    float initZ_;     // m        // Initial depth
    float initPitch_; //  rad     // Pitch wrto LV
    float initRoll_;  //  rad     // Roll wrto LV
    float initHeading_;   //  rad     // Yaw wrto LV

    // Initial Vehicle configuration
    float initMassPosition_;     // m
    float initBuoyancyPosition_; // m3

    // Initial Rate Vector
    float initU_;     // m/s     // vel x wrto B
    float initV_;     // m/s     // vel y wrto B
    float initW_;     // m/s     // vel z wrto B
    float initP_;     //  rad/s  // Pitch rate wrto LV
    float initQ_;     //  rad/s  // Roll rate wrto LV
    float initR_;     //  rad/s  // Yaw rate wrto LV

    // Optional environmental parameters
    float northCurrent_;      //  m/s    // vel x wrto LV
    float eastCurrent_;       //  m/s    // vel y wrto LV
    float vertCurrent_;       //  m/s    // vel w wrto LV
    float magneticVariation_; //  rad    // if not specified, calculated from lat & lon
    float soundSpeed_;        //  m/s    // if not specified, calculated from density, pressure
    float density_;           //  kg/m3  // sea water density.
    float sst_;               //  degK   // sea surface temperature.  Extends to the mixed layer depth
    float tMixed_;            //  degK   // temperature at mixed layer depth.  Linear change from surface
    float t300_;              //  degK   // temperature at 300 meters.  Linear change from mixed layer depth
    float sss_;               //  ppt    // sea surface salinity.  Extends to the mixed layer depth
    float sMixed_;            //  ppt    // salinity at mixed layer depth.  Linear change from surface
    float s300_;              //  ppt    // salinity at 300 meters.  Linear change from mixed layer depth
    uint8_t oceanModelData_[512]; //  path to ocean model data output, optionally followed by extra variables and units
    float mixedLayerDepth_;   //  meter  // depth of mixed layer

    // Recommended environmental parameter
    float defaultDensity_; //  kg/m3  // Always specify: used outside of 4D model

    // Variable buoyancy setting
    float buoyancyNeutral_;     // cc    // volume in buoyancy "bag" at neutral trim

    ///* translational and rotational body mass */
    //
    float mass_;
    float movableMass_;
    float volume_;
    float centerOfMassX_;
    float centerOfMassY_;
    float centerOfMassZ_;
    float centerOfMovableMassX_;
    float centerOfMovableMassY_;
    float centerOfMovableMassZ_;
    float centerOfBuoyX_;
    float centerOfBuoyY_;
    float centerOfBuoyZ_;
    float momentXX_;
    float momentYY_;
    float momentZZ_;

    //
    ///* hydrodynamic parameters ----------------------------------------------*/
    //
    //
    /* added mass */
    float kpDot_;
    float mqDot_;
    float nrDot_;
    float xuDot_;
    float yvDot_;
    float zwDot_;

    /* added mass cross terms */
    float kvDot_;
    float mwDot_;
    float nvDot_;
    float yrDot_;
    float ypDot_;
    float zqDot_;

    //                /* quadratic drag */
    float kpabp_;  // Kp|p| , kg-m^2
    float mqabq_;  // Mq|q| , kg-m^2
    float nrabr_;  // Nr|r| , kg-m^2
    float xuabu_;
    float yvabv_;  // Yv|v| , kg/m
    float zwabw_;  // Zw|w| , kg/m
    //
    //                /* quadratic drag cross terms */
    float mwabw_;  // Mw|w| , kg
    float nvabv_;  // Nv|v| , kg
    float yrabr_;  // Yr|r| , ?
    float zqabq_;  // Zq|q| , ?
    //
    //                /* in-line lift and drag */
    float muq_;  // Muq   , kg-m
    float muw_;  // Muw   , kg
    float mpr_;  // Mpr   , kg-m^2
    //
    float nur_;  // Nur   , kg-m
    float nuv_;  // Nuv   , kg
    float npq_;  // Npq   , kg-m^2
    //
    float xvv_;  // Xvv   , kg/m
    float xww_;  // Xww   , kg/m
    float xvr_;  // Xvr   , kg
    float xwq_;  // Xwq   , kg
    float xrr_;  // Xrr   , kg-m
    float xqq_;  // Xqq   , kg-m

    float yur_;  // Yur   , kg
    float yuv_;  // Yuv   , kg/m
    float ywp_;  // Ywp   , kg-m

    float zuq_;  // Zuq   , kg
    float zuw_;  // Zuw   , kg/m
    float zvp_;  // Zvp   , kg

    float kvt2_;  // ?     , ?

    float aspectRatio_;  //   , Unitless
    float stallAngle_;  //   , Deg.

    float rudderHystWidth_;  //   , rad
    float rudderHystCenter_; //   , rad
    float rudderSpeed_;      //   , rad/s

    float elevatorHystWidth_;  //   , rad
    float elevatorHystCenter_; //   , rad
    float elevatorSpeed_;      //   , rad/s

    float movableMassHystWidth_;  //   , meter
    float movableMassHystCenter_; //   , meter
    float movableMassSpeed_;      //   , meter/s

    float buoyancyHystWidth_;  //   , m^3
    float buoyancyHystCenter_; //   , m^3
    float buoyancySpeed_;      //   , m^3/s

    float finArea_;  //   , m^2
    float coeffDrag_;  // Coef. of Drag  , Unitless
    float coeffLift_;  // Coef. of Lift  , Unitless

    float lowerRudX_;
    float lowerRudY_;
    float lowerRudZ_;
    float upperRudX_;
    float upperRudY_;
    float upperRudZ_;
    float portElevX_;
    float portElevY_;
    float portElevZ_;
    float stbdElevX_;
    float stbdElevY_;
    float stbdElevZ_;

    float designSpeed_;
    float designPropEff_;
    float designOmega_;
    float designThrust_;
    float designTorque_;
    float dropWt1Volume_;
    float dropWt1Mass_;
    float dropWt1X_;
    float dropWt1Y_;
    float dropWt1Z_;

    float cylinderLength_;
    float cylinderRadius_;

    double time_;

    /// Constructor
    SimInitStruct()
        :
        // Initial Position Vector
        initLat_( 36.737845 ),    //  arcdeg // Initial latitude
        initLon_( -121.8804227 ), //  arcdeg // Initial longitude
        initZ_( 0.000000 ),       // m       // Initial depth
        initPitch_( 000.0000 ),   //  rad    // Pitch wrto LV
        initRoll_( 000.0000 ),    //  rad    // Roll wrto LV
        initHeading_( 0.0 ),      //  rad    // Yaw wrto LV

        // Initial Vehicle Configuration
        initMassPosition_( 0.0 ),     // m
        initBuoyancyPosition_( 0.0 ), // m3

        // Initial Rate Vector
        initU_( 0.000000 ),     // m/s      // vel x wrto B
        initV_( 0.000000 ),     // m/s      // vel y wrto B
        initW_( 0.000000 ),     // m/s      // vel z wrto B
        initP_( 000.0000 ),     // rad/s    // Pitch rate wrto LV
        initQ_( 000.0000 ),     // rad/s    // Roll rate wrto LV
        initR_( 000.0000 ),     // rad/s    // Yaw rate wrto LV

        northCurrent_( nanf( "" ) ),      //  m/s    // vel x wrto LV
        eastCurrent_( nanf( "" ) ),       //  m/s    // vel y wrto LV
        vertCurrent_( nanf( "" ) ),       //  m/s    // vel z wrto LV
        magneticVariation_( nanf( "" ) ), //  rad    // if not specified, calculated from lat & lon
        soundSpeed_( nanf( "" ) ),        //  m/s    // if not specified, calculated from density, pressure
        density_( nanf( "" ) ),           //  kg/m3  // sea water density.
        sst_( nanf( "" ) ),               //  degK   // sea surface temperature.  Extends to the mixed layer depth
        tMixed_( nanf( "" ) ),            //  degK   // temperature at mixed layer depth.  Linear change from surface
        t300_( nanf( "" ) ),              //  degK   // temperature at 300 meters.  Linear change from mixed layer depth
        sss_( nanf( "" ) ),               //  ppt    // sea surface salinity.  Extends to the mixed layer depth
        sMixed_( nanf( "" ) ),            //  ppt    // salinity at mixed layer depth.  Linear change from surface
        s300_( nanf( "" ) ),              //  ppt    // salinity at 300 meters.  Linear change from mixed layer depth
        mixedLayerDepth_( nanf( "" ) ),   //  meter  // depth of mixed layer

        // Recommended environmental parameter
        defaultDensity_( 1025.00 ),       //  kg/m3  // Always specify: used outside of 4D model

        // Variable buoyancy setting
        buoyancyNeutral_( nanf( "" ) ),   // cc      // volume in buoyancy "bag" at neutral trim

        mass_( nanf( "" ) ),
        movableMass_( nanf( "" ) ),
        volume_( nanf( "" ) ),
        centerOfMassX_( nanf( "" ) ),
        centerOfMassY_( nanf( "" ) ),
        centerOfMassZ_( nanf( "" ) ),
        centerOfMovableMassX_( nanf( "" ) ),
        centerOfMovableMassY_( nanf( "" ) ),
        centerOfMovableMassZ_( nanf( "" ) ),
        centerOfBuoyX_( nanf( "" ) ),
        centerOfBuoyY_( nanf( "" ) ),
        centerOfBuoyZ_( nanf( "" ) ),
        momentXX_( nanf( "" ) ),
        momentYY_( nanf( "" ) ),
        momentZZ_( nanf( "" ) ),

        //
        ///* hydrodynamic parameters ----------------------------------------------*/
        //
        //
        /* added mass */
        kpDot_( nanf( "" ) ),
        mqDot_( nanf( "" ) ),
        nrDot_( nanf( "" ) ),
        xuDot_( nanf( "" ) ),
        yvDot_( nanf( "" ) ),
        zwDot_( nanf( "" ) ),

        /* added mass cross terms */
        kvDot_( nanf( "" ) ),
        mwDot_( nanf( "" ) ),
        nvDot_( nanf( "" ) ),
        yrDot_( nanf( "" ) ),
        ypDot_( nanf( "" ) ),
        zqDot_( nanf( "" ) ),

        //                /* quadratic drag */
        kpabp_( nanf( "" ) ),  // Kp|p| , kg-m^2
        mqabq_( nanf( "" ) ),  // Mq|q| , kg-m^2
        nrabr_( nanf( "" ) ),  // Nr|r| , kg-m^2
        xuabu_( nanf( "" ) ),
        yvabv_( nanf( "" ) ),  // Yv|v| , kg/m
        zwabw_( nanf( "" ) ),  // Zw|w| , kg/m
        //
        //                /* quadratic drag cross terms */
        mwabw_( nanf( "" ) ),  // Mw|w| , kg
        nvabv_( nanf( "" ) ),  // Nv|v| , kg
        yrabr_( nanf( "" ) ),  // Yr|r| , ?
        zqabq_( nanf( "" ) ),  // Zq|q| , ?
        //
        //                /* in-line lift and drag */
        muq_( nanf( "" ) ),  // Muq   , kg-m
        muw_( nanf( "" ) ),  // Muw   , kg
        mpr_( nanf( "" ) ),  // Mpr   , kg-m^2
        //
        nur_( nanf( "" ) ),  // Nur   , kg-m
        nuv_( nanf( "" ) ),  // Nuv   , kg
        npq_( nanf( "" ) ),  // Npq   , kg-m^2
        //
        xvv_( nanf( "" ) ),  // Xvv   , kg/m
        xww_( nanf( "" ) ),  // Xww   , kg/m
        xvr_( nanf( "" ) ),  // Xvr   , kg
        xwq_( nanf( "" ) ),  // Xwq   , kg
        xrr_( nanf( "" ) ),  // Xrr   , kg-m
        xqq_( nanf( "" ) ),  // Xqq   , kg-m

        yur_( nanf( "" ) ),  // Yur   , kg
        yuv_( nanf( "" ) ),  // Yuv   , kg/m
        ywp_( nanf( "" ) ),  // Ywp   , kg-m

        zuq_( nanf( "" ) ),  // Zuq   , kg
        zuw_( nanf( "" ) ),  // Zuw   , kg/m
        zvp_( nanf( "" ) ),  // Zvp   , kg

        kvt2_( nanf( "" ) ),  // ?     , ?

        aspectRatio_( nanf( "" ) ),  //   , Unitless
        stallAngle_( nanf( "" ) ),  //   , Deg.

        rudderHystWidth_( nanf( "" ) ),  //   , rad
        rudderHystCenter_( nanf( "" ) ),  //   , rad
        rudderSpeed_( nanf( "" ) ),  //   , rad

        elevatorHystWidth_( nanf( "" ) ),  //   , rad
        elevatorHystCenter_( nanf( "" ) ),  //   , rad
        elevatorSpeed_( nanf( "" ) ),  //   , rad/sec

        movableMassHystWidth_( nanf( "" ) ),  //   , meter
        movableMassHystCenter_( nanf( "" ) ),  //   , meter
        movableMassSpeed_( nanf( "" ) ),  //   , meter/sec

        buoyancyHystWidth_( nanf( "" ) ),  //   , m^3
        buoyancyHystCenter_( nanf( "" ) ),  //   , m^3
        buoyancySpeed_( nanf( "" ) ),  //   , m^3/sec

        finArea_( nanf( "" ) ),  //   , m^2
        coeffDrag_( nanf( "" ) ),  // Coef. of Drag  , Unitless
        coeffLift_( nanf( "" ) ),  // Coef. of Lift  , Unitless

        lowerRudX_( nanf( "" ) ),
        lowerRudY_( nanf( "" ) ),
        lowerRudZ_( nanf( "" ) ),
        upperRudX_( nanf( "" ) ),
        upperRudY_( nanf( "" ) ),
        upperRudZ_( nanf( "" ) ),
        portElevX_( nanf( "" ) ),
        portElevY_( nanf( "" ) ),
        portElevZ_( nanf( "" ) ),
        stbdElevX_( nanf( "" ) ),
        stbdElevY_( nanf( "" ) ),
        stbdElevZ_( nanf( "" ) ),

        designSpeed_( nanf( "" ) ),
        designPropEff_( nanf( "" ) ),
        designOmega_( nanf( "" ) ),
        designThrust_( nanf( "" ) ),
        designTorque_( nanf( "" ) ),
        dropWt1Volume_( nanf( "" ) ),
        dropWt1Mass_( nanf( "" ) ),
        dropWt1X_( nanf( "" ) ),
        dropWt1Y_( nanf( "" ) ),
        dropWt1Z_( nanf( "" ) ),
        cylinderLength_( nanf( "" ) ),
        cylinderRadius_( nanf( "" ) ),
        time_( nanf( "" ) )
    {
        memset( oceanModelData_, 0, sizeof( oceanModelData_ ) );
    }

};

#endif /* SIMINITSTRUCT_H_ */
