/* ***************************************************
 * *                                                 *
 * *  Display contents of a protected area products  *
 * *         WARN, SLINE, TRACK, TDWR                *
 * *                                                 *
 * ***************************************************
 * File: iris/examiners/product_warn.C
 * 
 *                COPYRIGHT (c) 2001, 2002, 2004 BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED. 
 */
#include <math.h>
#include <stdio.h>
#include <string.h>

#include "sigtypes.h"
#include "headers.h"
#include "setup.h"
#include "product.h"
#include "misc_lib.h"
#include "user_lib.h"


/* Function prototypes used just within this file
 */


static void product_warn_one
  (SINT4 ipoint_a,
   const struct protect_setup *prots_a,
   const struct warning_results *results_a );

static void PrintProtectMask
( const char *sTitle_a,
  const struct protect_setup *prots_a,
  UINT4 iprotect_mask_a );


static void product_sline_one
  (SINT4 iline_a,
   const struct protect_setup *prots_a,
   const struct sline_results *results_a );

static void product_track_one
  (SINT4 ipoint_a,
   const struct product_hdr *phead_a,
   const struct protect_setup *prots_a,
   const struct track_results *ptrack_a );

static void print_etas
  (const struct protect_setup *prots_a,
   const SINT4 iprotect_etas_a[32] );

static void product_tdwr_one
(SINT4 ipoint_a,
 const struct product_hdr *phead_a,
 const struct tdwr_results *pTdwr_a );

/* ================================================================
 * Print out information about a warning product file:
 */
void product_warn
(const struct warn_product *pWarn_a,
 UINT2 icentroid_label_a )
{
  SINT4 iwarning;
  char smessage[81];
  UINT4 lwarning_found;
  const struct product_hdr     *pHead;
  const struct protect_setup   *prots ;
  const struct warning_results *results ;

  pHead   = &pWarn_a->Header;
  prots   = &pWarn_a->Protect;
  results = pWarn_a->Results;

  PrintProtectMask( "Protected areas enabled:\n", prots, pHead->pcf.psi.warn.iprotect_mask );
  /* Print out the number of warnings: */
  printf("Product contains %d regions found.\n", pHead->end.iresults_count );

  /* Loop through the text points */
  for (iwarning = 0; iwarning<pHead->end.iresults_count; iwarning++)
    {
      product_warn_one( iwarning, prots, &results[iwarning] );
    }

  lwarning_found = look_for_warning( pHead, smessage, icentroid_label_a );
  if (lwarning_found)
    {
      printf("\nMessage signalled '%s'\n", smessage );
    }
  else
    {
      printf("\nNo Message signalled.\n" );
    }

  return;
}

/* ================================================================
 * Compose a text description of a warning area.
 * History:
 *     jmh   26 Dec 1990   Init
 * Entry parameters:
 *     ipoint_a - Point number
 */
static void product_warn_one
  (SINT4 ipoint_a,
   const struct protect_setup *prots_a,
   const struct warning_results *results_a )
{
  char sline[81];
  FLT4 fangle, ftemp1, ftemp2;

  printf( "\nRegion %d.\n", ipoint_a );

  fangle = fDegFromBin4( results_a->ilatitude );
  strcpy( sline, srdeg_to_lat( fangle ) );
  fangle = fDegFromBin4( results_a->ilongitude );
  strcat( sline, srdeg_to_lon( fangle ) );
  ftemp1 = ((FLT4)results_a->iheight)/100000.0;
  printf( "Location: %s, Height: %4.2f km", sline, ftemp1 );

  ftemp1 = ((FLT4)results_a->iprop_speed) / 1000.0 ;
  fangle = fPDegFromBin4(results_a->iprop_direction) ;
  printf( ", Moving: %4.1fm/s @ %1ddeg\n", ftemp1, NINT(fangle) ) ;

  ftemp1 = ((FLT4)results_a->iarea)/100.;
  printf( "Area: %5.2f square km.\n", (double)ftemp1 );

  ftemp1 = ((FLT4)results_a->iEllipseMajor)/100000.;
  ftemp2 = ((FLT4)results_a->iEllipseMinor)/100000.;
  fangle = fPDegFromBin4( results_a->iEllipseAngle );
  printf( "Elipse: %5.2f by %5.2f km, orientation %4.1f degrees.\n",
	 (double)ftemp1, (double)ftemp2, (double)fangle );

  printf( "Protected areas: %x\n", results_a->iprotect_mask );

  printf( "Maximum values: %5.2f %5.2f %5.2f\n",
	 ((double)results_a->imax_value[0]) / 100.0,
	 ((double)results_a->imax_value[1]) / 100.0,
	 ((double)results_a->imax_value[2]) / 100.0 );

  printf( "Average values: %5.2f %5.2f %5.2f\n",
	 ((double)results_a->iaverage_value[0]) / 100.0,
	 ((double)results_a->iaverage_value[1]) / 100.0,
	 ((double)results_a->iaverage_value[2]) / 100.0 );

  ftemp1 = ((FLT4)results_a->iscale)/100000.;
  printf( "Scale of input: %7.4f km/pixel\n", (double)ftemp1 );
  printf( "Text message: '%s'\n", results_a->stext );
}

