<?php

/*
   ###########################################################################
   Horizons Heliocentric Ephemeris Demo Code - WITH 30-DAY COOKIE

   AUTHOR   : Jay Tanner - 2026
   LANGUAGE : PHP v8.2.12
   LICENSE  : Public Domain

   Built around the NASA/JPL Horizons API

   This program demonstrates making a basic customized heliocentric ephemeris
   for any planet or asteroid in the NASA/JPL database.

   It is basically a demo and does NOT extensively check for argument errors.

   The core function  could be used to generate  a series of positions of some
   astronomical body, such as a comet, for plotting its path in space relative
   to the position of the sun on some form of 2D or 3D chart relative .
   ###########################################################################
*/

   
ob_start(); // Oy!  The pain!

// ---------------------------------------------------------------
// Define the program cookie name and set it to expire in 30 days.

   
$CookieName 'Horizons-Heliocentric-Ephemeris';
   
$SetToExpireIn30Days time() + 30*86400;

// ------------------------------------------------------------------
// Define JavaScript message to display in (TextArea1) while working.

   
$_COMPUTING_ "TextArea1.innerHTML='                  W.O.R.K.I.N.G --- This may take a few seconds.';";

// ---------------------------------
// Define PHP program and HTML info.

   
$_AUTHOR_           'Jay Tanner';
   
$_PROGRAM_VERSION_  'v1.00 - '$at "&#97;&#116;&#32;&#76;&#111;&#99;&#97;&#108;&#32;&#84;&#105;&#109;&#101;&#32;"$LTC "&#85;&#84;&#67;";
   
$_SCRIPT_FILE_PATH_ Filter_Input(INPUT_SERVER'SCRIPT_FILENAME');
   
$_REVISION_DATE_    $_PROGRAM_VERSION_ .'Revised: 'date("Y-F-d-l $at h:i:s A   ($LTC"FileMTime($_SCRIPT_FILE_PATH_))."&minus;05:00)";
   
$_BROWSER_TAB_TEXT_ "Horizons Heliocentric Ephemeris DEMO";
   
$_INTERFACE_TITLE_  "<span style='font-size:15pt;'>Horizons Heliocentric Ephemeris DEMO</span><br><span style='font-size:13pt;'>Built Around the NASA/JPL Horizons API</span><br><span style='font-size:10pt;'>PHP Program by Jay Tanner of Geneva, NY, USA</span>";


/* -------------------------------------
   Define main TextArea text and background
   colors and HTML table row span. If an
   error is reported, then these colors
   will change internally to red/white.
*/
   
$TxColor 'black';
   
$BgColor 'white';


