// include statements
#include "slbm_C_shell.h"  // RSTT C library
#include <stdio.h>         // print to terminal
#include <math.h>          // math functions and constants
#include <stdlib.h>        // needed for exit codes

// define some constants for converting between degrees<-->radians
double DEG_PER_RAD = 180.0 / M_PI;
double RAD_PER_DEG = M_PI / 180.0;


// error catching function
void try(int errorCode)
{
    // if there is an error code (i.e., function returns anything other than 0)
    if (errorCode != 0)
    {
        // initialize a character array to hold error messages
        char errorMsg[1000];

        // get the error message
        slbm_shell_getErrorMessage(errorMsg);

        // print the error message
        printf("ERROR %d:%s\n", errorCode, errorMsg);

        // exit with the error code
        exit(errorCode);

    }

}


// main program
int main()
{
    // declare the relative path to the model file we're going to be using
    char* modelPath = "../models/pdu2020012Du.geotess";

    // choose an arbitrary phase (Pn, Pg, Sn, or Lg)
    char* phase = "Pn";

    // arbitrary source (Meteor Crater, AZ)
    double srcLatDeg =   35.0274;  // latitude (degrees)
    double srcLonDeg = -111.0228;  // longitude (degrees)
    double srcDepKm  =    1.2345;  // depth (km)

    // arbitrary receiver (Albuquerque, NM)
    double rcvLatDeg =   35.1053;  // latitude (degrees)
    double rcvLonDeg = -106.6294;  // longitude (degrees)
    double rcvDepKm  =   -1.6000;  // depth (km)

    // convert lat/lon from degrees to radians
    double srcLatRad = srcLatDeg * RAD_PER_DEG;
    double srcLonRad = srcLonDeg * RAD_PER_DEG;
    double rcvLatRad = rcvLatDeg * RAD_PER_DEG;
    double rcvLonRad = rcvLonDeg * RAD_PER_DEG;

    // instantiate an RSTT object
    try(slbm_shell_create());

    // load the velocity model
    try(slbm_shell_loadVelocityModel(modelPath));

    // create a great circle from source to the receiver
    try(slbm_shell_createGreatCircle(phase,
        &srcLatRad, &srcLonRad, &srcDepKm,
        &rcvLatRad, &rcvLonRad, &rcvDepKm));

    // get the distance and travel time from source --> receiver
    double distRad, distDeg, travelTimeSec;         // instantiate variables
    try(slbm_shell_getDistance(&distRad));          // compute distance (rad) and store its value
    try(slbm_shell_getTravelTime(&travelTimeSec));  // compute travel time (sec) and store its value
    distDeg = distRad * DEG_PER_RAD;                // convert radians --> degrees

    // get the travel time uncertainty
    double travelTimeUncertSec,    // path-dependent travel time uncertainty (sec)
           travelTime1DUncertSec;  // old-style 1D travel time uncertainty (sec)
    try(slbm_shell_getTTUncertainty(&travelTimeUncertSec));      // compute uncertainty
    try(slbm_shell_getTTUncertainty1D(&travelTime1DUncertSec));  // compute 1D uncertainty

    // print our results
    printf("\n"
           "C Example:\n"
           "--------------------------------\n"
           "Distance:          %9.4f deg\n"
           "Travel Time:       %9.4f sec\n"
           "Uncertainty:       %9.4f sec\n"
           "Uncertainty (1D):  %9.4f sec\n",
           distDeg, travelTimeSec, travelTimeUncertSec, travelTime1DUncertSec);

    // return successfully
    return 0;

}