/* ================================================================
 * Print out information about a sline product file:
 */
void product_sline
(const struct sline_product *pSline_a,
 UINT2 icentroid_label )
{
  SINT4 isline;
  const struct product_hdr   *pHead;
  const struct protect_setup *prots ;
  const struct sline_results *results ;
  UINT4 lwarning_found;
  char smessage[81];

  pHead   = &pSline_a->Header;
  prots   = &pSline_a->Protect;
  results = pSline_a->Results;

  PrintProtectMask(  "Protected areas enabled:\n", prots, pHead->pcf.psi.sline.iprotect_mask );
  /* Print out the number of shearlines: */
  printf("Product contains %d shearlines found.\n", pHead->end.iresults_count );

  /* Loop through the text points */
  for (isline = 0; isline<pHead->end.iresults_count; isline++)
    {
      product_sline_one( isline, prots, &results[isline] );
    }

  lwarning_found = look_for_warning( pHead, smessage, icentroid_label ) ;
  if (lwarning_found)
    {
      printf("\nMessage signalled '%s'\n", smessage );
    }
  else
    {
      printf("\nNo Message signalled.\n" );
    }
}

/* ================================================================
 * Compose a text description of a shear line.
 * Entry parameters:
 *     iline_a - Point number
 */
static void product_sline_one
  (SINT4 iline_a,
   const struct protect_setup *prots_a,
   const struct sline_results *results_a )
{
  FLT4 fangle, ftemp[6];
  SINT4 ii;

  printf( "\nShear Line %d.\n", iline_a );

  ftemp[0] = ((FLT4)results_a->icenter_east)/100000.0;
  ftemp[1] = ((FLT4)results_a->icenter_north)/100000.0;
  printf( "Center location: %5.1f km East, %5.1f km North\n", 
	 (double)ftemp[0], (double)ftemp[1] );

  fangle = fPDegFromBin4( results_a->irotation );
  printf( "Rotation angle: %5.1f degrees.\n", (double)fangle );

  ftemp[0] = ((FLT4)results_a->ixleft)/100000.0;
  ftemp[1] = ((FLT4)results_a->ixright)/100000.0;
  printf( "Length is from: %5.1f km to %5.1f km\n", (double)ftemp[0], (double)ftemp[1] );

  printf( "Ref wind: %3.1f m/s @ %d, other: %3.1f m/s @ %d\n",
	  ((FLT4)results_a->iref_wind_speed)/1000.0,
 	  NINT(fPDegFromBin4(results_a->iref_wind_direction)),
 	  ((FLT4)results_a->iother_wind_speed)/1000.0,
 	  NINT(fPDegFromBin4(results_a->iother_wind_direction)) );

  printf( "Polynomial:\n" );
  for (ii=0; ii<6; ii++)
    {
      ftemp[ii] = ((FLT4)results_a->icoefs[ii])/100000.0;
      printf( "    P%d=%10.5f km.\n", ii, (double)ftemp[ii] );
    }
  printf( "Standard deviation: %10.5f km.\n", ((double)results_a->ifit_std)/100000.0 );

  if (results_a->iflags & SLINE_FLG_FCST)
    {
      ftemp[0] = ((FLT4)results_a->iprop_speed)/1000.0;
      fangle = fPDegFromBin4( results_a->iprop_direction );
      printf( "Forecast speed %5.1f m/s, bearing %d degrees.\n", (double)ftemp[0],
	     (int)NINT(fangle) );

    }
  else
    {
      printf( "No motion forecast.\n" );
    }
  print_etas( prots_a, results_a->iprotect_etas );

  return;
}