// ------------------------------------------------
// Do this only if [SUBMIT] button was NOT clicked.

   
$w Filter_Input(INPUT_POST'SubmitButton');

   if (!IsSet(
$w))
  {

/* ----------------------------------------------------------------------
   If this program is being called externally, rather than being executed
   by clicking the [SUBMIT] button, and an active cookie also exists,
   then restore the previously saved interface settings from it. If
   the user leaves and comes back later, all the interface settings
   will be remembered and restored if the cookie was not deleted.
*/
   
$w Filter_Input(INPUT_COOKIE$CookieName);

   if (IsSet(
$w))
      {
       
$CookieDataString Filter_Input(INPUT_COOKIE$CookieName);
       list
      (
       
$BodyID,
       
$TimeScale,
       
$StartBCAD,
       
$StartYear,
       
$StartMonth,
       
$StartDay,
       
$StartTime,
       
$TimeZone,
       
$StopBCAD,
       
$StopYear,
       
$StopMonth,
       
$StopDay,
       
$StopTime,
       
$DaySumYN,
       
$StepSize
      
) = Preg_Split("[\|]"$CookieDataString);

      }

   else

/* -----------------------------------------------------------
   If there is no previous cookie with the interface settings,
   then set the initial default interface startup values and
   store them in a new cookie.
*/
 
{
  
$BodyID     '399';
  
$TimeScale  'UT';
  
$StartBCAD  'AD';
  
$StartYear  date('Y');
  
$StartMonth date('M');
  
$StartDay   date('d');
  
$StartTime  '00:00:00';
  
$TimeZone   '+00:00';
  
$DaySumYN   'No';
  
$StopBCAD   'AD';
  
$StopYear   date('Y');
  
$StopMonth  date('M');
  
$StopDay    date('d');
  
$StopTime   '23:00:01';
  
$StepSize   '1 hour';

// -------------------------------------------
// Store current interface settings in cookie.

   
$CookieDataString "$BodyID|$TimeScale|$StartBCAD|$StartYear|$StartMonth|$StartDay|$StartTime|$TimeZone|$StopBCAD|$StopYear|$StopMonth|$StopDay|$StopTime|$DaySumYN|$StepSize";
   
SetCookie ($CookieName$CookieDataString$SetToExpireIn30Days);
  } 
// End of  else {...}

  
// End of  if (...)


/* ------------------------------------------
   Read values of all interface arguments and
   set any empty arguments to default values.
*/
   
$w Filter_Input(INPUT_POST'SubmitButton');

   if (isset(
$w))
{
   
$BodyID     trim(Filter_Input(INPUT_POST'BodyID'));
                 if (
$BodyID == '') {$BodyID '399';}

   
$TimeScale  StrToUpper(trim(Filter_Input(INPUT_POST'TimeScale')));
                 if (
$TimeScale == '') {$TimeScale 'UT';}

   
$StartBCAD  trim(Filter_Input(INPUT_POST'StartBCAD'));
                 if (
$StartBCAD == '') {$StartBCAD 'AD';}

   
$StartYear  trim(Filter_Input(INPUT_POST'StartYear'));
                 if (
$StartYear == '') {$StartYear date('Y');}

   
$StartMonth trim(Filter_Input(INPUT_POST'StartMonth'));
                 if (
$StartMonth == '') {$StartMonth date('M');}

   
$StartDay   trim(Filter_Input(INPUT_POST'StartDay'));
                 if (
$StartDay == '') {$StartDay date('d');}

   
$StartTime  trim(Filter_Input(INPUT_POST'StartTime'));
                 if (
$StartTime == '') {$StartTime date('H:i:s');}

   
$TimeZone   trim(Filter_Input(INPUT_POST'TimeZone'));
                 if (
$TimeZone == '') {$TimeZone '+00:00';}

   
$DaySumYN   StrToUpper(trim(Filter_Input(INPUT_POST'DaySumYN')));
                 if (
$DaySumYN == '') {$DaySumYN 'No';}
   
$DaySumYN   substr($DaySumYN,0,1);
   
$DaySumYN   = ($DaySumYN == 'Y')? 'Yes':'No';

   
$StopBCAD   trim(Filter_Input(INPUT_POST'StopBCAD'));
                 if (
$StopBCAD == '') {$StopBCAD 'AD';}

   
$StopYear   trim(Filter_Input(INPUT_POST'StopYear'));
                 if (
$StopYear == '') {$StopYear date('Y');}

   
$StopMonth  trim(Filter_Input(INPUT_POST'StopMonth'));
                 if (
$StopMonth == '') {$StopMonth date('M');}

   
$StopDay    trim(Filter_Input(INPUT_POST'StopDay'));
                 if (
$StopDay == '') {$StopDay date('d');}

   
$StopTime   trim(Filter_Input(INPUT_POST'StopTime'));
                 if (
$StopTime == '') {$StopTime '23:00:01';}

   
$StepSize   trim(Filter_Input(INPUT_POST'StepSize'));
                 if (
$StepSize == '') {$StepSize '1 hour';}


// -------------------------------------
// Store interface argument in a cookie.

   
$CookieDataString "$BodyID|$TimeScale|$StartBCAD|$StartYear|$StartMonth|$StartDay|$StartTime|$TimeZone|$StopBCAD|$StopYear|$StopMonth|$StopDay|$StopTime|$DaySumYN|$StepSize";
   
SetCookie ($CookieName$CookieDataString$SetToExpireIn30Days);
}


// *******************************************************************
// *******************************************************************
// START MAIN FUNCTION CALL CODE HERE.

// ----------------------
// Set start dates/times.

   
$StartDateTime "$StartBCAD $StartYear-$StartMonth-$StartDay $StartTime";
   
$StopDateTime  "$StopBCAD $StopYear-$StopMonth-$StopDay $StopTime";


// -------------------------------
// Compute the heliocentric table.

   
$HelioCoordsTableC Helio_Coords($BodyID,$StartDateTime,$StopDateTime,
                                     
$TimeZone,$TimeScale,$StepSize'C');



   
$HelioCoordsTableR Helio_Coords($BodyID,$StartDateTime,$StopDateTime,
                                     
$TimeZone,$TimeScale,$StepSize'R');



/* -----------------------------------
   Set initial uniform width for input
   tables alignment in pixels.
*/
   
$TableWidth '780';


// ******************************************
// ******************************************

/* ----------------------------------------
   Optionally check arguments for validity.
   If errors found, then set error flag and
   message values.
*/
   
$ErrFlag FALSE;
   
$ErrMssg '';

/* THIS FEATURE IS DISABLED IN THIS PROGRAM.

   If error was reported (TRUE), then display
   the error message on a red background.
*/
   
if ($ErrFlag === TRUE)
  {
   
$TxColor 'white';
   
$BgColor '#CC0000';
   
$TextArea2Text '';

   
$TextArea1Text =
"=== ERROR ===

$ErrMssg";
  }

else


  {
/* *********************************************************
   BEGIN MAIN COMPUTATIONS HERE IF NO ERRORS DETECTED ABOVE.
   DROP THROUGH HERE AFTER COMPUTATIONS ABOVE
   TO PRINT OUT THE RESULTS OF THE OPERATIONS.
   *********************************************************
*/

   
$TextArea1Text =
"                          HELIOCENTRIC COORDINATES TABLE
                      Computed via the NASA/JPL Horizons API


For JPL Body ID  = 
$BodyID

Time Scale       = 
$TimeScale
Time Zone        = 
$TimeZone  (Time Zone ignored if using TT Time Scale)

Start Date/Time  = 
$StartBCAD $StartYear-$StartMonth-$StartDay  $StartTime
Stop  Date/Time  = 
$StopBCAD $StopYear-$StopMonth-$StopDay  $StopTime
Ephem Step Size  = 
$StepSize
Day/Sum     Y/N  = 
$DaySumYN
****************************************************************************
****************************************************************************

$HelioCoordsTableC
"
;
  }

// ****************************
// Define TextArea2 text block.

   
$TextArea2Text =
"Below is the raw ephemeris table from which the above table was extracted.
The customized smaller table is more compact and suitable for printing.

Notice that the table of interest is contained between two special markers:
\$\$SOE     Which means Start_Of_Ephemeris
and
\$\$EOE     Which means End_Of_Ephemeris

The table can consist of from 1 up to multiple lines, depending on Step Size.

The raw tables returned from the Horizons API may need to be reformatted to
a smaller format to be able to be printed on ordinary (80-column) paper.

This program is essentially a demo and does NOT extensively check for errors
in the input arguments, but it gets the basic job done.  Some argument errors
may cause a crash.  Generally, valid input should return valid output, but if
possible, cross-check.

$HelioCoordsTableR
"
;

   if (
$GLOBAL_ERROR_FLAG) {$TextArea2Text '';}

// **************************************************************************
// Determine number of text columns and rows to use in the output text areas.
// These values vary randomly according to the text block width and length.
// The idea is to eliminate the need for scroll-bars within the text areas
// or worry as much about the variable dimensions of a text display area.

// --------------------------------------------
// Text Area 1 - Default = At least 80 columns.

   
$Text1Cols Max(Array_Map('StrLen'PReg_Split("[\n]"trim($TextArea1Text))));
   if (
$Text1Cols 80) {$Text1Cols 80;}  // Default
   
$Text1Rows Substr_Count($TextArea1Text"\n");

// --------------------------------------------
// Text Area 2 - Default = At least 80 columns.

   
$Text2Cols Max(Array_Map('StrLen'PReg_Split("[\n]"trim($TextArea2Text))));
   if (
$Text2Cols 80) {$Text2Cols 80;} // Default
   
$Text2Rows Substr_Count($TextArea2Text"\n");



// ******************************************
// ******************************************
// GENERATE CLIENT WEB PAGE TO DISPLAY OUTPUT

   
print <<< _HTML

<!DOCTYPE HTML>
<HTML>

<head>
<title>
$_BROWSER_TAB_TEXT_</title>

<meta name='viewport'           content='width=device-width, initial-scale=0.8'>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'>
<meta http-equiv='pragma'       content='no-cache'>
<meta http-equiv='expires'      content='-1'>
<meta name='description'        content='xxxxxxxxxxxxxxx'>
<meta name='keywords'           content='NeoProgrammics  / PHP Science Labs'>
<meta name='author'             content='Jay Tanner - https://www.PHPScienceLabs.com'>
<meta name='robots'             content='noindex,nofollow'>
<meta name='googlebot'          content='noindex,nofollow'>

<style>

 BODY {color:white; background:black; font-family:Verdana; font-size:12pt; line-height:125%;}

 TABLE
{font-size:13pt; border: 1px solid black;}


 TD
{
 color:black; background:white; line-height:150%; font-size:10pt;
 padding:6px; text-align:center;
}


 UL
{font-family:Verdana; font-size:12pt; line-height:150%; text-align:justify;}


 PRE
{
 background:white; color:black; font-family:monospace; font-size:12.5pt;
 font-weight:bold; text-align:left; line-height:125%; padding:6px;
 border:2px solid black; border-radius:8px;
 page-break-before:page;
}


 DIV
{
 background:white; color:black; font-family:Verdana; font-size:11pt;
 font-weight:normal; line-height:125%; padding:6px;
}


 TEXTAREA
{
 background:white; color:black; font-family:monospace; font-size:13pt;
 font-weight:bold; padding:4pt; white-space:pre; border-radius:8px;
 line-height:125%;
}


 INPUT[type='text']::-ms-clear {width:0; height:0;}

 INPUT[type='text']
{
 font-family:monospace; color:black; background:white; font-size:13pt;
 font-weight:bold; text-align:center; box-shadow:2px 2px 3px #666666;
 border:2px solid black; border-radius:4px;
}
 INPUT[type='text']:focus
{
 font-family:monospace; background:white; box-shadow:2px 2px 3px #666666;
 font-size:13pt; border:2px solid blue; text-align:center; font-weight:bold;
 border-radius:4px;
}



 INPUT[type='submit']
{
 background:black; color:cyan; font-family:Verdana; font-size:10pt;
 font-weight:bold; border-radius:4px; border:4px solid #777777;
 padding:3pt;
}
 INPUT[type='submit']:hover
{
 background:black; color:white; font-family:Verdana; font-size:10pt;
 font-weight:bold; border-radius:4px; border:4px solid red;
 padding:3pt;
}


// Link states MUST be set in the following order:
// :link, :visited, :hover, :active

 A:link
{
 font-size:10pt; background:transparent; color:#8080FF; border-radius:4px;
 font-family:Verdana; font-weight:bold; text-decoration:none;
 line-height:175%; padding:3px; border:1px solid transparent;
}
 A:visited
{
 font-size:10pt; background:transparent; color:DarkCyan; border-radius:4px;
}
 A:hover
{
 font-size:10pt; background:yellow; color:black; border:1px solid black;
 box-shadow:1px 1px 3px #222222; border-radius:4px;
}
 A:active
{
 font-size:10pt; background:yellow; color:black; border-radius:4px;
}


 HR {background:red; height:4px; border:0px;}


[title-text]:hover:after
{
 opacity:1.0;
 transition:all 1.0s ease 1.0s;
 text-align:left;
 visibility:visible;
}

[title-text]:after
{
 opacity:1.0;
 content:attr(title-text);
 text-align:left;
 left:50%;
 background-color:yellow;
 color:black;
 font-size:10pt;
 position:absolute;
 padding:1px 5px 2px 5px;
 white-space:pre;
 border:1px solid red;
 z-index:1;
 visibility:hidden;
}

[title-text] {position: relative;}


::selection{background-color:yellow !important; color:black !important;}
::-moz-selection{background-color:yellow !important; color:black !important;}
</style>

</head>

<body>

<!-- Define container form --->
<form name="form1" method="post" action="">

<!-- Define main page title/header. --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">

<tr><td colspan="99" style="color:white; background-color:#000066; border:2px solid white; border-radius:8px 8px 0px 0px;">
$_INTERFACE_TITLE_</td></tr>
</table>

<!-- Define input (BodyID) text box  --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td style="line-height:175%;" width='25%'
title='&nbsp;MAJOR BODY IDs&nbsp;
10   = Sun
199 = Mercury
299 = Venus
301 = Moon (Luna)&nbsp;
399 = Earth
499 = Mars
599 = Jupiter
699 = Saturn
799 = Uranus
899 = Neptune
999 = Pluto

&nbsp;ASTEROID IDs
1;    = Ceres;
2;    = Pallas;
3;    = Juno;
4;    = Vesta;
5;    = Astraea;
6;    = Hebe;
7;    = Iris;
8;    = Flora;
9;    = Metis;
10;  = Hygiea;

3I;   = 90004923;
-31  = Voyager 1
-32  = Voyager 2
'>NASA/JPL&nbsp;Body&nbsp;ID<br>
<input name="BodyID"  type="text" value="
$BodyID" size="33" maxlength="32"></td>
</tr>
</table>

<!-- Define input (TimeScale) text box  --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td style="line-height:175%;" width='25%'>Time&nbsp;Scale<br><input name="TimeScale"  type="text" value="
$TimeScale" size="3" maxlength="2"></td>

<td >Start&nbsp;Date&nbsp;and&nbsp;Time<br><input name="StartBCAD"  type="text" value="
$StartBCAD" size="3" maxlength="2">
<input name="StartYear"  type="text" value="
$StartYear" size="6" maxlength="5"><input name="StartMonth"  type="text" value="$StartMonth" size="4" maxlength="3"><input name="StartDay"  type="text" value="$StartDay" size="3" maxlength="2">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input name="StartTime"  type="text" value="
$StartTime" size="9" maxlength="8"></td>

<td style="line-height:175%;" width='25%'>Time Zone<br><input name="TimeZone"  type="text" value="
$TimeZone" size="7" maxlength="6"></td>
</tr>

<td style="line-height:175%;" width='25%'>Daylight/Summer&nbsp;Time<br><input name="DaySumYN"  type="text" value="
$DaySumYN" size="4" maxlength="3">

<td >Stop&nbsp;Date&nbsp;and&nbsp;Time<br><input name="StopBCAD"  type="text" value="
$StopBCAD" size="3" maxlength="2">
<input name="StopYear"  type="text" value="
$StopYear" size="6" maxlength="5"><input name="StopMonth"  type="text" value="$StopMonth" size="4" maxlength="3"><input name="StopDay"  type="text" value="$StopDay" size="3" maxlength="2">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input name="StopTime"  type="text" value="
$StopTime" size="9" maxlength="8"></td>

<td >Step&nbsp;Size<br><input name="StepSize"  type="text" value="
$StepSize" size="10" maxlength="12"></td>
</tr>
</table>


<!-- Top yellow source code view link. --->
<br>
<table width="
$TableWidth" align="center" cellspacing="1" cellpadding="3">
<tr>
<td colspan="1" style='font-size:10pt; color:black; background:black;
                       text-align:center;' title=' Tries to Open in a New Tab. '>
<b><a href="View-Source-Code.php" target="_blank"
     style='font-family:Verdana; color:black; background:yellow;
            text-decoration:none; border:1px solid black; padding:4px;
            border-radius:4px; font-weight:normal;'>
&nbsp;View/Copy Source Code&nbsp;</a></b>
</td>
</tr>
</table>




<!-- Define [SUBMIT] button --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr><td colspan="99" style="background-color:black;"><input type="submit" name="SubmitButton" value=" S U B M I T " OnClick="
$_COMPUTING_"
></td></tr>
</table>


<!-- Define TextArea1 --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="text-align:center; color:GreenYellow; background-color:black;">Double-Click Within Text Area to Select ALL Text<br>
<textarea ID="TextArea1" name="TextArea1" style="color:
$TxColor; background:$BgColor; padding:6px; border:2px solid white;" cols="$Text1Cols" rows="$Text1Rows" ReadOnly OnDblClick="this.select();" OnMouseUp="return true;">
$TextArea1Text
</textarea>
</td>
</tr>
</table>


<!-- Define TextArea2 --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="text-align:center; color:GreenYellow; background:black;">Double-Click Within Text Area to Select ALL Text<br>
<textarea ID="TextArea2" name="TextArea2" style="color:black; background:white; padding:6px;" cols="
$Text2Cols" rows="$Text2Rows" ReadOnly OnDblClick="this.select();" OnMouseUp="return true;">
$TextArea2Text
</textarea>
</tr>
</table>


<!-- Define page footer --->
<table width="
$TableWidth" align="center" border="0" cellspacing="1" cellpadding="3">
<tr>
<td colspan="99" style="color:GreenYellow; background:black;">PHP Program by 
$_AUTHOR_<br><span style="color:silver; background:black;">$_REVISION_DATE_</span></td>
</tr>
</table>

</form>
<!-- End of container form --->


<!-- Extra bottom scroll space --->
<br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br>

</body>
</HTML>



_HTML;



/*
   This function returns a table of heliocentric coordinates
   and distance from the sun for any valid NASA/JPL body ID.
*/

   
function Helio_Coords ($BodyID,$StartDateTime,$StopDateTime,$TimeZone,
                          
$TimeScale,$StepSize$TableType)

{

   GLOBAL 
$GLOBAL_ERROR_FLAG;

   
$GLOBAL_ERROR_FLAG FALSE;

// *********************************************************
// HELIOCENTRIC ECLIPTICAL COORDINATES AND DISTANCE OF BODY.

// URL-encode the query.
   
$Command URLEncode($BodyID);

   
$TableType StrToUpper(substr($TableType,0,1));

   
$From_Horizons_API =
   
"https://ssd.jpl.nasa.gov/api/horizons.api?format=text" .

   
"&COMMAND='$Command'"                     .
   
"&OBJ_DATA='YES'"                         .
   
"&MAKE_EPHEM='YES'"                       .
   
"&EPHEM_TYPE='OBSERVER'"                  .
   
"&CAL_FORMAT='BOTH'"                      .
   
"&CAL_TYPE='MIXED'"                       .
   
"&REF_SYSTEM='ICRF'"                      .
   
"&APPARENT='AIRLESS'"                     .
   
"&RANGE_UNITS='AU'"                       .
   
"&SUPPRESS_RANGE_RATE='YES'"              .
   
"&CENTER='500@10'"                        .
   
"&TIME_DIGITS='SECONDS'"                  .
   
"&TIME_ZONE='$TimeZone'"                  .
   
"&START_TIME='$StartDateTime $TimeScale'" .
   
"&STOP_TIME='$StopDateTime'"              .
   
"&STEP_SIZE='$StepSize'"                  .
   
"&EXTRA_PREC='YES'"                       .
   
"&CSV_FORMAT='YES'"                       .
   
"&QUANTITIES='18,19'"                     ;

// ----------------------------------------------------------------
// Get the heliocentric ecliptical longitude and latitude of body.

   
$HelioTable Str_Replace(",\n"" \n"trim(File_Get_Contents($From_Horizons_API)));

/* ----------------------------------------------------
   Set pointers to start and end of ephemeris table and
   extract ONLY the required ephemeris CSV data lines
   from between the Start/End pointers.
*/
   
$i StrPos($HelioTable'$$SOE');
   
$j StrPos($HelioTable'$$EOE');

   if (
$i === FALSE)
      {
       
$GLOBAL_ERROR_FLAG TRUE;
       return 
"$HelioTable";
      }

// -------------------------------------
// Return either raw or extracted table.
// according to the TableType setting.

   
if ($TableType == 'C')
  {
   
$HelioTable trim(substr($HelioTable$i+5$j-$i-5));
   
$HelioTable = (substr($HelioTable,0,1) <> 'b')? $HelioTable$HelioTable;

// Reformat customized heliocentric table.

   
$wArray PReg_Split("[\n]"$HelioTable);
   
$wCount count($wArray);
   
$out '';

   for (
$i=0;   $i $wCount;   $i++)
       {
        
$CurrLine $wArray[$i];
        list(
$DateTimeStr,$w,$w,$w$hLonDeg$hLatDeg$r) = PReg_Split("[,]"$CurrLine);

// Separate the Date/Time strings.
   
list($DateStr$TimeStr) = PReg_Split("[ ]"trim($DateTimeStr));

   if (
substr($DateStr,0,1) == 'b')
      {
$DateStr 'BC ' substr($DateStr,1StrLen($DateStr));}
   else
      {
$DateStr 'AD ' $DateStr;}

        
$out .= "$DateStr  $TimeStr $hLonDeg  $hLatDeg$r\n";
       }
       
$HelioTable trim($out);
  }

//
   
if ($TableType == 'R')
      {
       
$TableHeader '';
      }
   else
      {
   
$TableHeader =
"Calendar_Date     Time    Helio_Lon&#176;  Helio_Lat&#176;   Helio_Dist_AU
==============  ========  ==========  ==========  ================"
;
      }


// ---------------------------
// Output as plain text table.

   
return "$TableHeader\n$HelioTable";
}



// END OF PROGRAM

?>