
#include "postgres.h"

typedef RA float8;

RA*   RA_in( char* );
char* RA_out( char* );
RA*   RA_add( RA*, RA* );
bool  RA_lt( RA*, RA* );
bool  RA_le( RA*, RA* );
bool  RA_eq( RA*, RA* );
bool  RA_ge( RA*, RA* );
bool  RA_gt( RA*, RA* );
int4  RA_cmp( RA*, RA* );

// Internal use - converts an RA into the proper range
RA
reduce( RA x )
   {
   while ( x < 0 ) { x += 360.0; }
   x %= 360.0;
   return( x );
   }

// Converts from string to RA type
RA *
RA_in( char* str )
   {
   RA x;
   RA* result;

   if ( 1 != sscanf( str, "%lf", &x ) )
      {
      elog( ERROR, "RA_in: error in parsing %s", str );
      return NULL;
      }
   else
      {
      result = (RA*)palloc( sizeof( RA ) );
      *result = x;
      }

   return( result );
   }

// Converts from RA type to string, handling the proper RA range
char *
RA_out( RA* ra )
   {
   char* result;

   if ( NULL == ra )
      {
      return( NULL );
      }
   else
      {
      result = (char*) palloc( 32 );
      sprintf( result, "%g", reduce( *ra ) );
      }

   return( result );
   }

// Adds one ra to another
RA*
RA_add( RA* lhs, RA* rhs )
   {
   RA* result;

   result = (RA*) palloc( sizeof( RA ) );
   *result = *lhs + *rhs;
   return( result );
   }

// Operator class for defining B-tree index
bool
RA_lt( RA* lhs, RA* rhs ) { return( reduce( *lhs )  < reduce( *rhs ) ) };
RA_le( RA* lhs, RA* rhs ) { return( reduce( *lhs ) <= reduce( *rhs ) ) };
RA_eq( RA* lhs, RA* rhs ) { return( reduce( *lhs ) == reduce( *rhs ) ) };
RA_ge( RA* lhs, RA* rhs ) { return( reduce( *lhs ) >= reduce( *rhs ) ) };
RA_gt( RA* lhs, RA* rhs ) { return( reduce( *lhs )  > reduce( *rhs ) ) };
RA_cmp( RA* lhs, RA* rsh )
   {
   RA x = reduce( *lhs );
   RA y = reduce( *rhs );
   if ( x < y )
      {
      return( -1 );
      }
   else if ( y > x )
      {
      return( 1 );
      }
   else
      {
      return( 0 );
      }
   }