/* ================================================================
 * Print out information about a track product file:
 * History:
 *     jmh   12 Dec 1990   Init
 * Entry parameters:
 *     phead_a - Product header
 */
void product_track
(const struct track_product *pTrack_a,
 UINT2 icentroid_label_a )
{
  SINT4 ipoint;
  UINT4 lwarning_found;
  char smessage[81];
  char sTZName[TZNAME_SIZE];
  const struct product_hdr   *pHead;
  const struct protect_setup *prots;
  const struct track_results *results;
  /* -------------------------------------------------------------- */
  pHead   = &pTrack_a->Header;
  prots   = &pTrack_a->Protect;
  results = pTrack_a->Results;

  TZNameBuild( sTZName, pTrack_a->Header.end.sLocalTZName, pTrack_a->Header.end.iMinutesWest,
	       pTrack_a->Header.pcf.ing_time.imills );

  PrintProtectMask( "Protected areas enabled:\n", prots, pHead->pcf.psi.track.iprotect_mask );

  /* Loop through the points
   */
  printf("\nProduct contains %d track points.", pHead->end.iresults_count );

  lwarning_found = look_for_warning( pHead, smessage, icentroid_label_a );
  if( lwarning_found ) {
    printf("  Message signalled: '%s'\n", smessage );
  } else {
    printf("  No messages signalled.\n" );
  }

  for( ipoint = 0 ; ipoint < pHead->end.iresults_count ; ipoint++ )
    {
      if( (ipoint == 0) ||
	 (0 != memcmp((char *)&results[ipoint  ].time,
		      (char *)&results[ipoint-1].time, sizeof(struct ymds_time)) ) )
	{
	  char sTimeBuffer[21];
	  printf( "\n    ------------- Data for %s %s -------------\n",
		 shhmmssddmonyyyy_r( &results[ipoint].time, sTimeBuffer ), sTZName ) ;
	  printf( "     -Index- -Latitude- -Longitude-  -Max-  -Avg-    --Motion--\n" ) ;
	}

      product_track_one( ipoint, pHead, prots, &results[ipoint] );
    }
}

/* ================================================================
 * Compose a text description of a track point.
 * History:
 *     jmh   26 Dec 1990   Init
 * Entry parameters:
 *     ipoint_a - Point number
 */
static void product_track_one
(SINT4 ipoint_a,
 const struct product_hdr *phead_a,
 const struct protect_setup *prots_a,
 const struct track_results *ptrack_a )
{
  FLT4 flat, flon, fspeed;
  SINT4 ilength, iangle;

  /* -------------------------------------------------------------- */
  if( ptrack_a->iflags & TRACK_FLG_MANUAL ) printf( "M" ) ; else printf ( " " ) ;
  if( ptrack_a->iflags & TRACK_FLG_TEXT   ) printf( "T" ) ; else printf ( " " ) ;

  printf( "%4d (%3.3d)", (1 + ipoint_a), ptrack_a->index ) ;

  flat = fDegFromBin4( ptrack_a->ilat );
  flon = fDegFromBin4( ptrack_a->ilong );
  printf( " %s  %s %6.2f %6.2f ", srdeg_to_lat(flat), srdeg_to_lon(flon),
	  ((double)ptrack_a->imax_value    ) / 100.0,
	  ((double)ptrack_a->iaverage_value) / 100.0 );

  if( ptrack_a->iflags & TRACK_FLG_TEXT )
    {
      ilength = strlen( ptrack_a->stext ) ; ilength = MIN(ilength, 16) ;
      if( ilength > 0 ) printf( "'%s'", ptrack_a->stext ) ;
    }

  if( ptrack_a->iflags & TRACK_FLG_FCST )
    {
      fspeed = (ptrack_a->iprop_speed) / 1000.0 ;
      iangle = NINT( fPDegFromBin4(ptrack_a->iprop_direction) ) ;
      printf( "%5.1fm/s %3ddeg", (double)fspeed, iangle ) ;
    }
  else
    {
      printf( "  --No motion--" ) ;
    }
  printf( "\n" ) ;

  print_etas( prots_a, ptrack_a->iprotect_etas );
}

/* ==============================================================
 * Prints the Estimated time of arrival for each the defined protected areas
 * for the product.
 */
