#include "dbhost.h"     /* PROTOTYPE_ALLOWED */
#include "dbext.h"      /* DMSH_POSITION_TYPE, BAD*, LONG, etc. */
/*****************************************************************************
*                                                                            *
*      COMMON OCEANOGRAPHIC DATA ACCESS SYSTEM (CODAS)                       *
*                                                                            *
*      WRITTEN BY:  RAMON CABRERA, ERIC FIRING, and JULIE RANADA             *
*                   JOINT INSTITUTE FOR MARINE AND ATMOSPHERIC RESEARCH      *
*                   1000 POPE ROAD  MSB 404                                  *
*                   HONOLULU, HI 96822                                       *
*                                                                            *
*      VERSION:     3.00                                                     *
*                                                                            *
*      DATE:        APRIL 1989                                               *
*                                                                            *
*****************************************************************************/
/*-----------------------------------------------------------------------------

       FILE:  posn.c

              POSITION CONVERSION & PRINTING FUNCTIONS

*/
#if PROTOTYPE_ALLOWED
void HUNPOS(DMSH_POSITION_TYPE *p, LONG *h);
LONG POSHUN(DMSH_POSITION_TYPE *p);
#else
void HUNPOS();
LONG POSHUN();
#endif
/*-----------------------------------------------------------------------------

   FUNCTION:  invalid_position

      It checks a DMSH_POSITION_TYPE structure.

   PARAMETERS:
   
      p = pointer to DMHS_POSITION_TYPE structure

   RETURNS:  0 if position is okay
             INVALID_POSITION (> 0) otherwise

   CALLED FROM:  C

*/
#if PROTOTYPE_ALLOWED
int invalid_position(DMSH_POSITION_TYPE *p, int is_lat)
#else
int invalid_position(p, is_lat)
DMSH_POSITION_TYPE *p;
int is_lat;
#endif
{
   int test_mask = 0;   /* jr+: must initialize to 0 in case of 0 d, m, s, or h */

   if (p->degree == BADSHORT) return(0);  /* jr+: ok value for no position */
   if ( ( is_lat && (abs_val(p->degree) > 90 ) ) ||
        (!is_lat && (abs_val(p->degree) > 359) ) ||
        (abs_val(p->minute) > 59) ||
        (abs_val(p->second) > 59) ||
        (abs_val(p->hundredth) > 99 )
      )
      return(INVALID_POSITION);
   if (p->degree > 0) 
      test_mask = 1;
   else if (p->degree < 0) 
      test_mask = 2;
   if (p->minute > 0) 
      test_mask = test_mask | 1;
   else if (p->minute < 0) 
      test_mask = test_mask | 2;
   if (p->second > 0) 
      test_mask = test_mask | 1;
   else if (p->second < 0) 
      test_mask = test_mask | 2;
   if (p->hundredth > 0) 
      test_mask = test_mask | 1;
   else if (p->hundredth < 0) 
      test_mask = test_mask | 2;
   if (test_mask == 3)  
      return(INVALID_POSITION);
   return(0);
}

/*-----------------------------------------------------------------------------

   FUNCTION:  POSHUN

      Given a DMSH_POSITION_TYPE structure, it returns the equivalent position
      in hundredths of a second.

   PARAMETER:

      p = pointer to DMSH_POSITION_TYPE structure

   RETURNS:  position in hundredths of a second

   CALLED FROM:  C, FORTRAN

*/
#if PROTOTYPE_ALLOWED
LONG POSHUN(DMSH_POSITION_TYPE *p)
#else
LONG POSHUN(p)
DMSH_POSITION_TYPE *p;
#endif
{
   LONG l_360000 = 360000L, l_6000 = 6000, l_100 = 100;

   if (p->degree == BADSHORT) return(BADLONG); /* jr+: bad value */
   return ((p->degree * l_360000)
      + (p->minute * l_6000)
      + (p->second * l_100)
      + (p->hundredth));
}