static void print_etas
(const struct protect_setup *prots_a,
 const SINT4 iprotect_etas_a[32] )
{
  SINT4 iregion;
  const char *pname;
  for (iregion=0; iregion<IMAX_PROT_REGIONS; iregion++)
    {
      pname = prots_a->protected_regions[iregion].sname;
      if ( pname[0] != ' ' )
	{
	  if (iprotect_etas_a[iregion] != -1) 
	    printf("     ETA to %12.12s: %d sec.\n", pname, iprotect_etas_a[iregion] );
	}
    }

  return;
}

/* ==============================================================
 * Prints a list of the protected areas which are enabled
 * for the product.
 */
static void PrintProtectMask
(const char *sTitle_a,
const struct protect_setup *prots_a,
 UINT4 iprotect_mask_a )
{
  SINT4 iregion;
  UINT2 lnone_found_so_far;
  const char *pname;

  lnone_found_so_far = TRUE;
  if (sTitle_a) printf( sTitle_a );
  for (iregion=0; iregion<IMAX_PROT_REGIONS; iregion++)
    {
      pname = prots_a->protected_regions[iregion].sname;
      if ( pname[0] != ' ' )
	{
	  if (BTEST( iprotect_mask_a, iregion ))
	    {
	      printf("   %2d: %12.12s\n", iregion, pname );
	      lnone_found_so_far = FALSE;
	    }
	}
    }

  if (lnone_found_so_far&&sTitle_a) printf( "None.\n" );
}

/* ================================================================
 * Print out information about a TDWR product file:
 */
void product_tdwr
(const struct product_hdr *phead_a )
{
  SINT4 iCorridor;
  UINT4 iWarning;
  const struct protect_setup *prots;
  const struct tdwr_results *results;
  const struct warning_results *pWarnings;
  /* -------------------------------------------------------------- */
  prots   = (struct protect_setup *)(PRODUCT_HDR_SIZE   + (UINT1 *)phead_a );
  results = (struct tdwr_results *)(PROTECT_SETUP_SIZE + (UINT1 *)prots );

  PrintProtectMask( "Protected areas enabled:\n", prots, phead_a->pcf.psi.tdwr.iprotect_mask );
  /* Loop through the points
   */
  printf("Product contains %d corridors.\n", phead_a->end.iresults_count );

  for( iCorridor=0 ; iCorridor < phead_a->end.iresults_count ; iCorridor++ )
    {
      product_tdwr_one( iCorridor, phead_a, &results[iCorridor] );
    }
  printf("Product also contains %d centroids.\n", phead_a->pcf.psi.tdwr.iCentroidCount );
  pWarnings = (const struct warning_results *)(void*)(results+phead_a->end.iresults_count);
  for (iWarning = 0; iWarning<phead_a->pcf.psi.tdwr.iCentroidCount; iWarning++)
    {
      product_warn_one( iWarning, prots, &pWarnings[iWarning] );
    }
  printf("\nProduct also contains %d shearlines.\n", phead_a->pcf.psi.tdwr.iSlineCount );
}

/* ================================================================
 * Compose a text description of a track point.
 * History:
 *     jmh   26 Dec 1990   Init
 * Entry parameters:
 *     ipoint_a - Point number
 */
static void product_tdwr_one
(SINT4 ipoint_a,
 const struct product_hdr *phead_a,
 const struct tdwr_results *pTdwr_a )
{
  char sArena[8]; FLT4 fSpeed;
  const struct protect_setup *prots;

  prots   = (struct protect_setup *)(PRODUCT_HDR_SIZE   + (UINT1 *)phead_a );
  spacify_ncpy( sArena, pTdwr_a->sArena, 3 );
  fSpeed = ((FLT4)pTdwr_a->iLossGain)/1000.0;
  printf( "%2d: %4.4s %3.3s %3.3s%6.1fm/s",
	  ipoint_a, pTdwr_a->sCorridor, pTdwr_a->sAlertType, sArena, fSpeed );
  printf( " TH%3.3s %3.3sknots",
	  pTdwr_a->sThresholdDirection, pTdwr_a->sThresholdSpeed );
  printf( "\n" ) ;
  PrintProtectMask( "Protected areas enabled:\n", prots, pTdwr_a->iProtectMask );
  PrintProtectMask( "Protected area hit:", prots, pTdwr_a->iProtectHit );
  printf( "\n" ) ;

}