/*-----------------------------------------------------------------------------

   FUNCTION:  HUNPOS

      Given a position in hundredths of a second, it transforms it into the
      equivalent DMSH_POSITION_TYPE structure.

   PARAMETERS:
   
      p = pointer to DMSH_POSITION_TYPE structure

      h = pointer to position in hundredths of a second

   RETURNS:  VOID

   CALLED FROM:  C, FORTRAN

*/
#if PROTOTYPE_ALLOWED
void HUNPOS(DMSH_POSITION_TYPE *p, LONG *h)
#else
void HUNPOS(p, h)
DMSH_POSITION_TYPE *p;
LONG *h;
#endif
{
   LONG temp, l_360000 = 360000L, l_6000 = 6000, l_100 = 100;

   if (*h != BADLONG)
   {
      p->degree = div_nr(*h,l_360000);
      temp = mod_nr(*h,l_360000);
      p->minute = div_nr(temp,l_6000);
      temp = mod_nr(*h,l_6000);
      p->second = div_nr(temp,l_100);
      p->hundredth = mod_nr(*h,l_100);
   }
   else
      p->degree = p->minute = p->second = p->hundredth = BADSHORT;
}

/*-----------------------------------------------------------------------------

   FUNCTION:  POSDIF

      Given two DMSH_POSITION_TYPE structures, it returns the difference 
      in hundredths of a second.

   PARAMETERS:
   
      p1 = pointer to first DMSH_POSITION_TYPE structure

      p2 = pointer to second DMSH_POSITION_TYPE structure

   RETURNS:  (p2 - p1) in hundredths of a second

   CALLED FROM:  C, FORTRAN

*/
#if PROTOTYPE_ALLOWED
LONG POSDIF(DMSH_POSITION_TYPE *p1, DMSH_POSITION_TYPE *p2)
#else
LONG POSDIF(p1, p2)
DMSH_POSITION_TYPE *p1, *p2;
#endif
{
   return(POSHUN(p2) - POSHUN(p1));
}

/*-----------------------------------------------------------------------------

   FUNCTION:  DIFPOS

      Given a reference DMSH_POSITION_TYPE structure and a displacement 
      in hundredths of a second, it calculates a new DMSH_POSITION_TYPE
      structure as the sum.

   PARAMETERS:
   
      p1 = pointer to reference DMSH_POSITION_TYPE structure

      p2 = pointer to resulting DMSH_POSITION_TYPE structure (p1 + s)

      h = pointer to displacement in hundredths of a second

   RETURNS:  VOID

   CALLED FROM:  C, FORTRAN

*/
#if PROTOTYPE_ALLOWED
void DIFPOS(DMSH_POSITION_TYPE *p1, DMSH_POSITION_TYPE *p2, LONG *h)
#else
void DIFPOS(p1, p2, h)
DMSH_POSITION_TYPE *p1, *p2;
LONG *h;
#endif
{
   LONG hh;

   hh = POSHUN(p1) + (*h);
   HUNPOS(p2, &hh);
}

/*-----------------------------------------------------------------------------

   FUNCTION:  POSCMP

      It compares two DMSH_POSITION_TYPE structures.

   PARAMETERS:
   
      p1 = pointer to first DMSH_POSITION_TYPE structure
          
      p2 = pointer to second DMSH_POSITION_TYPE structure

   RETURNS:  0 if p1 = p2
             1 if p1 < p2
             2 if p2 < p1

   CALLED FROM:  C, FORTRAN

*/
#if PROTOTYPE_ALLOWED
LONG POSCMP(DMSH_POSITION_TYPE *p1, DMSH_POSITION_TYPE *p2)
#else
LONG POSCMP(p1, p2)
DMSH_POSITION_TYPE *p1, *p2;
#endif
{
   if (p1->degree    < p2->degree   ) return(1);
   if (p1->degree    > p2->degree   ) return(2);
   if (p1->minute    < p2->minute   ) return(1);
   if (p1->minute    > p2->minute   ) return(2);
   if (p1->second    < p2->second   ) return(1);
   if (p1->second    > p2->second   ) return(2);
   if (p1->hundredth < p2->hundredth) return(1);
   if (p1->hundredth > p2->hundredth) return(2);
   return(0);
}

