/* bud32.h */

#include "resource.h"
#include "commdlg.h"
#include "commctrl.h"
#include "_ISource.h"
#include "eztwain.h"
#include "twain.h"
#include "mmsystem.h"	// NB. Winmm.lib needed in link list, too!!!
#include "vfw.h"		// This also needs vfw32.lib in the link list

#include <stdio.h>
#include <conio.h>
#include <direct.h>
#include <io.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <ctype.h>
#include <winspool.h>
#include <math.h>
#include <time.h>
#include <ShlObj.h>
#include <lmcons.h>


#define TOTAL_REBUILD  WM_USER + 300

#define SCROLLS        WM_USER + 356
#define CLOSEALL       WM_USER + 357

#define IDT_MSPAN	   WM_USER + 400

#define TG_GET_ALIGNS  WM_USER + 450 // "target" switch cases
#define TG_BUILD_DATA  WM_USER + 451
#define TG_MOVMEAN     WM_USER + 452
#define TG_MSPAN       WM_USER + 453

#define GET_ALIGN_DATA WM_USER + 460

#define IDM_SPLASH     WM_USER + 500
#define IDM_SCAN       WM_USER + 501
#define IDM_SHOWBM     WM_USER + 502
#define IDM_SHOW_SCAN  WM_USER + 503
#define WM_RESET       WM_USER + 504

#define IDT_BANNER_TIMER WM_USER + 505
#define IDT_BTIMER       WM_USER + 506
#define IDT_BTIMER1      WM_USER + 507
#define IDT_RTIMER       WM_USER + 508
#define IDT_VOCTIMER     WM_USER + 509
#define IDT_TIPDEFER     WM_USER + 510
#define IDT_TIPDWELL     WM_USER + 511
#define IDT_SELFTRKTIMER WM_USER + 512
#define IDT_DISMISS      WM_USER + 513
#define IDT_GRAB_TIMER   WM_USER + 514
#define IDT_SELSUITE	 WM_USER + 515
#define IDT_SLCTSUITE	 WM_USER + 516
#define IDT_HIT_TIMER    WM_USER + 517
#define IDT_GO_TIMER	 WM_USER + 518

#define SCR_GAIN         WM_USER + 520
#define SCR_THRESH       WM_USER + 521
#define SCR_SMOOTH       WM_USER + 522

#define ON_DRAW_CHANGE   WM_USER + 523
#define PRINT_COORDS     WM_USER + 524
#define RESIZE_IMAGE     WM_USER + 525

#define SCR_BRIGHT       WM_USER + 526
#define SCR_CONTRAST     WM_USER + 527
#define ED_BRIGHT        WM_USER + 528
#define ED_CONTRAST      WM_USER + 529

#define IDM_BRIGHT_UP          WM_USER + 530
#define IDM_CONTRAST_UP        WM_USER + 531
#define IDM_CHANGE_BRIGHT      WM_USER + 532
#define IDM_CHANGE_CONTRAST    WM_USER + 533
#define IDM_ACCEPT_BCHANGE     WM_USER + 534
#define IDM_ACCEPT_CCHANGE     WM_USER + 535
#define IDM_CANCEL_BCHANGE     WM_USER + 536
#define IDM_CANCEL_CCHANGE     WM_USER + 537

//#define IDM_PICK_N_MIX		   WM_USER + 538

#define IDM_SHOW_SETUP         WM_USER + 539

#define WM_XREF				   WM_USER + 550

#define IDC_GET_ITEMS_BUTTON      WM_USER + 600
#define IDC_LIST_ITEMS_BUTTON     WM_USER + 601
#define IDC_FOURIER_BUTTON        WM_USER + 602
#define IDC_DATAGRAPH_BUTTON      WM_USER + 603
#define IDC_ASTRONOMY_BUTTON      WM_USER + 604

#define IDC_LPOLE_BUTTON          WM_USER + 620
#define IDC_HPOLE_BUTTON          WM_USER + 621
#define IDC_SCAN_BUTTON           WM_USER + 622
#define IDC_LSCAN_BUTTON          WM_USER + 623
#define IDC_LEVELS_BUTTON         WM_USER + 624
#define IDC_GRAY_BUTTON           WM_USER + 625

#define WM_MOUSEGONE              WM_USER + 700
#define LEVEL_PICKED              WM_USER + 701
#define WM_DRAWSTUFF              WM_USER + 702
#define SETVIEWFRAME              WM_USER + 703

#define  OMAXLEVELS    25  //Max. # of measurement levels (old style)
#define   MAXLEVELS	   52  //Max. # of measurement levels (new style)
#define NUMCONTROLS    80  //Max. # of control buttons
#define    MAXITEMS    50  //Max. # of items in a search/collation
#define     MAXBUDS  9150  //Max. # of bud instances in collation (>25 year's worth)
#define     MAXDATA  7350  //Max. # of items in Fourier data set
#define    MAXPEAKS  3000  //Max. # of Luminance Peaks in a line scan
#define	    MAXDAYS  9150  //Max. # of days in the Grand Period (>25 year's worth)

#define    IMPERIAL    0
#define      METRIC    1
#define  IMAGEUNITS    2

#define         RAW    1
#define        MEAN    0

#define      RANGED    1
#define    UNRANGED	   0

#define        NONE    0
#define        LEFT    1
#define       RIGHT    2
#define        BOTH    3
#define        AXIS    4

   // Frames of reference.

#define MO   8   // Motional Frame on Mean Body
#define PT   7	 // Planetocentric
#define AP   6   // Appulse (not strictly a frame)
#define SE   5   // Selenocentric
#define CA   4	 // Cartesian (Regession Plane on "Mean Body") 
#define TP   3   // Topocentric
#define EQ	 2   // Equatorial
#define GE	 1   // Geocentric
#define HE	 0   // Heliocentric

  // Indices to planets, etc., by 'name mnemonic'
  
#define EAR	 1
#define MOO	 2
#define MER	 3
#define VEN	 4
#define MAR	 5
#define JUP	 6
#define SAT	 7
#define URA	 8
#define NEP	 9
#define PLU 10	 // Pluto's data are not currently available.
#define NOD 10   // Lunar Ascending Node in Ecliptic
#define SUN	11
#define EQN 12   // Equatorial Lunar Ascending Node	(its geoc. long. or RA)
#define PER	13   // Perigee's longitude, or RA.
#define LEQ	14   // Angle between Lunar and Equatorial planes
#define MOT 15   // Generalised Systemic "Motional" Direction
#define PRG 16   // Include Perigee in calculation of systemic direction.  (No, don't!)
#define MBD 17   // Reference to Mean Body
#define MAS 18	 // Reference to Mass Centre
#define FXP 19   // Fixed Point
#define GNR 20	 // body/body directivity ops


int    gotimage = 0 ;	  // whether image loaded

// JPEG save quality.

UINT32 JPGQuality =  64 ; // default


// Measurement Status

#define    EYEBALLED   1
#define      TRACKED   2
#define    PREDICTED   3
#define		 DROPPED   4

// Window rectangle invalidation

BOOL ivrc(HWND hWnd, LPRECT rc, BOOL erase)
{
	return InvalidateRect(hWnd, rc, erase) ;
}

// Window rectangle validation

BOOL  vrc(HWND hWnd, LPRECT rc)
{
	return ValidateRect(hWnd, rc) ;
}

// Geolocation

HANDLE	hGPSCom ; // handle of the GPS serial port

int baudrate = 38400 ;
char port[20] = "COM3" ;
DWORD dwStoredFlags = EV_BREAK | EV_CTS   | EV_DSR | EV_ERR | EV_RING |\
                      EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;
DWORD dwCommEvent = EV_RXCHAR ;
DWORD dwSize = 0 ;
char GPSstring[256] = {'\0'} ;
char GPSlat[30]     = {'\0'} ;
char GPSlong[30]    = {'\0'} ;

// Plotting

		 int xlmar = 40 ;
		 int xrmar = 40 ;
		 int ylmar = 40 ;
		 int yhmar = 65 ;

      double HiGH ;
	  double LoW ;
/**
		 int wd;
		 int Wd;
		 int ht;
		 int big; 
		 int is_al; 
		 int transit; 
		 int first_al_to_show = 0 
**/;

		 double  phi_o;
		 double Vphi_o ;

#define    MAXTRACES  100

 	int oxp[MAXTRACES] ;
	int oyp[MAXTRACES] ;

	// To wait or not to wait to Enable time bound changes

	int  dont_wait = 1 ;

	// To update on every request, or wait for manual enable

	int    GoForIt = 1 ;

	// Viewer Centre - default is the Sun

	int ViewCentre = SUN ;

	int  epdensity = 1 ;
	int oepdensity = 1 ;

	// TIMED WINDOW GRABBING

HGLOBAL hbuff ;
HBITMAP hGrab ;
 UINT32 wGrb ;			// width
 UINT32 hGrb ;			// height
    int TGR = 0 ;
   char *  grabgo[] = {"Go  (F10)","Stop  (F10)"} ;
   char *  filego[] = {"Go  (F11)","Stop  (F11)"} ;

	// GPS GEOLOCATION

   int GPS = 0 ;

	// GENERAL ARCHIVING

// I use statically allocated arrays until I work out
// how to allocate them dynamically at run time!  Some 
// issues here are that static allocation can (a) be exhausted,
// and, (b) before exhaustion, imply unused, wasted memory.


	char * budData[300] ;	// the array of pointers to single lines of ASCII bud data from a JPEG
	 int budDatalines ;		// the current number of such lines

int UseSuite = 0 ;
int OldSuite ;
int LastSuite ;
int SUI = 0 ;
int ACV = 0 ;
int COL = 0 ;

 // Drives and their types found on the system

 int DrvType[10] ;
char Drvname[20] ;
 int numdrv ;
 char * szDrvType[]  = {"Hard Drive", "Network Drive", "RamDisk"} ;

// Quantity limit #defines

#define MAXPFXS	   500	// max number of prefixes
#define MAXPTHS	  1500	// max number of valid paths
#define MAXINST	  8000	// max number of instances 
#define MAXDUPL    500	// max number of paths to same-name items known to an instance
#define MAXSERS    500	// max number of series of items with the same prefix and type
#define MAXITMS   1000	// max number of items on any one path
#define MAXITEM 200000	// max number of items in all the TreeViews taken together
#define MAXASSY     20	// max number of suites per prefix
#define MAXTAIL	   256
#define MAXARCS	   256	// max number of distinct Archives

#define MAXALS    2000  // limit on alignments found

//	EVENT CROSS REFERENCE - DIPS, PEAKS, True and Modified Alignments

#define URDP	0	// untuned  raw dip
#define TRDP	1	//   tuned  raw dip
#define UMDP	2	// untuned mean dip
#define TMDP	3	//   tuned mean dip

#define URPK	4	// untuned  raw peak
#define TRPK	5	//   tuned  raw peak
#define UMPK	6	// untuned mean peak
#define TMPK	7	//   tuned mean peak

#define AL		8	// actual	alignment
#define MAL		9	// modified alignment

/***
char szSearchTitle[MAX_PATH] ;
BROWSEINFO bi ;
bi.hwndOwner = GetSafeHwnd(); 
bi.pidlRoot = NULL; 
bi.pszDisplayName = szTitle; 
bi.lpszTitle = "Select a folder containing the response file"; 
bi.ulFlags = BIF_RETURNONLYFSDIRS; 
bi.lpfn = NULL; 
bi.lParam = 0; 
LPITEMIDLIST pidl = SHBrowseForFolder(&bi); // <--- shell function finding directories
if (pidl!= NULL)
{ 
if (SHGetPathFromIDList(pidl, szTitle)) 
AfxMessageBox(szTitle)
}
***/

// for FindFolders() ;

#define       MAXDEPTH    50
#define MAXDIRSATDEPTH 10000

char * szDirpath[MAXDEPTH][MAXDIRSATDEPTH] ;	// the subdir paths as strings
 static int   iDirsat[MAXDEPTH] ;				// the number of subdirs found at [depth] 
 static int   deepest = 0 ;							// greatest depth reached
 static int   totaldirs ;								// total number of subdirs found

 UINT iImgDirs = 0 ;	// number of dirs with at least one possibly-valid IMG 
 UINT iIniDirs = 0 ;	// number of dirs with at least one possibly-valid INI 
 UINT iDatDirs = 0 ;	// number of dirs with at least one possibly-valid DAT 
 UINT iTrkDirs = 0 ;	// number of dirs with at least one possibly-valid TRK
 
 // indices and depths per possible directory per type

 UINT iImgDirIndex[MAXINST] ;
 UINT iIniDirIndex[MAXINST] ;
 UINT iDatDirIndex[MAXINST] ;
 UINT iTrkDirIndex[MAXINST] ;

 UINT iImgDirDepth[MAXINST] ;
 UINT iIniDirDepth[MAXINST] ;
 UINT iDatDirDepth[MAXINST] ;
 UINT iTrkDirDepth[MAXINST] ;

// for Bud Image previews in the Archivist

HBITMAP hDefault = (HBITMAP)NULL ;
HBITMAP hPreview = (HBITMAP)NULL ;
 UINT32 wPrview ;		// width
 UINT32 hPrview ;		// height

// flags indicating that the current system is being
// or has been searched for valid bud-type items.
 
 int    searched = 0 ;
 int   searching = 0 ;
 int    batching = 0 ;

 int showpreview = 0 ;

 typedef struct tagSUITE
		{
	char desc[100] ; // tail string of suite's paths
	int iIMGpth ; // path ID to IMG
	int iINIpth ; // path ID to INI
	int iDATpth ; // path ID to DAT 
	int iTRKpth ; // path ID to TRK
		} SUITE, * LPSUITE ;

unsigned long budref = 0L ;
unsigned long imgref = 0L ;
unsigned long iniref = 0L ;
unsigned long datref = 0L ;
unsigned long trkref = 0L ;

//	Most Recently Used

char     szMRUearly[ 30] ;	// instance dates
char     szMRUfinal[ 30] ;
char       szMRUpvu[256] ;	// preview image


 // Current

 int   CurrentPfxID ;		// the prefix selected for  Archive work
 int   BudPfxID ;		// the prefix selected for Instance work
 int   OldBudPfxID ;
 int   IsInst ;			// flag that an instance is wanted
 int  LoadImgbyTree = 0 ;	// Suite selection from the tree for image 
 int  LoadSerbyTree = 0 ;	// Suite selection from the tree for series 
 int	  haveimage = 0 ;	// images are/are not available for a selected prefix

// Data-type defs

#define PFX			 1
#define IMG			 2
#define INI			 3
#define TRK			 4
#define DAT			 5
#define PTH			 6
#define IMGPTH		 7
#define INIPTH		 8
#define TRKPTH		 9
#define DATPTH		10
#define SUIT		11
#define ARCH		12

int openpfx[MAXPFXS] ;	// whether an instance of a prefix has been loaded during this session 
int   newpfx = 0 ;		// whether latest loaded is an instance of an entirely new bud (prefix)
int newsuite = 0 ;		// whether a new suite has been created for a suitless image

//***************************************
// struct with details of ANY valid file
//***************************************
/***
typedef struct tagbudfile
	{
		  char szfilename[100] ;	// the valid file name
		  char     prefix[ 50] ;	// the prefix pertaining to the valid file
		  char     szpath[256] ;	// the path string to the valid file 
		double epoch ;				// the epoch of the valid file
		 ULONG  bref ;				// the index of this reference
		  UINT   typ ;				// the type of the valid file (IMG, INI, DAT or TRK)
		  UINT pfxID ;				// the prefix ID
		  UINT typID ;				// the ID corresponding to the type
		  UINT pthID ;				// the path ID

	} BUDFILE, * LPBUDFILE ;

LPBUDFILE Bfiles[MAXITEM] ;
***/
//************************
// per-item ID collection 
//************************
typedef struct tagIDS
		{
	UINT pfxID ;
	UINT imgID ;
	UINT imgpth ;
	UINT iniID ;
	UINT inipth ;
	UINT datID ;
	UINT datpth ;
	UINT trkID ;
	UINT trkpth ;
 LPSUITE pS ;
		} IDS, * LPIDS ;

  IDS  I ;				// Working instance
LPIDS pI = &I ;



typedef struct tagARCHIVE			// 9th November 2005: the working Archive items are now held in a struct
			{						// to facilitate block de-allocation and clearing - possibly block disking too.		
// SUITES

LPSUITE    pSuiteperpfx[MAXPFXS][MAXASSY] ;
    int   iNumsuiperpfx[MAXPFXS] ;
	int	       pthinABR[MAXPTHS] ;				// is the path in the Working ABR?
	
// GLOBAL PATHS 

 int	  iGpthIDs ;
char * szKnownpth[MAXPTHS] ;

 
 // PATHS KNOWN TO ITEMS
 // -- PER ITEM

 int      iNumpthsperimg[MAXINST] ;				// the number of IMG path-IDs known to an IMG
 int		iPthIDperimg[MAXINST][MAXDUPL] ;	// the IMG path ID numbers    known to an IMG

 int	  iNumpthsperini[MAXINST] ;				// the number of INI path-IDs known to an INI
 int		iPthIDperini[MAXINST][MAXDUPL] ;	// the INI path ID numbers    known to an INI

 int	  iNumpthspertrk[MAXINST] ;				// the number of TRK path-IDs known to a  TRK
 int		iPthIDpertrk[MAXINST][MAXDUPL] ;	// the TRK path ID numbers    known to a  TRK

 int	  iNumpthsperdat[MAXINST] ;				// the number of DAT path-IDs known to a  DAT
 int		iPthIDperdat[MAXINST][MAXDUPL] ;	// the DAT path ID numbers    known to a  DAT

// -- ITEMISED PATHS/SERIES PER PFX 

 int   iNumimgpthsperpfx[MAXPFXS] ;				// the number of paths-to-IMG known to a PFX ID
 int       iImgpthperpfx[MAXPFXS][MAXDUPL] ;	// the path-to-IMG IDs        known to a PFX ID 

 int   iNuminipthsperpfx[MAXPFXS] ;				// the number of paths-to-INI known to a PFX ID
 int       iInipthperpfx[MAXPFXS][MAXDUPL] ;	// the path-to-INI IDs        known to a PFX ID 

 int   iNumdatpthsperpfx[MAXPFXS] ;				// the number of paths-to-DAT known to a PFX ID
 int       iDatpthperpfx[MAXPFXS][MAXDUPL] ;	// the path-to-DAT IDs        known to a PFX ID

 int   iNumtrkpthsperpfx[MAXPFXS] ;				// the number of paths-to-TRK known to a PFX ID
 int       iTrkpthperpfx[MAXPFXS][MAXDUPL] ;	// the path-to-TRK IDs        known to a PFX ID

// ITEMS KNOWN TO PATHS

 int		   iNumfiles[MAXPTHS] ;				// the number of files (items) on the path
 int		     iFileID[MAXPTHS][MAXITMS] ;	// the ID numbers of items per path
 int		    iFiletyp[MAXPTHS][MAXITMS] ;	// the types of items per path

// IMG (INSTANCE)

 int       iImgIDs ;						// total number of unique instances
 int        iImgPfxID[MAXINST] ;			// the iImgID'th prefix ID number
char	 * szKnownimg[MAXINST] ;			// the instance-strings indexed by iImgID
 
double    fKnownimgEp[MAXINST] ;			// the iImgID'th instance epoch as double
char	  * szImgdate[MAXINST] ;			// the datetime-strings indexed by iImgID

// INI

 int	  iIniIDs ;							// total number of uniquely named instance INIs
 int        iIniPfxID[MAXINST] ;			// prefix ID corresponding to this INI ID
char	 * szKnownini[MAXINST] ;			// the instance INI strings indexed by iIniID

// TRK

 int      iTrkIDs ;							// total number of uniquely named instance TRKs
 int        iTrkPfxID[MAXINST] ;			// prefix ID corresponding to this TRK ID
char     * szKnowntrk[MAXINST] ;			// the instance TRK strings indexed by iTrkID

// DAT

 int      iDatIDs ;							// total number of uniquely named instance DATs
 int        iDatPfxID[MAXINST] ;			// prefix ID corresponding to this DAT ID
char     * szKnowndat[MAXINST] ;			// the instance DAT strings indexed by iDatID

// TAILS

 int       iTails ;							// there should be at least as many tails as prefixes
 char	 * szKnowntail[MAXTAIL] ;			// and probably several more

 LPSUITE  Suitepertail[MAXTAIL] ;
 LPSUITE  SelSuite ;

// ARCHIVES

 int       iArcs ;
char	 * szKnownArc[MAXARCS] ;

// PER PREFIX

 int	   iPfxIDs ;							// total number of global unique prefixes
char     * szKnownpfx[MAXPFXS] ;				// the prefix-strings indexed by iPfxID

 int	iNumImgperpfx[MAXPFXS] ;				// the number of IMG IDs  known to a prefix
 int        Imgperpfx[MAXPFXS][MAXDUPL] ;		// the IMG ID numbers  known to a prefix

 int	iNumIniperpfx[MAXPFXS] ;				// the number of INI IDs  known to a prefix
 int        Iniperpfx[MAXPFXS][MAXDUPL] ;		// the INI ID numbers  known to a prefix

 int	iNumDatperpfx[MAXPFXS] ;				// the number of DAT IDs  known to a prefix
 int        Datperpfx[MAXPFXS][MAXDUPL] ;		// the DAT ID numbers  known to a prefix

 int	iNumTrkperpfx[MAXPFXS] ;				// the number of TRK IDs  known to a prefix
 int        Trkperpfx[MAXPFXS][MAXDUPL] ;		// the TRK ID numbers  known to a prefix

// PER INSTANCE (PER IMG)

 int    iNuminiperimg[MAXINST] ;			// number of global INI IDs per instance
 int       iIniperimg[MAXINST][MAXDUPL] ;	// the global INI IDs of instances

 int    iNumdatperimg[MAXINST] ;			// number of global DAT IDs per instance
 int       iDatperimg[MAXINST][MAXDUPL] ;	// the global DAT IDs of instances

 int    iNumtrkperimg[MAXINST] ;			// number of global TRK IDs per instance
 int       iTrkperimg[MAXINST][MAXDUPL] ;	// the global TRK IDs of instances

// EPOCHS

double       fLaterEp[MAXPFXS] ;			// the latest   instance epoch known to a prefix 
double       fEarlyEp[MAXPFXS] ;			// the earliest instance epoch known to a prefix
double		fEpperpfx[MAXPFXS][MAXDUPL] ;	// all instance epochs         known to a prefix

int			iInstYear[MAXINST] ;
int		   iInstMonth[MAXINST] ;
int			 iInstDay[MAXINST] ;
int			iInstHour[MAXINST] ;
int		  iInstMinute[MAXINST] ;
int		  iInstSecond[MAXINST] ;

		} ARCHIVE, * LPARCHIVE ;

ARCHIVE A ;
LPARCHIVE pA = &A ;

// Data and Grand Periods

   int samples ;	// number of samples taken from the current bud time-series
double BudGP ;		// grand period of the current bud series
double BudEp1 ;		// first instance epoch of the current bud series
double BudEp2 ;		// final instance epoch of the current bud series
double AstGP ;		// grand astronomical period currently in use
double AstEp1 ;		// first epoch of the astronomical period currently in use
double AstEp2 ;		// final epoch of the astronomical period currently in use
double ep1983 ;		// datum epoch for observed phase shift

double  ashift = 5.0 ;	// default angular correction
double latiply = 1.0 ;	// latitude amplitude factor 

// Chart quantities

int timecase ;
int using_seconds, using_minutes, using_hours ;

#define tSECOND 0	// plotting: time-interval cases
#define tMINUTE 1
#define tHOUR   2
#define tDAY    3
#define tWEEK   4
#define tMONTH  5
#define tYEAR   6


double tchart, lochart,  hichart ;		// epoch-span, start-epoch and end-epoch of chart
double vchart, lovchart, hivchart ;		// value-span, lowest value and highest value of chart
double stu ;							// smallest time-unit for plotting  

int chartwid, lftmargin, rytmargin ;	// pixel chart width, and left and right chart margins
int charthyt, botmargin,  topmargin ;	// pixel chart height, and bottom and top margins

double sitd ;		// seconds in tick division
double simd ;		// seconds in minor division
double siMd ;		// seconds in major division

// x chart pixel position from epoch
int ep2xp(double epoch) 
{
	return ((int)((double)chartwid * (epoch - lochart) / tchart) + lftmargin) ;
}

// epoch from chart x pixel position
double xp2ep(int x) 
{
	return (tchart * (double)(x - lftmargin) / (double)chartwid + lochart) ;
}

// Raster: amount of lead or lag
// imposed on the dips and peaks.

double leadlag = 0.0 ;

//Bitmap Control-Button Indexes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//in control window
#define Opf 0   //  Open file control
#define Col 1   //    Collate control
#define Voc 2   // Sound bite control
#define Cmt 3	// Commentary control
#define Acq 4	//    Acquire control
#define Cap 5   //    Capture control
#define Tgr 6	// Timed Grab control
#define Gps 7	//        GPS control 
#define Sla 8   //  Select Archive control
#define Xit 9   //       Exit control

//in Bud Window.
#define Lop 10   // Set lo pole toggle control
#define Hip 11	 // Set hi pole toggle control
#define Lsc 12	 // Measurement scan toggle control
#define Gra 13	 // Line-scan Graphs toggle control
#define Lev 14	 // Set number of measure heights toggle control
#define Gry 15	 // GrayScale/Colour toggle control
#define Ca1 16	 // Calibrate on point 1 control
#define Ca2 17	 // Calibrate on point 2 control
#define Rez 18   // Resize image control

//in Scan window
#define Lum 19  // Luminosity and Diff.Lum. graph display selection 
#define Hue 20  // Hue and Saturation graph display selection
#define Cwh 21	// toggle Cartesian/Colour Wheel hue&sat display
#define Smu 22  // Increase Smoothing level control
#define Smd 23  // Decrease Smoothing level control


//in Results window
#define Prj 24	// Projective/Regression result toggle
#define Dia 25	// Lambda on diameters
#define Lef 26	// Lambda on left radii 
#define Ryt 27	// Lambda on right radii
#define Npr 28  // Null Profile toggle
#define Dtl 29	// Details dialog

//in Acquire window
#define Oex 30	// Open existing image
#define Grb 31	// Acquire (grab) image
#define Sac 32	// Save current image
#define Use 33	// Use image in Workshop
#define Prn 34  // Print now button
#define Lay 35  // Print preview button
#define Pmx 36	// Move/rename images 
#define Rot 37	// Rotate image
#define Slr 38  // Select rectangle
#define Crp 39  // Crop to rectangle
#define Rsz 40  // Resize image
#define Brc 41	// Brightness/Contrast on/off
#define Tst 42  // Make Test Image.

// More in Bud Window

#define Aut 43  // Auto Tracking control
#define Alf 44	// Track Left profile
#define Art 45	// Track Right profile
#define Acp 46  // Accept track
#define Prm 47  // Tracking parameters (smoothing, seek span, threshold, etc)

// Extras for window-type controls

#define Itm 56  // Select Items for Collation
#define Lst 57	// List selected Items 
#define Ast 58	// Astronomical operations
#define Acv 59	// Archivist
#define Fou 60	// Fourier Operations
#define Fos 61  // Fourier SetUp Dialogue box
#define Prv 62	// Previous image in sequence
#define Nxt 63	// Next image in sequence
#define Svi 64	// Save all away now button

#define Scc 65  // Line Scan colour selection button
#define Lsa 66  // Line scan on all colours
#define Lsr 67  // Line scan on red
#define Lsg 68  // Line scan on green
#define Lsb 69  // Line scan on blue

#define Pck 70  // Special for "mouse trace".

// 10 buttons for the bud window

#define Btn80 80
#define Btn81 81
#define Btn82 82
#define Btn83 83
#define Btn84 84
#define Btn85 85
#define Btn86 86
#define Btn87 87
#define Btn88 88
#define Btn89 89

// Names of Topocentric Origins (i.e., Places!)

#define ABERDEEN     0
#define STRONTIAN    1
#define KINGSLANGLEY 2
#define SYDNEY       3
#define TERRAFLORA   4
#define LOCATION     5

// Toolbar

#define NUM_BUTTONS        5
#define NUM_BUTTON_BITMAPS 5
#define IDM_TB1  10  
#define IDM_TB2  11  
#define IDM_TB3  12  
#define IDM_TB4  13  
#define IDM_TB5  14  
   HWND hWndTB ;

//        re Cells
// Sides, indexed clockwise from top
#define         Top    0
#define       Right    1
#define      Bottom    2
#define        Left    3
// Corners, no special order
#define         TLc    0	  // top left
#define         TRc    1	  // top right
#define         BLc    2	  // bottom left
#define         BRc    3	  // bottom right
// Indices given to cells on boundaries
LONG Tbnd = -1L ;			  // Top
LONG Lbnd = -2L ;			  // Left
LONG Rbnd = -3L ;			  // Right
LONG Bbnd = -4L ;			  // Bottom

/*******************************************/

HINSTANCE hInst ;

/*******************************************/

 double polarst = 180.0 ;	// number of angular steps in polar diagram ;

	int TPOrg = ABERDEEN ;


// Enumeration of "known" windows
 int NumKnown = 0 ;

// Window handles

HWND hWndKnown[30] ; // List of handles of "Known" Windows

HWND hWndDesk ;	 // the Desktop

HWND hWndBud ;   // for the bud image
HWND hWndCtrl ;  // the main control window
HWND hWndScan ;	 // for the line scan graphs
HWND hWndFlag ;	 // for the sign-on banner.
HWND hWndRslt ;  // for the results
HWND hWndColl ;  // for data-collation operations
HWND hWndAcq  ;  // for TWAIN image-acquisition
HWND hWndNPGraf ;// for Null Profile graphing
HWND hWndArch  ; // for Fourier operations.
HWND hWndAgr  ;  // for Agraphing
HWND hWndTune ;	 // for the Selectivity Curve
HWND hWndView ;  // for Viewer
HWND hWndRast ;  // for PG Alignment Raster
HWND hWndLists ; // for Listings

HWND hWndPvw ;	 // for Previewing in the Archivist
HWND hWndGrb ;	 // for Displaying Grabs
HWND hWndLayout ;// for Print Preview
HWND hWndCap ;   // for Capture from Webcam using VFW

HWND   BriConDlg ;
HWND   TkParmDlg ;
HWND      SigDlg ;
HWND    hWndZoom ;
HWND    hFly[25] ;

// Capture of a window as bitmap

HWND hWndNow ;	 
 int      CAP = 0 ;
 int  capture = 0 ;
 int captured = 0 ;

 int    wuzin = 0 ;

// Line cursor hide state

 int lcursorhide = 0 ; 

//Fonts

   HFONT hfnt, hfnt1, hfnt2, hfnt4, hfntOld ;
   HFONT hgrk, hgrk1, hgrk2, hgrk4 ;
 LOGFONT lf ;
    char  Face[] = "Tahoma" ;
	char Greek[] = "Symbol" ;

//Pens 

 HPEN bluePen,   blueWPen,   plbluePen,  ltbluePen,   dkbluePen,  whitePen ;
 HPEN greenPen,  greenWPen,  ltgreenPen, dkgreenPen,  dkgndotPen, cyanPen, cyanWPen ;
 HPEN redPen,    redWPen,    reddotPen,  ltredPen,    dkredPen,   redWPen ;
 HPEN yellowPen, yellowWPen, dkgoldPen,  goldPen,     notgoldPen, orangePen ;
 HPEN blackPen,  blkdotPen,  blackWPen,   purplePen,  purpleWPen ;
 HPEN palePen,   grayPen,    dkgrayPen,   mdgrayPen, dkgrydotPen ;

 // Complementary Pens

 HPEN cbluePen,     cltbluePen, cplbluePen, cdkbluePen, credPen,     cdkredPen ;
 HPEN cltredPen,    cpurplePen, ccyanPen,   cwhitePen,  cgreenPen, cdkgreenPen ;
 HPEN cltgreenPen,  cblackPen,  cyellowPen, cdkgoldPen, notgoldPen,   cgrayPen ;
 HPEN cdkgrayPen,   cpalePen ;

// Menu

HMENU hmenu ;

// Growth Measure distribution of measurement heights

   int GrowthMeasure = 0 ; // Distribute Measurement Heights by Growth Measure
   int  UsingDefault = 1 ; // for first time use
   int   ModeChanged = 0 ; // mode has toggled
   int   FracChanged = 0 ; // first fraction has changed

double FirstFrac ;	       // fraction of IPD between the half-up height
                           // and the first height up from it.

double fHyts[MAXLEVELS] ;  // fractional growth-measure heights
double growth ;			   // the growth-measure coefficient
    

HBITMAP hFlag ;			   // handle of sign-on banner bitmap: the FIRST TIMER will kill this

HBITMAP hAbout ;		   // <--- NEW: handle of About bitmap : the SECOND Timer will kill this    

// Current line-scan colour selection

int scancolour = 0 ;	 // Selection of scanned colour component.
                         // 0-all, 1-red, 2-green, 3-blue. 

// Fourier and Astron complain if these are not here
double itan( double num,  double den) ;
double twopi ;	
double  adiff( double newa, double olda) ; // returns -pi < a < pi
double adiff2( double newa, double olda) ; // returns   0 < a < twopi
double arccos( double x ) ;


// Archive Control Panel window

HWND hPanelDlg = (HWND)NULL ;
RECT rcArc ;			// Client rectangle.

//  Rasterised Dip/Peak Dialog

HWND hRastDlg = (HWND)NULL ;

//	Archive Selection Dialog

HWND hPickArcDlg ;
char szUsingArchive[256] ;

// Flyer routine needs these global
 int horpix ;			
 int verpix ;

// Progress controls

HWND	 hWndPB1 ;	   // Progress Bar in Archive Control Panel
HWND	 hWndPB2 ;	   // Progress Bar in Archivist Dialogue Box
HWND	 hWndPB3 ;	   // Progress Bar in Archivist Dialogue Box
HWND   hWndFetch ;	   // Static control indicating what is being fetched

// Build

HWND      hBuild ;	   // Build-Button in Archive Control Panel

int   allowbuild = 0 ;

// Tabbed Control Panel and corresponding child dialogue handles

HWND     hWndTab ;     // Tab Control in Archive Control Panel
RECT       rcTab ;	   // Tab Control Window Rectangle
RECT rcTabDisplay ;	   // Display Area of Tab Control

// child dialogue handles

HWND     hDlgSource ;		// Get Lambda Series and Dates Dialogue
HWND     hDlgDisplay ;		// Display selection Dialogue
HWND     hDlgEpochs ;		// Display/Set Epochs Dialogue
HWND     hDlgFourier ;		// Fourier settings Dialogue
HWND     hDlgSystemic ;		// Systemic settings Dialogue
HWND     hDlgSystemicII ;   // Systemic settings Extra
HWND     hDlgTuned ;		// Tuned Filter Dialogue
HWND	 hDlgField ;		// Directional Field Dialogue
HWND     hDlgMisc ;			// Miscellaneous items Dialogue
HWND     hDlgSpectra ;		// Spectra Dialogue
HWND     hDlgViewSet ;		// Viewer Settings Dialogue
HWND	 hDlgSelectBody ;	// Selection into Body Lists 
HWND     hDlgBudProfile ;	// Bud Profile Operations Dialogue

HWND	 hArcDlg ;			// Archivist Dialog Box handle

HWND	 hDlgStats ;		// Statistics Dialog Box handle

HWND	 hDlgGPS ;			// Geolocation by GPS

HWND     hDlgGrabSetUp ;	// Grab sequence settings Dialogue
HWND     hWndTarget = (HWND)NULL ;		// Grab target window
HWND	 hDlgCaptDriver ;
HWND	 hDlgCaptDriver_List ;

CAPDRIVERCAPS CapDrvCaps ;

double mouseEp ;			// the ep of the mouse x position in the time chart

int     Levels = 7 ;		// Default number of measure heights.

// Null-level bud measures

double Ho[MAXLEVELS] ; // fractional height
double Xo[MAXLEVELS] ; // Null-level x at fract. height.
double Yo[MAXLEVELS] ; // Null-level y at fract. height.
double iL[MAXLEVELS] ; // Ratio of changes ("interval" lambda)
double loiL, hiiL ;	   // Least and largest interval lambdas
double loXo, hiXo ;	   // Least and largest Null value changes
double loYo, hiYo ;
	
// Appulse angle (actual angle between moon and body, vertex in Earth)

double appulse ;

// Recall most recent image on start up

int RecallMRI = 0 ;

// Prediction Model

int PredictionModel = 1 ;

// All Alignments found

int AllAlsDone = 0 ;

// Image dimensions.

	int		  dibwid ;
	int		  dibhyt ;

// Used by "mouse trace", and by various other things.
// ***************************************************

   int   iYear[MAXBUDS] ;
   int  iMonth[MAXBUDS] ;
   int    iDay[MAXBUDS] ;
   int   iHour[MAXBUDS] ;
   int iMinute[MAXBUDS] ;
   int iSecond[MAXBUDS] ;
   int  IsPlotTime = 0 ; // Plotting something versus Time
   int IsPlotOrder = 0 ; // Plotting something versus Fourier order
   int xmouse ;
   int ymouse ;
double clickedEp, MousedEp ;
double curOrder ;
double curDays ;
double curEp ;
double curFrq ;

// For Test Bud Image creation.
// ****************************

double   TLambda = 2.0,    TWidth = 0.25, TLength = 1.0 ;
double TImgNoise = 0.0, TImgGrain = 1.0 ;
double TPrfNoise = 0.0, TPrfGrain = 1.0 ;

   int filltestbud = 1 ;
   int outltestbud = 0 ;

COLORREF OutlineColour = RGB(  0,  0,255) ; // blue
COLORREF FillColour    = RGB(  0, 64,  0) ; // dark green
COLORREF BackColour    = RGB(255,255,255) ; // white

// Current pixel dimensions of image in "Imagery" window.

unsigned long w_now, h_now ;

//****** Image Rotation ******

// Stepped Rotation Angles

#define R90  0
#define R180 1
#define R270 2

// Free Rotation Angle

#define RFREE 3

// Rotation defaults

int rot_degrees = R90 ;

double FreeRotation = 0.0 ;

// ****** Image Resizing ******

#define S1024 0
#define S640  1
#define S320  2
#define S160  3
#define SCUST 4

// Resize default

int rsz_size  = S640 ;

// Preserve aspect ratio default

int keep_aspect = 1 ;

// New dimensions

unsigned long rsz_x ;
unsigned long rsz_y ;

// mouse client co-ordinates in measurement window

int Xms, Yms ;
int LEV[MAXLEVELS] ; 

// image pixel widths and heights

int bimwid, bimhyt ;   // in bud measurement window
int rimwid, rimhyt ;   // in results window
int pimwid, pimhyt ;   // in preview window


int    collating = 0 ;
int  recupdating = 0 ;
int    fourierop = 0 ;
int    dolisting = 0 ;
int datagraphing = 0 ;
int    astronomy = 0 ;

// result window display state flags

int showImage    =  1 ;
int showGrid     =  1 ;
int showAnnot    =  1 ; 
int showTrack    =  1 ;
int matchbend    =  1 ;

// Whether archivable material is available

int toArchive = 0 ;

// autotracking and automeasurement

int this_hs ;

// Edges done and Level inclusion

int     EdgeDone[MAXLEVELS + 2] ; // record of completed profile measurements
int   IncludeLev[MAXLEVELS + 2] ; // whether level included in lambda reckoning

int   zoompatch = 1 ;
 
int seekspan     =  8 ;
int SelfTrkRate  =  2 ;
int jumpsize     =  4 ;
int jumpmouse    =  1 ;

int autotrack    =  0 ;
int autodolft    =  0 ;
int autolftdone  =  0 ;
int autodoryt    =  0 ;
int autorytdone  =  0 ;
int autotracked  =  0 ;
int         AUT  =  0 ;
int         ALF  =  0 ;
int         ART  =  0 ;

// In RGB buffer

typedef struct tagTRKINFO
			{
   int   hyt ;
   int   wid ;
   int * Beplft ;
   int * Bepryt ;
   int * Blftcapt ;
   int * Brytcapt ;
   int   Blcapt ;
   int   Brcapt ;
   int   Blftloidx ;
   int   Brytloidx ;
   int   Blfthiidx ;
   int   Brythiidx ;
			} TRKINFO, * LPTRKINFO ;

TRKINFO Tk ;
TRKINFO tk ;

TVHITTESTINFO tvht1, tvht2, tvht3 ;

 int ExclPers = 0 ;

// Cut high-period, VLF components from bud-series synthesis (greater than 1 month by default)

 int FilterHP = 0 ;
 double HiPer = 31.0 ;	// days
 
// Cut low-period, VHF components from bud-series synthesis (less than 7.0 days by default)

 int FilterLP = 0 ;
 double LoPer = 7.0 ;	// days

// Exact semi-lunar period

 double Semi_lun = 13.777275 ; // days
 double sIAP ;

// Standard Bud. Currently unused, but may be one day.
/*
HGLOBAL hlperim  = NULL ;
double * lperim ;
HGLOBAL hrperim  = NULL ;
double * rperim ;
double lperimeter ;
double rperimeter ;
HGLOBAL hlslope  = NULL ;
double * lslope ;
HGLOBAL hrslope  = NULL ;
double * rslope ;
HGLOBAL hlicept  = NULL ;
double * licept ;
HGLOBAL hricept  = NULL ;
double * ricept ;
*/

HWND TDlg ;	 // Tuning dialog box handle
HWND CDlg ;  // Tabbed Control Panel dialog box handle 

BYTE * pnewbuf ;
BYTE * pCpybuf ;
BYTE * pTemp ;
BYTE * pTempo ;
BYTE * pTmp ;

// ****** Printing ***********

     int layout ;

  double winch  = 4.0 ;	  // default inch width of printed image
  double hinch ;		  // inch height calculated from image aspect ratio
  double xoinch = 0.5 ;   // default inch printed offsets to TLC of image
  double yoinch = 0.5 ;
  double xrinch ;		  // right and bottom inch margins
  double ybinch ;
  double realpaperwid = 210.0 / 25.4 ;// A4 paper width in inches
  double realpaperhyt = 297.0 / 25.4 ;// A4 paper height in inches
  double physwidth ;
  double physheight ;
  double physoffsetx ;
  double physoffsety ;
     int WPels,  HPels ;
	 int xLeft,  yTop ;
	 int pwid,   phyt ;
	 int Previewed = 0 ;
	 HDC hPrnDC ;
 HBITMAP hPrn, oPrn ;
PRINTDLG pd ;
 DOCINFO di ;

// ***** Search and Collation ******

 // In next two, negative value means no first or final record exists
double JEpOfMissing[MAXBUDS] ; // Julian epochs of missing instances

 // Allow Option of over-ride of old Fourier Order-Limits on loading new bud

int PermitOverRideOnNew = 0 ;  // default : Disallow over-ride
int        PrefixChange = 0 ;  // Prefix has been changed
int          HavePrefix = 0 ;  // We have a Prefix

//	Basic selections have changed
 
int			BodyChanged = 0 ;	//  Body selection has changed
int        FrameChanged = 0 ;	// Frame selection has changed

// Per-line inclusions...

int    OrderInSet = 0 ;	   // Include set-order number
int    DayOfMonth = 1 ;	   // Include the day of the month
int      UseBudID = 1 ;	   // Include the full ID per instance
int      WantFile = 1 ;	   // Indicates if to save szBudItems[] to disk
int       AskName = 1 ;	   // Whether to auto-name, or ask name for file.

// Include-item bit-patterns for bit-wise OR'ing into search pattern

// lambda style
UINT PLAM = 0x0001 ;  // want projective lambdas
UINT RLAM = 0x0002 ;  // want regression lambdas
// lambda source
UINT LDIA = 0x0004 ;  // want lambdas on diameters 
UINT LRYT = 0x0008 ;  // want lambdas on right radii
UINT LLFT = 0x0010 ;  // want lambdas on left radii
// quality of fit
UINT MRDS = 0x0020 ;  // want MRDs
UINT MLDS = 0x0040 ;  // want MLDs
// dimensions
UINT DDIA = 0x0080 ;  // want diameters
UINT DRYT = 0x0100 ;  // want right radii
UINT DLFT = 0x0200 ;  // want left radii
UINT IPDS = 0x0400 ;  // want IPDs
UINT CMPO = 0x0800 ;  // want composite	bud
// standard deviations
UINT RSTD = 0x1000 ;  // want mov. std. dev. on raw lambda data
UINT MSTD = 0x2000 ;  // want mov. std. dev. on mov. mean lambda data

UINT SRCH = 0x0425 ;  // Default 16 bit search pattern

double RStDev ;          // moving standard deviation on raw  lambdas
double MStDev ;          // moving standard deviation on mean lambdas
   int MeanSpan =  3 ;
   int	  msgbox = 0 ;	 // hide the line cursors if message box

// Origins of measurements

   int NoOrgData = 0 ;
   int  LEdgeOrg[MAXLEVELS + 2] ; // origin of measure per left  edge
   int  REdgeOrg[MAXLEVELS + 2] ; // origin of measure per right edge

// Fourier and Other Analysis stuff

typedef struct tagSTATE
{
	int      Set[15] ;
	int    AllEpSet ;
	int      Ep1Set ;
	int      Ep2Set ;
	int  TimeSeries ;  // is/is not Time series
 double      weeIAP ;  // Least IAP
 double      bigIAP ;  // Largest IAP
 double        pord ;  // Fourier order corresponding to mean IAP
 double   ordforwee ;  // order for   least IAP
 double   ordforbig ;  // order for largest IAP
 double    ordrange ;  // order range

 double      BTopOrd ;  //    top bud series order used
 double      BBotOrd ;  // bottom bud series order used
 double     BOrdStep ;  //		  bud series order step

 double     ATopOrd ;  //    top astron series order used
 double     ABotOrd ;  // bottom astron series order used
 double    AOrdStep ;  //		 astron series order step

 double    rx_t[100] ; // positions of  raw component minima
 double    mx_t[100] ; // positions of mean component minima
 double  rt2min[100] ; // times to  raw minima from start of grand period
 double  mt2min[100] ; // times to mean minima from start of grand period
 double	    rdt[100] ; // times of  raw minima to following alignments
 double	    mdt[100] ; // times of mean minima to following alignments
 double       rshift ; // mean  raw shift interval
 double       mshift ; // mean mean shift interval
                      } STATE, * LPSTATE ;

STATE st ;

typedef struct tagEXISTS
{
	int BodyDirsExist ;// We have a set of body directions
	int   DataExist ;  // Lambda Data exist
	int  MeansExist ;  // Running Mean Lambda Data exist

	int AlignsExist ;		// Alignments exist for current body
	int modAlignsExist ;	// Modified Alignments exist for current body
	int AllAlsExist ;		// Alignment list for all bodies exists
	int AlDataExist ;		// All Alignment Data complete

	int AvelsExist ;
	int CsqRateExists ;

	int LamSpExists ;  // Spectrum of Raw Lambda exists
	int mLamSpExists  ;// Spectrum of Running Mean Lambda exists
	int LamSnExists   ;// Synthesis of Raw Lambdas exists
	int mLamSnExists  ;// Synthesis of Running Mean Lambdas exists
	int LamFSnExists  ;// Forced Synthesis of Raw Lambdas exists
	int mLamFSnExists ;// Forced Synthesis of Running Mean Lambdas exists

	int        RawDipsExist ;
	int       MeanDipsExist ;
	int   RawTunedDipsExist ;
	int  MeanTunedDipsExist ;	// Various Synthesised-Lambda Dip or Peak series exist
	int       RawPeaksExist ;
	int      MeanPeaksExist ;
	int  RawTunedPeaksExist ;
	int MeanTunedPeaksExist ;

	int  SynAgrExists ;		// Synthesis exists for building Synthetic Agraph on Raw  Lambda
	int mSynAgrExists ;		// Synthesis exists for building Synthetic Agraph on Mean Lambda

	int ALNSpExists ;  // Spectrum of Alignment Data exists
	int IMPSpExists ;  // Spectrum of Implied Periods exists
	int   ImpsExist ;  // Implied periods exist
	int PhasesExist ;  // observed phase shifts are available
	int rAgraphExists ;// Direct raw Agraph exists
	int mAgraphExists ;// Direct running mean Agraph exists

} EXISTS, * LPEXISTS ;

EXISTS _is ; 

double    resorder =  13.5 ;
double resorderbud =  13.5 ;
double  dfltresord =  13.5 ;
double selectivity = 100.0 ;
double        gain =  25.0 ;
double   bandwidth =   0.0 ;
double   hi_dB_ord =   0.0 ;
double   lo_dB_ord =   0.0 ;

double       specT =  28.0 ;  // default specified implied period ;
long        vcount =    1L ;  // current count of VELS usage

int    DoDirectMeasure = 0 ;  // Make a list of the XY co-ordinates of Image points (----TO DO----)

 
int     wantMovingMean = 0 ;
int          wanttImps = 0 ;
int            wantDMB = 0 ;	// Direction of Mean Body
int			 wantAlnSp = 1 ;	// Spectrum of Alignment
int            wantSDM = 0 ;	// Spectrum of Direction of Mean Body
int             wantVs = 0 ;	// Angular Velocities
int          wantBumps = 0 ;	// Dips or Peaks in Synthesised Lambda
int			wantSynAgr = 0 ;	// Synthetic Agraph
int         wantOneDay = 0 ;	// Doing day-at-a-time synthesis for Synthetic Agraph
int		   wantModanom = 0 ;	// Use modified Lunar Anomaly
int			wantPredSh = 0 ;	// want Predicted Phase Shift
int     wantHeliocMots = 0 ;    // want heliocentric systemic motion
int		    wantShifts = 0 ;	// want bisectoid shifts due to bodies

int    wantAlIconLinks = 0 ;	// lines linking alignment icons on the chart
int wantModAlIconLinks = 0 ;	// lines linking modified alignment icons on the chart
int      wantLunAxials = 0 ;	// lines on-chart indicating lunar axial epochs

int			 wantNotch = 0 ;	// Tuner: invert selectivity curve

int			 viewcount = 0 ;	// Viewer: Usage flag
int         wantBodies = 0 ;	// Viewer: See Bodies
int             wantMB = 0 ;	// Viewer: See Mean Body
int     wantMassCentre = 0 ;	// Viewer: See Centre of Mass
int       wantBackdrop = 0 ;	// Viewer: Black Background
int wantInterbodyLines = 0 ;	// Viewer: Inter-body Linking Lines
int  wantMeanbodyLines = 0 ;	// Viewer: Lines from Mean Body to Bodies
int       wantCoMLines = 0 ;	// Viewer: Lines from Mass Centre to Bodies
int   wantInterbodyTPs = 0 ;	// Viewer: Turning points of Inter-Body lines
int		 wantRstraight = 0 ;	// Viewer: Include inverse of Radius
int  wantHeliocDirofMB = 0 ;	// Viewer: Heliocentric direction of the Mean body
int     wantExtSunToMB = 0 ;	// Viewer: Extended line of Sun to Mean body
int    wantGeocDirofMB = 0 ;	// Viewer: Geocentric direction of the Mean body
int   wantHeliocDirofMass = 0 ;	// Viewer: Heliocentric direction of the Mass Centre
int     wantGeocDirofMass = 0 ;	// Viewer: Geocentric direction of the Mass Centre
int   wantSystemicPrimary = 0 ;	// Viewer: Systemic Primary

int         wantMBvelVect = 0 ;	// Viewer: Velocity Vector of Mean Body
int        wantMBvelEndPt = 0 ;	// Viewer: End Point of Velocity Vector of Mean Body
int         wantMBaccVect = 0 ;	// Viewer: Acceleration Vector of Mean Body
int        wantMBaccEndPt = 0 ;	// Viewer: End Point of Acceleration Vector of Mean Body

int        wantCoMvelVect = 0 ;	// Viewer: Velocity Vector of Centre of Mass
int		   wantExtVelVect = 0 ;	// Viewer: Extend Velocity Vector of Centre of Mass
int       wantCoMvelEndPt = 0 ;	// Viewer: End Point of Velocity Vector of Centre of Mass
int        wantCoMaccVect = 0 ;	// Viewer: Acceleration Vector of Centre of Mass
int	  wantCoMaccVectinSun = 0 ;
int        wantExtAccVect = 0 ;	// Viewer: Extend Acceleration Vector of Centre of Mass
int     wantExtAccVectSun = 0 ;	// Viewer: Extend Acceleration Vector in Sun
int       wantCoMaccEndPt = 0 ;	// Viewer: End Point of Acceleration Vector of Centre of Mass

int     wantGenSysDironMB = 0 ;	// Viewer: General Systemic Direction referred to Mean Body
int  wantSysDironMBbyMass = 0 ;	// Viewer: Systemic Mass Direction on the Mean Body
int   wantMassLineCrosses = 0 ;	// Viewer: Intersections of Mass directions

int			 wantCJBodyMB = 0 ;	// Viewer: Conjugate Body on Mean body direction
int			 wantCJBodyTP = 0 ;	// Viewer: Conjugate Body on Mass direction TP

int		  wantTPbyMass = 1 ;	// Viewer: Turning points by Mass
int		  wantTPbyPos  = 0 ;	// Viewer: Turning points by Position

int		 wantDateClick = 0 ;	// Viewer: Enable Date Clicking
int		  wantMousedEp = 0 ;	// Viewer: Enable Date selection by mouse move
int      OpsViewEnable = 0 ;	// Viewer: Enable operations to be viewed

int			 wantIcons = 0 ;	// Raster:          body icons on the Raster display
int			 wantJoins = 0 ;	// Raster: joins of body icons on the Raster display
int    wantAxialLabels = 0 ;	// Raster: Annotate Axial Epochs
int      wantDayLabels = 0 ;	// Raster: Annotate Day ticks
int       wantPDPopups = 0 ;	// Raster:'Hover Pop up' Annotate Dip/Peak Epochs, etc
int       wantAlPopups = 0 ;	// Raster:'Hover Pop up' Annotate Alignment Epochs
int           wantXref = 0 ;	// Raster:'Hover Pop up' Cross Reference Chart/Raster Dip/Peaks
int        wantAlsXref = 0 ;	// Raster:'Hover Pop up' Cross Reference Chart/Raster Alignments 

int		 wantDemod = 0 ;	   // demodulate (find modulation envelope) TO DO!!
double			  moda ;

int       FouSetUp = 0 ;	   // Show Fourier dialogue
int      DataReady = 0 ;	   // When set, allow Operations

int  PowerSpectrum = 0 ;	   // Plot the Power Spectrum
int mPowerSpectrum = 0 ;       // Plot the Power Spectrum for means
int  AmpliSpectrum = 0 ;	   // Plot the Amplitude Spectrum
int mAmpliSpectrum = 0 ;       // Plot the Amplitude Spectrum for means
int       PlotData = 0 ;	   // Plot the Data series
int      mPlotData = 0 ;	   // Plot the Moving Mean Data series
int      PlotPhase = 0 ;	   // Plot the Lambda Phases
int     mPlotPhase = 0 ;	   // Plot the Lambda Phases for means
int      PlotSynth = 0 ;	   // Plot the synthesis of raw lambdas
int     mPlotSynth = 0 ;	   // Plot the synthesis of running mean lambdas

int     PlotRawDips    = 0 ;   // Plot dips on synthesised raw lambdas
int    PlotMeanDips    = 0 ;   // Plot dips on synthesised running mean lambdas
int   PlotRawTunedDips = 0 ;   // Plot dips on tuned synthesised raw lambdas
int  PlotMeanTunedDips = 0 ;   // Plot dips on tuned synthesised running mean lambdas

int    PlotRawPeaks    = 0 ;   // Plot peaks on synthesised raw lambdas
int   PlotMeanPeaks    = 0 ;   // Plot peaks on synthesised running mean lambdas
int  PlotRawTunedPeaks = 0 ;   // Plot peaks on tuned synthesised raw lambdas
int PlotMeanTunedPeaks = 0 ;   // Plot peaks on tuned synthesised mean lambdas

int     PlotFSynth = 0 ;	   // Plot the forced synthesis of raw lambdas
int    mPlotFSynth = 0 ;	   // Plot the forced synthesis of running mean lambdas
int   PlotFAlSynth = 0 ; 	   // Plot the forced synthesis of cos^2 alignment
int       PlotComp = 0 ;	   // Plot the Fourier Component
int      mPlotComp = 0 ;	   // Plot the Fourier Component for means
int     PlotShifts = 0 ;	   // Show leads of raw  Comp minima on aligns
int    mPlotShifts = 0 ;	   // Show leads of mean Comp minima on aligns
int     PlotAgraph = 0 ;	   // Agraph on raw data
int    mPlotAgraph = 0 ;	   // Agraph on moving mean data
int      PlotSysAV = 0 ;	   // Systemic Angular Velocity
int    PlotAlSysAV = 0 ;	   // Alignment of Systemic Angular Velocity
int  PlotSysMeanAlign = 0 ;	   // Alignment of the Systemic Direction on Mean Body
int PlotHSysMeanAlign = 0 ;	   // Ditto, heliocentric (should actually be the same)
int     PlotAligns = 0 ;	   // Show the Alignment symbols/arrows
int  modPlotAligns = 0 ;	   // Show the Modified Alignment symbols/arrows

int     ShowSelCrv = 0 ;	   // Show the Selectivity Curve

int    LPlotSynAgr = 0 ;	   // Prepare day-at-a-time Synthesis of  Raw Lambda for Synthetic Agraph
int   mLPlotSynAgr = 0 ;	   // Prepare day-at-a-time Synthesis of Mean Lambda for Synthetic Agraph

int   LPlotSynTune = 0 ;	   // Plot Synthesis of  Raw Lambda from filtered spectra
int  mLPlotSynTune = 0 ;	   // Plot Synthesis of Mean Lambda from filtered spectra
int    PlotSysPeri = 0 ;	   // Plot the direction of the Systemic Perihelion
int      PlotNEcLo = 0 ;	   // Plot Direction of Lunar Nodal in Ecliptic
int      PlotNEqLo = 0 ;	   // Plot Direction of Lunar Nodal in Equatorial plane
int     PlotPeriLo = 0 ;	   // Plot Longitude/RA of Perigee
int        PlotMot = 0 ;	   // Plot Direction of Systemic Motion
int       PlotAMot = 0 ;	   // Plot Alignment of Systemic Motion
int  PlotBSysAlign = 0 ;	   // Plot the Body's Alignment with the System
int    PlotSelLong = 0 ;	   // Plot the Selected Longitude(s)
int  PlotAccBodies = 0 ;	   // Plot the Selected Acceleration(s)
int    PlotDirMean = 0 ;	   // Plot the direction of the Cartesian Mean Body
int   PlotMassBscs = 0 ;	   // Plot per-body mass bisectoids
int    GeocMeanBod = 0 ;	   // Plot the geocentric version of the CBM else heliocentric
int PlotSysDirMean = 0 ;	   // Plot the systemic direction on the Cartesian Mean Body
int PlotSysDirMeanbyMass = 0 ; // Plot the systemic direction on the Cartesian Mean Body
int     PlothMassDir = 0 ;	   // Plot the heliocentric direction of the Mass Centre
int  PlotSysDirOnSun = 0 ;     // Plot the heliocentric systemic direction
int      PlotCRate = 0 ;	   // Plot the "Closure Rate"
int    PlotCsqRate = 0 ;	   // Plot the Time Rate of Change of alignment
int     PlotAlData = 0 ;	   // Plot the unmodified cos^2 alignment graph
int  PlotAlModData = 0 ;	   // Plot the   modified cos^2 alignment graph
int    PlotAlFrequ = 0 ;	   // Plot instantaneous alignment frequency
int      PlotAlPow = 0 ;	   // Plot the alignment power spectrum
int      PlotAlAmp = 0 ;	   // Plot the alignment amplitude spectrum
int      PlotAlPha = 0 ;	   // Plot the alignment phase spectrum
int     PlotSinCos = 0 ;	   // Plot the sin and cos fourier align't spectra
int    Plot3MLines = 0 ;	   // Plot the max, min and mean order cursor lines and texts
int   PlotObsShift = 0 ;	   // Plot Observed Phase Shift
int   Plot7daygrat = 0 ;	   // Plot Graticule
int     ShowShifts = 0 ;	   // Show phase-shifts of actual bud dips vertically
int         toLink = 0 ;	   // Display Links to Dip Arrowa

int  PlotVectorSum = 0 ;	   // Plot the resultant of radii on Mean Body
int  PlotVectorDir = 0 ;	   // Plot the direction of the resultant on Mean Body
int  PlotVectorLat = 0 ;	   // Plot the latitude  of the resultant on Mean Body

int   PlotAccelSum = 0 ;	   // Plot the resultant of acceleration of Mean Body
int   PlotAccelDir = 0 ;	   // Plot the direction of the acceleration of Mean Body
int   PlotAccelLat = 0 ;	   // Plot the latitude  of the acceleration of Mean Body

int PlotCoMVectorSum = 0 ;	   // Plot the resultant of velocities on Mass Centre
int PlotCoMVectorDir = 0 ;	   // Plot the direction of the mean velocity on Mass Centre
int PlotCoMVectorLat = 0 ;	   // Plot the latitude  of the mean velocity on Mass Centre

int  PlotCoMAccelSum = 0 ;	   // Plot the resultant of acceleration on Mass Centre
int  PlotCoMAccelDir = 0 ;	   // Plot the direction of acceleration on Mass Centre
int  PlotCoMAccelLat = 0 ;	   // Plot the  latitude of acceleration on Mass Centre

int		   PlotTest  = 0 ;	   // Plot of test
int		   PlotTest1 = 0 ;	   // Plot of test
int		   PlotTest2 = 0 ;	   // Plot of test

int  PlotMBhRadius = 0 ;	   // Plot the heliocentric radius of the Mean Body
int PlotSysAlOnSun = 0 ;	   // Plot heliocentric Systemic Alignment
int     PlotAllAls = 0 ;	   // Plot all the geocentric Alignment epochs
int     PlotRaster = 0 ;	   // Plot the PG Raster (i.e., flags that the window is showing)
int   PlotMBDirreSun = 0 ;	   // Plot MB directions wrt MB Sun direction
int PlotMassDirreSun = 0 ;	   // Plot Mass directions wrt Mass Sun direction

int        RastRawDips = 0 ;   // Rasterise Synthetic Lambda Dips and Peaks
int       RastMeanDips = 0 ;
int       RastRawPeaks = 0 ;
int      RastMeanPeaks = 0 ;
int   RastTunedRawDips = 0 ;
int  RastTunedMeanDips = 0 ;
int  RastTunedRawPeaks = 0 ;
int RastTunedMeanPeaks = 0 ;

//****************************************************************
//****************************************************************

int              bud ;		   // Global bud index or counter

//****************************************************************
//****************************************************************

#define MAXORDINDEX  32000
#define MAXIMPLIED   60000		

#define   sidx MAXORDINDEX - 20
int      stash = sidx     ;		// "spare" Fourier struct members
int     mstash = sidx + 1 ;
int   stashbig = sidx + 2 ;
int   stashwee = sidx + 3 ;
int  mstashbig = sidx + 4 ;
int  mstashwee = sidx + 5 ;

// this struct holds results pertaining to a single epoch

        typedef struct tagSYSTEMIC
                {
	       double gLongs[30] ;	// geocentric
		   double hLongs[30] ;	// heliocentric 
	       double  gLats[30] ;	// geocentric
		   double  hLats[30] ;	// heliocentric 
		   double  gRads[30] ;	// (N.B., geocentric, in the referencing plane)
		   double  hRads[30] ;	// these are heliocentric and lie in the ecliptic

		   double gx_on_Earth[25] ;	// geocentric cartesian ordinates of bodies wrt ecliptic
		   double gy_on_Earth[25] ;
		   double gz_on_Earth[25] ;

		   double ex_on_Earth[25] ;	// geocentric cartesian ordinates of bodies wrt equatorial plane
		   double ey_on_Earth[25] ;
		   double ez_on_Earth[25] ;

		   double x_on_Sun[25] ;	// heliocentric cartesian ordinates of bodies
		   double y_on_Sun[25] ;
		   double z_on_Sun[25] ;

		   double xvel[25] ;		// heliocentric cartesian ordinates of body velocities
		   double yvel[25] ;
		   double zvel[25] ;

		   double xmvel[25] ;		// heliocentric mass-weighted cartesian ordinates of body velocities
		   double ymvel[25] ;
		   double zmvel[25] ;

		   double xacc[25] ;		// heliocentric cartesian ordinates of body accelerations
		   double yacc[25] ;
		   double zacc[25] ;
		   double BodAcc[25] ;

		   double xmacc[25] ;		// heliocentric mass-weighted cartesian ordinates of body accelerations
		   double ymacc[25] ;
		   double zmacc[25] ;

		   double xmf[25] ;			// heliocentric mass-weighted cartesian ordinates of body forces (????)
		   double ymf[25] ;
		   double zmf[25] ;

		   double xFpt ;
		   double yFpt ;
		   double Spd ;

		   double    Pair[18][18] ;	// directions of body-to-body lines
		   double PairRad[18][18] ;	// "radii" of pairs

		   double gmean_x ;		// geocentric mean position of included bodies ("mean body") 
		   double gmean_y ;
		   double gmean_z ;

		   double gmean_lo ;	// geocentric direction of mean body
		   double gmean_la ;	// geocentric  latitude of mean body
		   double gmean_ra ;	// geocentric    radius of mean body

		   double hmean_lo ;	// heliocentric direction of mean body
		   double hmean_la ;	// heliocentric  latitude of mean body
		   double hmean_ra ;	// heliocentric    radius of mean body

		   double hMmean_lo ;	// heliocentric direction of Mass Centre
		   double hMmean_la ;	// heliocentric  latitude of Mass Centre
		   double hMmean_ra ;	// heliocentric    radius of Mass Centre

		   double rmc ;			// radius of mean circle ON mean body

		   double mVectSum ;	//  vector sum of velocities ON mean body
		   double mVectDir ;    //  direction of velocity vector sum
		   double mVectLat ;	// "latitude" of velocity vector

		   double maVectSum ;	//  vector sum of accelerations ON mean body
		   double maVectDir ;	//  direction of acceleration vector sum
		   double maVectLat ;	// "latitude" of acceleration vector

		// Mass weighted

		   double mMVectSum ;	//  vector sum of velocities ON mass centre
		   double mMVectDir ;    //  direction of mass centre velocity vector sum
		   double mMVectLat ;	// "latitude" of mass centre velocity vector

		   double mMaVectSum ;	//  vector sum of forces ON mass centre
		   double mMaVectDir ;	//  direction of mass centre force vector sum
		   double mMaVectLat ;	// "latitude" of mass centre force vector sum

		   double mMAVectSum ;	//  vector sum of acceleration ON mass centre
		   double mMAVectDir ;	//  direction of mass centre acceleration vector sum
		   double mMAVectLat ;	// "latitude" of mass centre acceleration vector sum

			double hmeanbod_lo[25] ;
			double hmeanbod_la[25] ;

			double bSysDir[25] ;
			double bSysAln[25] ;

			double sysmeanalign ;

		   double TPx[25] ;			// per body x on ecliptic of mass systemic line (bisectoid) turning point 
		   double TPy[25] ;			// per body y on ecliptic of mass systemic line (bisectoid) turning point
		   
		   double TPBx[25] ;		// per body x on ecliptic of position systemic line (bisectoid) turning point 
		   double TPBy[25] ;		// per body y on ecliptic of position systemic line (bisectoid) turning point

		   double TPMBx[25] ;		// per body x of turning point on Mean Body to True Body line
		   double TPMBy[25] ;		// per body y of turning point on Mean Body to True Body line

		   double xT[25][25] ;		// x of interbody turning points (that is, xT[bod1][bod2])
		   double yT[25][25] ;		// y of interbody turning points (that is, yT[bod1][bod2])

		   double SPMx ;			// 'Systemic Primary'
		   double SPMy ;

		   double SPx ;
		   double SPy ;

		   double xyslp ;			// slope of xy regression line in current frame
		   double xyicept ;
		   double xycorr ;
		   double regxsig ;
		   double regysig ;
		   double xyphi ;

		   double av[25] ;		 // per-body angular velocity
		   double sysav ;		 // systemic angular velocity
		   double alsysav[25] ;	 // per-body alignment of angular velocities to sysav
		   double malsysav ;	 // mean alignment of angular velocities to sysav
		   double frq[25] ;		 // per-body instantaneous frequency in cycles per day (av[p]/twopi)

		   double mpairAV ;		 // mean Angular Velocity of pairs
		   double pairVt[25][25] ; // function of velocity of turning point

		   double gshift[25] ;  // per-body angular shifts of systemic directions by position
		   double hshift[25] ;
		   double mshift[25] ;
		   double meangshift ;	// mean shifts
		   double meanhshift ;
		   double meanmshift ;

                } SYSTEMIC, * LPSYSTEMIC ;

		SYSTEMIC Sy ;			 // make an instance of the above struct
	  LPSYSTEMIC pSy = &Sy ;	 // get a pointer to it
		SYSTEMIC VSy ;			 // an instance for the viewer
	  LPSYSTEMIC pVSy = &VSy ;	 // get a pointer to it


// This struct holds arrays of results pertaining to a range of epochs

        typedef struct tagFOURIER
                {
	       double    amp[MAXORDINDEX] ;   // spectrum component amplitude
	       double  phase[MAXORDINDEX] ;   // spectrum component phase
	       double   mamp[MAXORDINDEX] ;    // Same for meandata 
	       double mphase[MAXORDINDEX] ;    // 
	       double     Ac[MAXORDINDEX] ;   // Cosine component 
	       double     Bs[MAXORDINDEX] ;   // Sine component 
	       double    mAc[MAXORDINDEX] ;    // Same for meandata
	       double    mBs[MAXORDINDEX] ;    //
		   double  tShift[MAXORDINDEX] ;  // Raw  Time shift corresponding to phase
		   double mtShift[MAXORDINDEX] ;  // Mean Time shift corresponding to phase

		   double    avlun[MAXDATA] ;	  // lunar angular velocity in frame
		   double    avbod[MAXDATA] ;	  // body's angular velocity in frame
		   double   angclr[MAXDATA] ;	  // Apparent angular "closure rate"
		   double   minclr ; 			  // Min. closure rate
		   double   maxclr ;	    	  // Max. closure rate
		   double    clrpd[MAXDATA] ;     // Closure period = 1/frequ, frequ = rate/twopi
		   double  sysAclr[MAXDATA] ;	  // Systemic angular "closure rate"
		   double   dAbydt[MAXDATA] ;	  // Rate of change of alignment

           double     data[MAXDATA] ;     // Raw Data series
           double  moddata[MAXDATA] ;     // Modified Raw Data series

		   double    mdata[MAXDATA] ;     // Moving Mean Data series

		   double  sOneDay[MAXDATA] ;	  // Synthesised     Data Series a day at a time
		   double msOneDay[MAXDATA] ;	  // Synthesised MeanData Series a day at a time
		   double    sdata[MAXORDINDEX] ; // Synthesized     Data series
		   double   msdata[MAXORDINDEX] ; // Synthesised MeanData series
		   double   fsdata[MAXORDINDEX] ; // Force-synthesized     Data series
		   double  fmsdata[MAXORDINDEX] ; // Force-synthesised MeanData series
		   double fsaldata[MAXORDINDEX] ; // Force-synthesised Alignment Data series

		   double   tsdata[MAXORDINDEX] ; // Tuned-synthesis Data Series
		   double  tmsdata[MAXORDINDEX] ; // Tuned-synthesis MeanData Series
		   double tsaldata[MAXORDINDEX] ; // Tuned-synthesis Alignment Data Series
		   double      tau[MAXORDINDEX] ; // Transfer co-efficients
		   double      eta[MAXORDINDEX] ; // Phase shifts of transfers

		   double   maxtau ;			  // Maximum transfer co-efficient
		   double   maxeta ;			  // Phase shift at maximum transfer
		   double taumaxord ;			  // Order of maximum transfer
		      int taumaxidx ;			  // Index of max transfer values

		   double   mintau ;			  // Minimum transfer co-efficient
		   double   mineta ;			  // Phase shift at minimum transfer
		   double tauminord ;			  // Order of minimum transfer
		      int tauminidx ;			  // Index of min transfer values

		   double OrderStep ;		   // Order step used
	       double DataMean ;           // Mean of data
		   double mDataMean ;		   // Mean of MeanData
		   double Hidata ;             // Greatest data amplitude
		   double Lodata ;			   // Least data amplitude
		   double mHidata ;            // Greatest meandata amplitude
		   double mLodata ;			   // Least meandata amplitude
		   double Maxamp ;			   // Highest Spectrum Ampl. found (Dominant)
		   double mMaxamp ;			   // Highest for meandata (Dominant)
		   double ComMaxamp ;          // The latest maximum amplitude
		   double Maxampord ;		   // Order of Maxamp
		   double mMaxampord ;		   // Order of mMaxamp
			  int Maxampidx ;		   // Index of Maxamp
			  int mMaxampidx ;		   // Index of mMaxamp
		   double  spcPeak[MAXPEAKS] ;	   // spectrum peak values
		   double  ordPeak[MAXPEAKS] ;	   // orders of spectrum peaks
		   double  phaPeak[MAXPEAKS] ;     // phases of the spectrum peaks
		   double mspcPeak[MAXPEAKS] ;	   // spectrum peak values (running means)
		   double mordPeak[MAXPEAKS] ;	   // orders of spectrum peaks (ditto)
		   double mphaPeak[MAXPEAKS] ;     // phases of the spectrum peaks(ditto)
		     RECT   rcPeak[MAXPEAKS] ;	   // rectangles enclosing peaks
			 RECT  rcmPeak[MAXPEAKS] ;     // rectangles enclosing peaks (running means)
		      int  Peaks ;			   // indices of peaks in raw spectrum
			  int mPeaks ;			   // indices of peaks in running mean spectrum
		   double bigPeak ;			   // value of highest peak
		   double bigOrd ;			   // order of highest peak
		   double bigPha ;			   // phase of highest peak
		   double mbigPeak ;		   // same, but for running mean data
		   double mbigOrd ;
		   double mbigPha ;
	          int max_order_index ;	   // Highest index of array of orders
		   double loAlOrd ;			   // Lowest  Alignment order used
		   double hiAlOrd ;			   // Highest Alignment order used
		   double  rSTDdata[MAXDATA] ; // Mov. std. devs on raw  lambdas
		   double  mSTDdata[MAXDATA] ; // Mov. std. devs on mean lambdas

		   double    DipVal[MAXPEAKS] ; // values of dips in current raw  synthesis
		   double   mDipVal[MAXPEAKS] ; // values of dips in current mean synthesis
		   double   tDipVal[MAXPEAKS] ; // values of dips in current raw  tuned synthesis
		   double  tmDipVal[MAXPEAKS] ; // values of dips in current mean tuned synthesis

		   double    DipEps[MAXPEAKS] ; //   ep's of dips in current raw  synthesis
		   double   mDipEps[MAXPEAKS] ; //   ep's of dips in current mean synthesis
		   double   tDipEps[MAXPEAKS] ; //   ep's of dips in current raw  tuned synthesis
		   double  tmDipEps[MAXPEAKS] ; //   ep's of dips in current mean tuned synthesis

		      int     nDips ;		    // Number of dips in current raw  synthesis
			  int    nmDips ;			// Number of dips in current mean synthesis
			  int	 ntDips ;			// Number of dips in current raw  tuned synthesis
			  int   nmtDips ;			// Number of dips in current mean tuned synthesis

		   double  rdpShift[MAXPEAKS] ;	//       raw  dip shift wrt body
		   double trdpShift[MAXPEAKS] ;	// tuned raw  dip shift wrt body
		   double  mdpShift[MAXPEAKS] ;	//       mean dip shift wrt body
		   double tmdpShift[MAXPEAKS] ;	// tuned mean dip shift wrt body

		   double rdpMeanShift ;		// mean raw dip shift for the series
		   double rdpMeanEpoch ;		// mean epoch of the raw dips of the series

		   double    PeakVal[MAXPEAKS] ; // values of peaks in current raw  synthesis
		   double   mPeakVal[MAXPEAKS] ; // values of peaks in current mean synthesis
		   double   tPeakVal[MAXPEAKS] ; // values of peaks in current raw  tuned synthesis
		   double  tmPeakVal[MAXPEAKS] ; // values of peaks in current mean tuned synthesis

		   double    PeakEps[MAXPEAKS] ; //   ep's of peaks in current raw  synthesis
		   double   mPeakEps[MAXPEAKS] ; //   ep's of peaks in current mean synthesis
		   double   tPeakEps[MAXPEAKS] ; //   ep's of peaks in current raw  tuned synthesis
		   double  tmPeakEps[MAXPEAKS] ; //   ep's of peaks in current mean tuned synthesis

		      int     nPeaks ;		     // Number of peaks in current raw  synthesis
			  int    nmPeaks ;			 // Number of peaks in current mean synthesis
			  int	 ntPeaks ;			 // Number of peaks in current raw  tuned synthesis
			  int   nmtPeaks ;			 // Number of peaks in current mean tuned synthesis

		   double  rpkShift[MAXPEAKS] ;	//       raw  peak shift wrt body
		   double trpkShift[MAXPEAKS] ;	// tuned raw  peak shift wrt body
		   double  mpkShift[MAXPEAKS] ;	//       mean peak shift wrt body
		   double tmpkShift[MAXPEAKS] ;	// tuned mean peak shift wrt body

			  int items ;              // Number of data items
                } FOURIER, * LPFOURIER ;

		FOURIER     Samp ;					// make an instance of this struct
		LPFOURIER  pSamp = &Samp ;			// get pointer to it
        
        LPFOURIER  pFourier = NULL ;	   // General struct
		LPFOURIER    pAlFou = NULL ;	   // Alignment struct
		LPFOURIER   pFAlFou = NULL ;	   // Forced Alignment Synthesis struct
		LPFOURIER    pIMFou = NULL ;	   // Implied Period struct

		LPFOURIER pf, pa, pv, pn, pk, pz, pb ;

			  int  doFlyers = 0 ;			// Flyers turned off at kick-off

			 RECT        rcRawDip[MAXPEAKS] ;
			 RECT       rcMeanDip[MAXPEAKS] ;
			 RECT   rctunedRawDip[MAXPEAKS] ;
			 RECT  rctunedMeanDip[MAXPEAKS] ;

			 RECT       rcRawPeak[MAXPEAKS] ;
			 RECT      rcMeanPeak[MAXPEAKS] ;
			 RECT  rctunedRawPeak[MAXPEAKS] ;
			 RECT rctunedMeanPeak[MAXPEAKS] ;


			 RECT        rcRastRawDip[MAXPEAKS] ;
			 RECT       rcRastMeanDip[MAXPEAKS] ;
			 RECT   rcRastTunedRawDip[MAXPEAKS] ;
			 RECT  rcRastTunedMeanDip[MAXPEAKS] ;

			 RECT       rcRastRawPeak[MAXPEAKS] ;
			 RECT      rcRastMeanPeak[MAXPEAKS] ;
			 RECT  rcRastTunedRawPeak[MAXPEAKS] ;
			 RECT rcRastTunedMeanPeak[MAXPEAKS] ;

			 RECT rcRastAl[MAXALS] ;

// prototype needed now
void Spectrum( 
			  LPFOURIER fou,
			        int N,
			     double * pOrderStep,
			     double Hi_Order,
				 double Lo_Order,
				    int Raw
			) ;

// The next function was originally defined in Fourier.h,
// but is now first needed by an astronomical function.

double integral( double c[], int n )    // Simpson's approximation. 
{       				                // n should be even: final  
 int i ;   double h, esum, osum ;	    // data value dropped if not.
 if ( n%2 ) n-- ;
 esum = osum = 0.0 ; h = 1.0 /(double)n ;
    i = 1 ; while ( i < n )     { osum += c[i] ; i += 2 ; }
    i = 2 ; while ( i < n - 1 ) { esum += c[i] ; i += 2 ; }
	return ( ( h/3.0 )*( c[0] + c[n] + 4.0*osum + 2.0*esum ) ) ;

} // integral()


int			UseCentre =  GE ;		// default centre is Geocentric
int			UsePlanet =  MAR ;      // default planet is Mars
char  CurrentBody[25] = "MARS" ;

// Bring in the Astronomical functions

#include "Astron.h"

  RECT rcAL[Planets][MAXALS] ; // enclosing alignments on Raster per body per series

// Bring in the Fourier functions

#include "Fourier.h"

// Astronomical stuff. (cross refer to "Astron.h")

UINT      day1 =  1 ;	   // default dates
UINT      day2 =  2 ;
UINT      mon1 =  6 ;
UINT      mon2 =  7 ;
UINT     year1 = 98 ;
UINT     year2 = 99 ;


int   S_Hour   = 12 ;     // hour   of sample (default mid-day).
int   S_Minute =  0 ; 	  // minute of sample

int mondy[] = {0,31,28,31,30,31,30,31,31,30,31,30,31} ; // days in months

// Friendly month names
char    * szMonth[] = { "None","Jan ","Feb ","Mar ","Apr ","May ", 
							   "Jun ","Jul ","Aug ","Sep ","Oct ","Nov ",
                                "Dec " } ;

int StandardBudImage = 1 ;		// we have a standard bud image in work


//*****************************
// DEFAULT RESULT-BASE FOLDERS
//*****************************
char DefaultABRpath[] = "c:\\Main Bud Archive\\" ;	// default base ABR path
char		 AllCol[] = "c:\\Main Bud Archive\\All Collations\\" ;
char         AllHst[] = "c:\\Main Bud Archive\\Host Images\\" ;

char    AllImg[256] ;	// default base paths for result files
		//strcpy(AllImg, "C:\\Main Bud Archive\\All IMG\\") ;
char    AllIni[256] ;
		//strcpy(AllIni, "C:\\Main Bud Archive\\All INI\\") ;
char    AllDat[256] ;
		//strcpy(AllDat, "C:\\Main Bud Archive\\All DAT\\") ;
char    AllTrk[256] ;
		//strcpy(AllTrk, "C:\\Main Bud Archive\\All TRK\\") ;
//*****************************

char    * szBudItems[MAXBUDS] ;   // Enough for 25 yrs at a bud-per-day

int   UpdateDisplay = 1 ;         // Update display on image load.
int     skipgetfile = 0 ;		  // skip over getbudfile
int UpdatingRecords = 0 ;		  // Used during "synching"
int      Sequencing = 0 ;		  // Used while sequencing
int       showstats = 0 ;		  // Show search statistics
int		  Select2BW = 0 ;		  // Select into BW

//Calibration

double  InterCalMarkDIBits ;	// Bits in DIB between marks		 
double       CalSize = 0.0 ;	// Actual distance at object between marks
int       calibrated = 0 ;	    // Is calibration in effect
int       xCal1, yCal1 ;		// Client co-ords of  first mark
int       xCal2, yCal2 ;		// Client co-ords of second mark 
int       xBCal1, yBCal1 ;		// Buffer co-ords of  first mark
int       xBCal2, yBCal2 ;		// Buffer co-ords of second mark
int      CAL_1_AVAILABLE ;		// First  mark is available, perhaps from file
int      CAL_2_AVAILABLE ; 		// Second mark is available, perhaps from file

// Pole Setting: show matching Path Curve

   int    showPC = 1    ;

//Trial PC

double  TrialLam = 2.0  ;	// default
double  TrialRad = 0.25 ;	// default

double   TLamInc = 0.005  ;  // default
double   TRadInc = 0.005 ;	 // default

//Axial

//double TrialALam = 0.0 ;
//double TrialARad = 0.0 ;

static PRJ = 1, DIA = 0, LEF = 0, RYT = 0 ;
static DTL = 0, NPR = 0 ;

// TWAIN

HANDLE		hDib;       // current DIB, if any
HPALETTE 	hpal;       // logical palette for same, if any
unsigned    wPixTypes;  // enabled pixel types
int         acquired = 0 ;
static char			szAppName[32];
static char			szMessage[128];

// Scroll bars for setting line-scanning and peak-picking parameters
HWND hScrGain, hScrTh, hScrSmooth ;

// Sub-Rectangles of line-scan colour selection control 
RECT rcLsa, rcLsr, rcLsg, rcLsb ;

// Auto Grab

UINT MaxGrbIval = 120 ;		// default maximum
UINT MaxGrbIntLimit = 1440 ; // 24 hrs in minutes

 // Tips

RECT     rctl[NUMCONTROLS] ;        // rectangles for control bitmaps
HWND hWndInfo[NUMCONTROLS + 2] ;    // for overlaid info-window
HWND CurrentWindow ;
HWND CurrentTip = (HWND)NULL ;          // Tip currently showing
HWND hWndOfCurrentTip = (HWND)NULL ;	// Window of currently showing Tip
 int HaveOvly[NUMCONTROLS] ;
 int Deferred[NUMCONTROLS] ;
 int Dwelling[NUMCONTROLS] ;
 int  Clicked[NUMCONTROLS] ;
 int UseCtl ;
UINT WaitTim ;
UINT onTim ;
 int tDwell = 2500 ;
 int tDefer =  750 ;

 int picknmix = 0 ;
 int  useDATs = 0 ;

 int InButton[NUMCONTROLS] ; // For voiced tips
 int UseBtn ;
 int washere[NUMCONTROLS] ;
UINT  TimeOut ;
UINT  VTim ;
 int  delay = 1000 ;
 int    VOC = 0 ;

// Tip texts

	 char *Tip[] = {"  Set Search  \n Directory ",		  //0
					" Work with \n  Archive ",			  //1
		            " Voice Tips ",						  //2
					"  Running \n Commentary ",			  //3
					" Acquire and \n Prepare Images ",	  //4
                    "     Capture Window \n " \
                    "  for Saving or Printing. \n\n " \
                    "    Click here, then \n " \
                    " Press F12, then Click on \n" \
                    "     Window to Capture ",            //5
					" Grab Sequence ",
					" Geolocation by GPS ",
					" Select Archive ",					  //6
					" Quit the Workshop ",				  //7
					" Place Low Pole \n    Ctrl+L ",	  //8
					" Place High Pole \n     Ctrl+H ",	  //9
					" Scan or Measure Bud \n    Ctrl+S ",		 //10
					" Show or Hide \n Scan Graphs \n  Ctrl+G ",	 //11
					"      Set Number, and whether \n " \
					"   Linear or Growth Distribution, \n " \
					"  of Measurement Heights \n    Ctrl+V ",		    //12
					"     Colour or\n Grayscale Image, or \n Significance   Ctrl+C ",	//13
					" Calibrate on \n Marker One \n    Alt+1 ",			//14
					" Calibrate on \n Marker Two \n    Alt+2 ",			//15
					" Restore or \n Resize the Image ",		 //16
	                "    Scan on\n Luminance values ",		 //17
	                "    Scan on\n Colour values ",			 //18
	                " More Smoothing\n (On Lum. Values) ",	 //19
	                " Less Smoothing\n (On Lum. Values) ",	 //20
					"    Projective or\n Regression Path Curves \n    Ctrl+Shift+T ", //21
	                "   Show Path Curve\n Match on Diameters \n  Ctrl+Shift+D ",	//22
	                "   Show Path Curve\n Match on Left Radii \n  Ctrl+Shift+L ",	//23
					"   Show Path Curve\n Match on Right Radii \n  Ctrl+Shift+R ",	//24
					" Show Null Profile\n  Ctrl+Shift+N ",							//25
					" Show Bud \n Details\n  Ctrl+Shift+E ",						//26
					" Open an Existing Image ",										//27
                    " Acquire Image from \n Camera or Scanner ",					//28
					" Save the Image ",												//29
					" Pass the Image into \n the Bud Workshop ",					//30
					" Print the Image Now ",										//31
					" Preview and \n  Page Setup ",									//32
					" Rotate the Image ",											//33
					" Select Rectangle ",											//34
					" Crop the Image to \n the Rectangle ",							//35
					" Change the \n Dimensions \n of the Image ",					//36
					" Modify Contrast \n  or Brightness ",							//37
					" Design a \n Test Bud ", 										//38
					" Toggle Profile \n Tracking \n     Alt+M ",					//39
					" Track Left Profile \n    Alt+L ",								//40
					" Track Right Profile \n    Alt+R ",							//41
					" Accept Track \n    Alt+A",									//42
					" Set Smoothing Level, \n " \
					"   or Seek Span, \n " \
					"   or Threshold. \n    Alt+P ",								//43
					" Select Items \n for Collation ",								//44
					"   Show/Hide \n Listings Window ",								//45
					"    Lunar \n Alignments ",										//46
					" Synchronise Files ",											//47
					"  Archive \n Operations ",										//48
					"   Show/Hide \n Control Panel  ",								//49
					"  Previous Instance \n in Sequence \n      Alt+ <- ",			//50
					"   Next Instance \n in Sequence  \n       Alt+ -> ",			//51
					" Archive this Instance ",										//52
					"",																//53
					" Line scanning \n on Grayscale ",								//54
					" Line scanning \n on Red only ",								//55
					" Line scanning \n on Green only ",								//56
					" Line scanning \n on Blue only "								//57
					//" Archive this Instance "										//58
	                } ;

 int	showtips = 0 ;  // default is NOT to show tips. Change this in "preferences".

// Sound bite WAV files

char * szVocTipWav[] = {
		                "",				 // Set Search    Opf,  0
		                "collate.wav",	 //	Collate       Col,  1
		                "soundbite.wav", //	Sounds on     Voc,  2
						"commentary.wav",// Commentary    Cmt,  3
						"acquire.wav",	 //	Acquire		  Acq,  4
						"", "",          // Empty         5 to  6 incl.
		                "quit.wav",		 //	Exit          Xit,  7
		                "lopole.wav",	 //	Lo Pole       Lop,  8
		                "hipole.wav",	 //	Hi Pole       Hip,  9
		                "startscan.wav", //	Scan/Meas.	  Lsc, 10
		                "linescan.wav",	 //	Scan graphs   Gra, 11
		                "levels.wav",	 //	Levels        Lev, 12
		                "colgray.wav",	 //	Col/Gray/Stat Gry, 13
		                "calib1.wav",	 //	Calib 1		  Ca1, 14
		                "calib2.wav",	 //	Calib 2       Ca2, 15
						"",              // Resize 		  Rez, 16
		                "lumdlum.wav",	 // Luminance     Lum. 17
		                "huesat.wav",    // Hue           Hue, 18
	                    "smop.wav",      // Smooth up,    Smu, 19
						"smod.wav",		 // Smooth down,  Smd, 20
						"",				 // Proj/Regr,    Prj, 21
						"pfitdiam.wav",	 // on Diameters, Dia, 22
						"pfitlrad.wav",	 // Left radii,   Lef, 23
						"pfitrrad.wav",	 // Right radii,  Ryt, 24
						"nullprof.wav",	 // Null profile, Npr, 25
						"details.wav",	 // Details,      Dtl, 26
						"openexisting.wav",
						"acquire2.wav",
						"saveimage.wav",
						"passtowkshp.wav",
						"",
						"",
						"rotate.wav",
						"selectrect.wav",
						"croptorect.wav",
						"newpixdim.wav",
						"bricon.wav",
						"",
						"autotrack.wav",
						"trackleft.wav",
						"trackright.wav",
						"accepttrack.wav",
						"trackparms.wav"
                      } ;
	  
      int clips = 0 ;
	  int PlayList[25] ;

	  // "Running commentary" WAV files

      char * sBite[] = {
		                   "gotbmp.wav",	// 0 "Bit Map"
						   "gotjpg.wav",	// 1 "Jpeg"
						   "newbud.wav",	// 2 "This bud is new"
						  "newdate.wav",	// 3 "The date is new"
						   "oldbud.wav",	// 4 "This bud is on record"
						  "olddate.wav",	// 5 "The date is on record"
	                      "calibin.wav",	// 6 "It is calibrated in inches"
					      "calibmm.wav",	// 7 "It is calibrated in millimetres"
					     "defcalib.wav",	// 8 "in default image units"
					      "scanned.wav",	// 9
						"wrongtype.wav",	// 10
						  "isinset.wav",	// 11
						"isalldone.wav",	// 12
						 "somedone.wav",	// 13
						 "nonedone.wav",	// 14
						   "topset.wav",	// 15
						   "botset.wav",	// 16
						  "noneset.wav",	// 17
						  "bothset.wav"		// 18
                       } ;

// Early prototypes!
 
char    * FetchPath( char * fn ) ;
 
void    ReadDatFile( int ) ;
 int	ReadTrkFile( LPTRKINFO, char * ) ;

void    SaveDatFile( int, IDS ) ;
void	SaveIniFile( int, IDS ) ;
void    SaveTrkFile( LPTRKINFO, int, IDS ) ;


 int    MakeOverlay( UINT, int, int , char * ) ;
void        KillTip( HWND, int ) ;
void         PutTip( HWND, int, int ) ;
 int    RunningMean( int, int, LPFOURIER ) ;
 int             rm( int, int, double *, double * ) ;
		 
// Common Dialog File Handling

		 HFILE hBudfile ;
		 HFILE hBudData ;
         HFILE hf ;

         OPENFILENAME ofn ; 
         char szDirName[255] ;
		 char szCollDir[] = "\\Bud Archive\\All Collations" ;
         char szFile[255] ;
		 char szArchFile[255] ;
		 char szImageryFile[255] ;
		 char szCollFile[255] ;
         char szFileTitle[255] ;
         char szFilter[255] ;
		 char szCollFilter[255] ;
         char szHeader[255] ;

		 char szDummyFile[255] ;
		 char szSearchDir[255] = "C:\\Duplicate Bud Archive\\" ;
		 char pszDisplayName[] = "Please Select an Archive" ;

unsigned long FileSize ;

		 char szImgFile[255] ;
		 char szDatFile[255] ;
		 char szIniFile[255] ;
		 char szTrkFile[255] ;

		 char szIniPath[255] ;
		 char szDatPath[255] ;
		 char szTrkPath[255] ;

		 char szCurrentSuite[255] ;

		 char szResultPath[255] ;
		 char szNoImageFile[256] ;

	    HFILE htrack, hbud, hdat ;

// for the "Details" dialogue box and other things

char  * DimenCombo[200] ;
char * ResultCombo[200] ;

int     sounds = 0 ;   // sound bites.
int commentary = 0 ;   // spoken comment and guidance.


int      Units = IMAGEUNITS ; // Default measurement units

int     nPeaks = 0 ;  // Number of maxima in differential luminance scan
int   ISONPEAK = 0 ;  // Cursor is on a differential luminance peak
int     onPeak ;	  // Index of maximum currently under the cursor

// Ouch! These arrays were fixed at 200 long, and this is not adjusted in the distributed Workshops!
// Big, rich images may cause crashes. Need to warn them, and get out new version.
 
int     PeakAt[MAXPEAKS] ; // Buffer-inset-relative Positions of maxima
int    PeakVal[MAXPEAKS] ; // Values of maxima

// Following have origin at top left corner (TLC),
// Y increasing downwards,
// X increasing rightwards.

int       xRGB ;	 // X co-ord of cursor in RGB buffer
int       yRGB ;	 // Y co-ord of cursor in RGB buffer

int       xINS ;	 // X co-ord of cursor in RGB buffer inset
int       yINS ;	 // Y co-ord of cursor in RGB buffer inset

// Sub-Image (Inset) dimensions

// Y increasing downwards,
// X increasing rightwards.

int ws ;		   	 // Width
int hs ;			 // Height
int xsa, ysa ;       // Position of TLC in RGB buffer
int xsb, ysb ;		 // Position of BRC	in RGB buffer

int newimage = 0 ;

// Default pole positions in image units.
// We choose very unlikely values not
// too far from convenient ones!

double TPxdefault = 0.4567 ; // hi pole	
double TPydefault = 0.9543 ;
double BPxdefault = 0.5678 ; // low pole
double BPydefault = 0.0987 ;

   int hasDATinfo = 0 ;		 // Whether or not the INI carries the old DAT info
   int haveOldDAT = 0 ;		 // Whether or not we still have the old DAT file

// 'double' equivalent of POINT struct
typedef struct tagDPOINT		
       {
	double x ;
	double y ;
       } DPOINT, * LPDPOINT ;

typedef struct tagTXT
          {
			COLORREF tC ;	 //text colour
			COLORREF bC ;	 //background colour
			   HFONT fnt ;	 //font
			     int bM ;	 //mode OPAQUE|TRANSPARENT
			     int x ;	 //where x
			     int y ;	 //where y
                   } TXT, * LPTXT;

#define BLACK   0
#define WHITE   1
#define RED     2
#define GREEN   3
#define BLUE    4
#define YELLOW  5
#define MAGENTA 6


COLORREF Cr[] = {RGB(  0,  0,  0),	// Black
                 RGB(255,255,255),	// White
				 RGB(255,  0,  0),	// Red
				 RGB(  0,255,  0),	// Green
				 RGB(  0,  0,255),	// Blue
                 RGB(255,255,  0),	// Yellow
                 RGB(255,  0,255)} ;// Purple

typedef struct tagASTEPOCH
		{
	int aDay1 ;
	int aMon1 ;
	int aYr1 ;
	int aHr1 ;
	int aMn1 ;
	int aSc1 ;
 double aEp1 ;

	int aDay2 ;
	int aMon2 ;
	int aYr2 ;
	int aHr2 ;
	int aMn2 ;
	int aSc2 ;
 double aEp2 ;
		} ASTEPOCH, * LPASTEPOCH ;

  ASTEPOCH aE ;
LPASTEPOCH paE = &aE ;


typedef struct tagBUDID			// Bud ID struct
          {
	char      InstName[255] ;  // whole image file name, sans path or extension
	char        Prefix[80]  ;
	char        Suffix[80]  ;
	char     Extension[255] ;
	char     Directory[255] ;
	char    FriendlyID[255] ;
	char FriendlyPlace[255] ;
	char  FriendlyDate[255] ;
	char  FriendlyTime[255] ;
	char        szTime[80] ;

	char      szBudDay[80] ;
	 int        BudDay ;
	char      szBudMon[80] ;
	 int        BudMon ;
	char       szBudYr[80] ;
	 int         BudYr ;

	char	   szBudHr[80] ;
	 int         BudHr ;
	char	   szBudMn[80] ;
	 int		 BudMn ;
	char	   szBudSc[80] ;
	 int		 BudSc ;

    char       szJulEp[80] ;
  double         JulEp ;
          } BUDID, * LPBUDID ;

	BUDID B_ID ; 
	BUDID S_ID ;
	LPBUDID    Bud_ID = &B_ID ; 
	LPBUDID Search_ID = &S_ID ; 

 // the following are actual, in-memory-at-run-time
 // instances of the above struct.

 BUDID ToFro, Lose_Files, Valid_Bud ;

typedef struct tagBUDSEARCH  // Details of a search
          {
	char    Prefix[80] ;
	char    Suffix[80] ;
	char Extension[80] ;
	char Directory[255] ;

	// first epoch

	char szBudDay1[80] ;	// first day as string
	 int   BudDay1 ;		// first day as integer
	char szBudMon1[80] ;
	 int   BudMon1 ;
	char szBudYr1[80] ;
	 int   BudYr1 ;
	char szBudHr1[80] ;
	 int   BudHr1 ;
	char szBudMn1[80] ;
	 int   BudMn1 ;
	char szBudSc1[80] ;
	 int   BudSc1 ;
    char szJulEp1[80] ;	// the first ep in julian form as string 
  double   JulEp1 ;		// the first ep in julian form as double
  
	// final epoch

	char szBudDay2[80] ;	// final day as string
	 int   BudDay2 ;		// final day as integer
	char szBudMon2[80] ;
	 int   BudMon2 ;
	char szBudYr2[80] ;
	 int   BudYr2 ;
	char szBudHr2[80] ;
	 int   BudHr2 ;
	char szBudMn2[80] ;
	 int   BudMn2 ;
	char szBudSc2[80] ;
	 int   BudSc2 ;
    char szJulEp2[80] ;	// the final ep in julian form as string 
  double   JulEp2 ;		// the final ep in julian form as double 
          } BUDSEARCH, * LPBUDSEARCH ;

  BUDSEARCH BSrch ;
LPBUDSEARCH BudSearch = &BSrch ;

// This struct is copied exactly as it is to the bud instance data file (*.DAT),
// and saved in the Archive on disk.  When the instance is next loaded into the
// Workshop, this struct is simply put back where it came from.

/**********************************************************************************************
    !!!! THIS STRUCT DID NOT WORK PROPERLY UNDER BUILD BY VISUAL STUDIO 2010 C++ ULTIMATE !!!!
 **********************************************************************************************/
typedef struct tagBUDRESULTS	// as it says!
           {
	      char BudSpecTxt[255] ;   // bud I.D.(species, assay number etc)
		  char BudPlaceTxt[255] ;  // address-style location
		  char BudLatitudeTxt[80] ;	 // geographic location ..
		  char BudLongitudeTxt[80] ; // .. from GPS
		  char BudImageFile[128] ; // sample source image file
		  char BudDataFile[128] ;  // sample data file
		  char BudTextFile[128] ;  // sample text file for printing etc
		  char BudDateTxt[80] ;	   // date of this sample
		  char BudTimeTxt[80] ;	   // time of this sample

		   int NumHyts ;           // number of measurement heights

		   int SubImageX ;		   // x position of sub image
		   int SubImageY ;		   // y position of sub image
		   int SubImageW ;		   // width of  sub image
		   int SubImageH ;		   // height of sub image
		   int Edges[MAXLEVELS] ;  // Measurement status per level

		double BudMag ;            // image magnification
	    double BudLength ;		   // distance between poles,
		                           //   in "image units".
		double BudTilt ;		   // in radians from horizontal
		double BudTopPoleX ;	   // x-position of top pole,
		                           //   as fraction of image width
		double BudTopPoleY ;	   // y-position of top pole,
		                           //   as fraction of image width
		double BudBotPoleX ;	   // x,y position of bottom pole, ditto.
		double BudBotPoleY ;

		// re lambda on left radii
		double LeftProjLambda ;		// lambda by Lawrence's method
		double LeftProjMRD ;		// corresponding mean radius deviation 
		double LeftRegrLambda ;		// lambda by linear regression
		double LeftRegrMRD ;		// corresponding mean radius deviation

		// re lambda on right radii
		double RightProjLambda ;	// lambda by Lawrence's method
		double RightProjMRD ;		// corresponding mean radius deviation 
		double RightRegrLambda ;	// lambda by linear regression
		double RightRegrMRD ;		// corresponding mean radius deviation

		// re lambda on diameters
		double DiamProjLambda ;		// lambda by Lawrence's method
	    double DiamProjMRD ;		// corresponding mean radius deviation 
		double DiamRegrLambda ;		// lambda by linear regression
		double DiamRegrMRD ;		// corresponding mean radius deviation

		double RProjDev[MAXLEVELS] ; // radius or diameter deviations
		double LProjDev[MAXLEVELS] ; // Projective
		double BProjDev[MAXLEVELS] ;

		double RRegrDev[MAXLEVELS] ; // radius or diameter deviations
		double LRegrDev[MAXLEVELS] ; // Regression
		double BRegrDev[MAXLEVELS] ;

		   int RProjBestAt ;		 // Level for least deviation
		   int LProjBestAt ;
		   int BProjBestAt ;

		   int RRegrBestAt ;
		   int LRegrBestAt ;
		   int BRegrBestAt ;

		double RightRegrCoeff ;		// right regression coefficient
		double LeftRegrCoeff ;		//  left regression coefficient
		double BothRegrCoeff ;		//  both regression coefficient
		double Xmult[100] ;			//    top-limb multipliers
		double Ymult[100] ;			// bottom-limb multipliers
		double meanXmult ;			// mean of included    top-limb multipliers
		double meanYmult ;			// mean of included bottom-limb multipliers

           } BUDRESULTS, * LPBUDRESULTS ;

LPBUDRESULTS pBudResults ;				// the actual pointer

// An adjustment was made to the number of measurement-heights
// available on a bud, which put structs saved before the change
// out of date. This struct allows old .DAT files to be used -
// but they are converted to the new style and re-saved under their
// old names, so they should eventually be eliminated from the archive.

typedef struct tagOBUDRESULTS	// as it says! (old version)
           {
	      char BudSpecTxt[255] ;		// bud I.D.(species, assay number etc)
		  char BudPlaceTxt[255] ;		// address-style location
		  char BudLatitudeTxt[80] ;		// topographic location ..
		  char BudLongitudeTxt[80] ;	// .. from GPS
		  char BudImageFile[128] ;		// sample source image file
		  char BudDataFile[128] ;		// sample data file
		  char BudTextFile[128] ;		// sample text file for printing etc
		  char BudDateTxt[80] ;			// date of this sample
		  char BudTimeTxt[80] ;			// time of this sample

		   int NumHyts ;            // number of measurement heights

		   int SubImageX ;		    // x position of sub image
		   int SubImageY ;		    // y position of sub image
		   int SubImageW ;		    // width of  sub image
		   int SubImageH ;		    // height of sub image
		   int Edges[OMAXLEVELS] ;  // Measurement status per level

		double BudMag ;             // image magnification
	    double BudLength ;		    // distance between poles,
		                            //   in "image units".
		double BudTilt ;		    // in radians from horizontal
		double BudTopPoleX ;	    // x-position of top pole,
		                            //   as fraction of image width
		double BudTopPoleY ;	    // y-position of top pole,
		                            //   as fraction of image width
		double BudBotPoleX ;	    // x,y position of bottom pole, ditto.
		double BudBotPoleY ;

		// Lambda etc on left radii
		double LeftProjLambda ;		// lambda by Lawrence's method ("Projective Lambda")
		double LeftProjMRD ;		// corresponding mean radius deviation 
		double LeftRegrLambda ;		// lambda by linear regression ("Regression Lambda")
		double LeftRegrMRD ;		// corresponding mean radius deviation

		// on right radii
		double RightProjLambda ;	// lambda by Lawrence's method
		double RightProjMRD ;		// corresponding mean radius deviation 
		double RightRegrLambda ;	// lambda by linear regression
		double RightRegrMRD ;		// corresponding mean radius deviation

		// on diameters
		double DiamProjLambda ;		// lambda by Lawrence's method
	    double DiamProjMRD ;		// corresponding mean radius deviation 
		double DiamRegrLambda ;		// lambda by linear regression
		double DiamRegrMRD ;		// corresponding mean radius deviation

		double RProjDev[OMAXLEVELS] ; // radius or diameter deviations
		double LProjDev[OMAXLEVELS] ; // Projective
		double BProjDev[OMAXLEVELS] ;

		double RRegrDev[OMAXLEVELS] ; // radius or diameter deviations
		double LRegrDev[OMAXLEVELS] ; // Regression
		double BRegrDev[OMAXLEVELS] ;

		   int RProjBestAt ;		 // Level for least deviations
		   int LProjBestAt ;
		   int BProjBestAt ;

		   int RRegrBestAt ;
		   int LRegrBestAt ;
		   int BRegrBestAt ;

		double RightRegrCoeff ;		// right regression coefficient
		double LeftRegrCoeff ;		// left regression coefficient
		double BothRegrCoeff ;		// both regression coefficient

           } OBUDRESULTS, * LPOBUDRESULTS ;

LPOBUDRESULTS pOBudResults ;				// the actual pointer

// Standard Deviations of bud from computed form 
// (come too late for inclusion in results struct!)

// Projective
double DProjSD ; // diameters
double LProjSD ; // left radii
double RProjSD ; // right radii
// Regression
double DRegrSD ; // diameters
double LRegrSD ; // left radii
double RRegrSD ; // right radii

// Measurement details.
// ~~~~~~~~~~~~~~~~~~~~
// All quantities are image relative and in image units.
//
// One (1) image unit is the _width_ of the displayed
// bud-image, in pixels - that is, any measurement
// in pixels is converted to image units by dividing
// that measurement by the image-width in pixels.
typedef struct tagMEASURE		  
     {							  
	DPOINT       iTopPole ;				// top pole position
	DPOINT       iBotPole ;				// bottom pole position
    DPOINT      iAxisCuts[MAXLEVELS] ;	// axis cut points
	DPOINT iLevGradIcepts[MAXLEVELS] ;	// gradient and Icepts of levels
	DPOINT iAxisGradIcept ;			    // gradient and icept of axis
	DPOINT       iLeftCut[MAXLEVELS] ;	// pos. of left cut of bud edge
	DPOINT      iRightCut[MAXLEVELS] ;	// pos. of right cut of bud edge
	double       iLeftRad[MAXLEVELS] ;	// 'radius' to left of axis
	double      iRightRad[MAXLEVELS] ;	// 'radius' to right of axis
	double      iDiameter[MAXLEVELS] ;	// 'diameter' of bud at level
     } MEASURE, * LPMEASURE ;

LPMEASURE pMeasure ;

// Old-style struct, for upgrading old data files.
// See remarks above about the old Results struct.
 
typedef struct tagOMEASURE		  
     {							  
	DPOINT       iTopPole ;				   // top pole position
	DPOINT       iBotPole ;				   // bottom pole position
    DPOINT      iAxisCuts[OMAXLEVELS] ;    // axis cut points
	DPOINT iLevGradIcepts[OMAXLEVELS] ;    // gradient and Icepts of levels
	DPOINT iAxisGradIcept ;			       // gradient and icept of axis
	DPOINT       iLeftCut[OMAXLEVELS] ;	   // pos. of left cut of bud edge
	DPOINT      iRightCut[OMAXLEVELS] ;	   // pos. of right cut of bud edge
	double       iLeftRad[OMAXLEVELS] ;	   //'radius' to left of axis
	double      iRightRad[OMAXLEVELS] ;	   //'radius' to right of axis
	double      iDiameter[OMAXLEVELS] ;	   //'diameter' of bud at level
     } OMEASURE, * LPOMEASURE ;

LPOMEASURE pOMeasure ;

// Axis details in image units
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
DPOINT MidPt[MAXLEVELS+2] ;
double AxisProjLambda ;
double AxisRegrLambda ;
double AxisProjBestAt ;
double AxisRegrBestAt ;
double AxisRadius[MAXLEVELS+2] ;
double AxisProjDev[MAXLEVELS+2] ;
double AxisRegrDev[MAXLEVELS+2] ;
double AxisProjMRD ;
double AxisRegrMRD ;

char JulEpCpy[100] ;

int	PlotSeg( HWND hWnd, int i , int s, int xp, int yp )
		{
			   HDC hdc ;

			if (s > MAXTRACES)
			{
				msgbox = 1 ;
				MessageBox(NULL,
					"Too many Traces",
					"Plotting",
					MB_ICONEXCLAMATION|MB_OK) ;
				msgbox = 0 ;
				return 0 ;
			}

			hdc = GetDC(hWnd) ;

			if (i == 0)
				MoveToEx(hdc, oxp[s] = xp, oyp[s] = yp, NULL) ;
			else
			{
				MoveToEx(hdc, oxp[s], oyp[s], NULL) ;
				  LineTo(hdc, oxp[s] = xp, oyp[s] = yp) ;
			}

			ReleaseDC(hWnd, hdc) ;

			return 1 ;
		}

/*****************************************************************
		Make a "Friendly" Date String
 *****************************************************************/
char * MakeFriendlyDate(int full, int day, int month, int year)
{
	static char Friendly[255] ;											 	

	if (!full)
	{
	if (year > 80) year += 1900 ;
	if (year < 80) year += 2000 ;
	}

	sprintf(Friendly,"%2.2d %s %4.4d", day, szMonth[month], year ) ;
		
	return (Friendly) ;
}

/*****************************************************************
			Get a Date/epoch by Mouse Click in a Graph
 *****************************************************************/
double PickDate(
		  int xmouse,		// client mouse x position
		 char date[]		// friendly date corresponding to curEp
		)
	{
		 double eptemp, curEp ;

		 // convert mouse X-position to corresponding julian date
		 eptemp = ep ;
		 ep = xp2ep(xmouse) ;
		 curEp = ep ;
		 civildate() ;
	     clickedEp = curEp ;
		 sprintf(date, "Epoch at Cursor: %s, ep %d",
				      MakeFriendlyDate(1, day, mo, yr), (int)curEp) ;
		 SetWindowText(hWndView, date) ;
		 ep = eptemp ;

	return curEp ;
	}

/*****************************************************************
			Get a Date/epoch by Mouse Move in a Graph
 *****************************************************************/
double PickMseDate(
		  int xmouse,		// client mouse x position
		 char date[]		// friendly date corresponding to curEp
		)
	{
		 double eptemp, curEp ;

		 // convert mouse X-position to corresponding julian date
		 eptemp = ep ;
		 ep = xp2ep(xmouse) ;
		 curEp = ep ;
		 civildate() ;
	     MousedEp = curEp ;
		 sprintf(date, "Epoch at Cursor: %s, ep %d",
				      MakeFriendlyDate(1, day, mo, yr), (int)curEp) ;
		 SetWindowText(hWndView, date) ;
		 ep = eptemp ;


	return curEp ;
	}


/********************************************************/
/* Inverse Tangent                                      */
/********************************************************/
double itan( double num, double den)
// Inverse tangent, returning
// angle in correct quadrant
{
   double a, r ;
	if ( den == 0.0 )
	 { if ( num < 0 ) r = ( 3.0*pi/2.0 ) ; else r = ( pi/2.0 ) ; }
	 else
	 { a = atan( num/den) ; if ( den < 0.0 ) r =  a + pi  ;
	 else
	 { if ( num < 0.0 ) r = a + twopi ; else r = a ; } }
	 return ( r ) ;
}

/******************
   Inverse Cosine
 ******************/
double arccos( double x )
{
	if (fabs(x) == 1.0)
	{
		if (x > 0.0)
		    return 0.0 ;
		else
			return -pi ;
	}

   return pi / 2.0 - atan(x / sqrt(fabs(1.0 - x*x))) ;
}

double adiff( double newa, double olda)
// Returns angular difference, new - old;
// avoid zero-crossing problems by setting the zero 
// reference to the old value, and using cartesian rotation.
{
  double x, y, cs, sn ;
  
   x = cos(newa) ;  y = sin(newa) ;
  cs = cos(olda) ; sn = sin(olda) ;

  return atan2((y*cs - x*sn), (x*cs + y*sn)) ; // -pi <= angle <= pi
}

double adiff2( double newa, double olda)
// Returns angular difference, new - old;
// avoid zero-crossing problems by setting the zero 
// reference to the old value, and using cartesian rotation.
{
  double x, y, cs, sn ;
  
   x = cos(newa) ;  y = sin(newa) ;
  cs = cos(olda) ; sn = sin(olda) ;

  return itan((y*cs - x*sn), (x*cs + y*sn)) ; // 0 <= angle <= twopi
}

double ajx(double x, SYSTEMIC S)
{
	return (x - S.x_on_Sun[ViewCentre]) ;
}

double ajy(double y, SYSTEMIC S)
{
	return (y - S.y_on_Sun[ViewCentre]) ;
}

void Connect(HDC hdc, int x1, int y1, int x2, int y2)
{
		   MoveToEx(hdc, x1, y1, NULL) ;
		     LineTo(hdc, x2, y2) ;
}

void Polar(HDC hdc, int Body, int xc, int yc, int unit, double fr, HPEN Pen, SYSTEMIC S)
		{
				HPEN oPen ;
			  static p, xb, yb ;
			  double ph, x, y, h, cs, sn, a, b ;
			  double n, al, sum ;

				oPen = SelectObject(hdc, Pen) ;

				 x = S.x_on_Sun[Body] ;
				 y = S.y_on_Sun[Body] ;

			for (ph = 0.0 ; ph < twopi ; ph += twopi / polarst)
			{
			  for (p = EAR, sum = n = 0.0 ; p <= SUN ; p++)
			  {
				  if (p == PLU || p == Body|| !BodyList[p]) continue ;
				  sum += pow(cos(S.Pair[Body][p] - ph), 2.0) ;
				  n++ ;
			  }

			  al = sum / n ;
			   h = 5.0 * al ;
			  cs = cos(ph) ;
			  sn = sin(ph) ;
			   a = h * cs ;
			   b = h * sn ;

			  xb = xc + (int)(unit * ajx(x + a, S) / fr ) ;
			  yb = yc - (int)(unit * ajy(y + b, S) / fr ) ;

			if (ph == 0.0)
		    MoveToEx(hdc, xb, yb, NULL) ; // plot polar diagram
			else
		      LineTo(hdc, xb, yb) ;
			}
			SelectObject(hdc, oPen) ;
		}

void bSysDirection(HDC hdc, int Body, int xc, int yc, int unit, double fr, HPEN Pen, SYSTEMIC S)
	{
		HPEN oPen ;
		double x, y, h, cs, sn, a, b ;
		int xu1, yu1, xu2, yu2 ;
	 static oxu1, oyu1, oxu2, oyu2, done ;

				oPen = SelectObject(hdc, Pen) ;
				cs = cos(S.bSysDir[Body]) ;
				sn = sin(S.bSysDir[Body]) ;
				 x = S.x_on_Sun[Body] ;
				 y = S.y_on_Sun[Body] ;
				 h = 10.0 * fr ;
				 a = h * cs ;
				 b = h * sn ;

			xu1 = xc + (int)(unit * ajx(x + a, S) / fr) ;
			yu1 = yc - (int)(unit * ajy(y + b, S) / fr) ;
			xu2 = xc + (int)(unit * ajx(x - a, S) / fr) ;
			yu2 = yc - (int)(unit * ajy(y - b, S) / fr) ;
		    Connect(hdc, xu1, yu1, xu2, yu2) ;
		    oxu1 = xu1 ; oyu1 = yu1 ;  oxu2 = xu2 ; oyu2 = yu2 ;  done = 1 ;
			SelectObject(hdc, oPen) ;
	}

/****
void bSysDispersion(HDC hdc, int p, int xc, int yc, int unit, double fr, HPEN Pen)		
		{
			HPEN oPen ;
			double u, h, x, y, a, b, cs, sn ;
			   int xu1, yu1, xu2, yu2 ;

				oPen = SelectObject(hdc, Pen) ;

				 a = Sy.bSysDir[p] ;
				 b = Sy.bSysDsp[p]/2.0 ;

				 x = Sy.x_on_Sun[p] ;
				 y = Sy.y_on_Sun[p] ;

				 h = 0.5 * fr ;

				cs = cos(u = a + b) ;
				sn = sin(u ) ;

			xu1 = xc + (int)(unit * ajx( x + h * cs) / fr ) ;
			yu1 = yc - (int)(unit * ajy( y + h * sn) / fr ) ;
			xu2 = xc + (int)(unit * ajx( x - h * cs) / fr ) ;
			yu2 = yc - (int)(unit * ajy( y - h * sn) / fr ) ;

			// systemic direction
			// plus Half Dispersion
		    Connect(hdc, xu1, yu1, xu2, yu2) ;

				cs = cos(u = a - b) ;
				sn = sin(u) ;

			xu1 = xc + (int)(unit * ajx( x + h * cs) / fr ) ;
			yu1 = yc - (int)(unit * ajy( y + h * sn) / fr ) ;
			xu2 = xc + (int)(unit * ajx( x - h * cs) / fr ) ;
			yu2 = yc - (int)(unit * ajy( y - h * sn) / fr ) ;

			// systemic direction
			// minus Half Dispersion
		    Connect(hdc, xu1, yu1, xu2, yu2) ;

			SelectObject(hdc, oPen) ;
		}
***/
/**************************************************
 Get the path of a file
 **************************************************/
char * FetchPath(char * fn)
{
	int i, j, len ;
	static char path[255] ;

	len = strlen(fn) ;

	// find all the backslashes

	for (i = 0, j = 0 ; i < len ; i++)
	{
		if (fn[i] == '\\') j = i ;	// get index of most recently found backslash
	}

// copy all chars up to and including the most recently found backslash

   strncpy(path, fn, j+1) ; // num of chars is one more than index

   path[j+1] = '\0' ;       // append zero
   
   return path ;
}


VOID DiscardImage (VOID)
// delete/free global palette, and dib, as necessary.
{

	if (hpal) {
		DeleteObject(hpal);
		hpal = NULL;
	}
	if (hDib) {
		TWAIN_FreeNative(hDib);
		hDib = NULL;
	}
} // DiscardImage

//*************************************************************
//	   Running Mean of M over a sequence of N values.
//*************************************************************
int RunningMean(
				     int   N,	  // the # of data points 
				     int   M,	  // the range of the moving mean
			   LPFOURIER   F	  // structure with the data
			   )
{
	static h, start, stop ;
	static j, k ;


	 if (M < 0 || N <= 0) return 0 ; // return zero on silly requests

	while (M < 3)  M++ ;   // bring M up to 3 if M is at least zero
	 if (!(M % 2)) M++ ;   // span must be an odd integer >= 3

	 if (M > N) return 0 ; // if oddizing puts us past the end

	h = M / 2 ;      // half-span, rounded down

		// ****** IMPLEMENTATION NOTES ************
		//
		// The bud indices start at zero!!!!
		//
		// For argument, let N = 11, M = 5.
		// Then halfM = 2. If j < halfM = 2,
		// then start should be 0, stop should
		// be two greater than j, i.e., j + halfM.
		//
		// If j > N - (halfM + 1), in this case 11 - 3 = 8,
		// then start should be	two less than j,
		// i.e., j - halfM, and stop should be (N - 1).
		//
		// Else start = j - halfM, stop = j + halfM.
		//
		// Start and stop are _included_ indices.
		//
		// The divisor is always (stop - start + 1).

	for (j = 0 ; j < N ; j++)
	{
		
		F->mdata[j] = 0.0 ;	 // Begin with the j'th result = 0

	if (j < h) // we're at the leading end of the data
		{ start = 0 ; stop = (j + h) ; }

	if (j > (N - (h + 1))) // we're at the trailing end of the data
		{ start = (j - h) ; stop = (N - 1) ; }

	if (j >= h && j <= (N - (h + 1))) // we're in the body
		{ start = (j - h) ; stop = (j + h) ; }


	  for (
           k = start ; k <= stop ; k++
		  ) F->mdata[j] += F->data[k] ;

	       F->mdata[j] /= (double)(stop - start + 1) ; 
	}

         return 1 ;
}

//*************************************************************
//	   Running Mean of M over a sequence of N values.
//*************************************************************
int rm(
				     int   N,	  // the # of data points 
				     int   M,	  // the range of the moving mean
			        double * s,	  // pointer to source array
					double * d	  // pointer to destination array
			   )
{
	static h, start, stop ;
	static j, k ;


	 if (M < 0 || N <= 0) return 0 ; // return zero on silly requests

	while (M < 3)  M++ ;   // bring M up to 3 if M is at least zero
	 if (!(M % 2)) M++ ;   // span must be an odd integer >= 3

	 if (M > N) return 0 ; // if oddizing puts us past the end

	h = M / 2 ;      // half-span, rounded down

		// ****** IMPLEMENTATION NOTES *******
		//
		// The bud indices start at zero!!!!
		//
		// For argument, let N = 11, M = 5.
		// Then halfM = 2. If j < halfM = 2,
		// then start should be 0, stop should
		// be two greater than j, i.e., j + halfM.
		//
		// If j > N - (halfM + 1), in this case 11 - 3 = 8,
		// then start should be	two less than j,
		// i.e., j - halfM, and stop should be (N - 1).
		//
		// Else start = j - halfM, stop = j + halfM.
		//
		// Start and stop are _included_ indices.
		//
		// The divisor is always (stop - start + 1).

	for (j = 0 ; j < N ; j++)
	{
		
		d[j] = 0.0 ;	 // Begin with the j'th result = 0

	if (j < h) // we're at the leading end of the data
		{ start = 0 ; stop = (j + h) ; }

	if (j > (N - (h + 1))) // we're at the trailing end of the data
		{ start = (j - h) ; stop = (N - 1) ; }

	if (j >= h && j <= (N - (h + 1))) // we're in the body
		{ start = (j - h) ; stop = (j + h) ; }


	  for (
           k = start ; k <= stop ; k++
		  ) d[j] += s[k] ;

	       d[j] /= (double)(stop - start + 1) ; 
	}

         return 1 ;
}


// Creating a Tool Bar
HWND CreateAToolBar(HWND hwndParent) 
	{ 
	                HWND hwndTB; 
	  static TBADDBITMAP tbab; 
      static    TBBUTTON tbb[5];
 
    // Create a toolbar that has a 
    // tooltip associated with it.
	  
    hwndTB = CreateWindowEx
		(
		 0,
		 TOOLBARCLASSNAME,
		 (LPSTR) NULL, 
         WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE | CCS_TOP, 
         0, 0, 0, 0,
		 hwndParent,
		 (HMENU)IDR_TOOLBAR1,
		 hInst,
		 NULL
		);
	

    // Send the TB_BUTTONSTRUCTSIZE message, which is required for 
    // backward compatibility. 
    SendMessage(hwndTB, TB_BUTTONSTRUCTSIZE, 
        (WPARAM) sizeof(TBBUTTON), 0);
	
	SendMessage(hwndTB, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(16, 15)) ;
 
    // Add the bitmap containing button images to the toolbar. 
    tbab.hInst = hInst; 
    tbab.nID   = IDR_TOOLBAR1; 
    SendMessage(hwndTB, TB_ADDBITMAP, (WPARAM) NUM_BUTTON_BITMAPS, 
        (LPARAM)(LPTBADDBITMAP) &tbab); 
 /*
    // Add the button strings to the toolbar. 
    LoadString(hInst, IDS_CUT, (LPSTR) &szBuf, MAX_LEN); 
    iCut = SendMessage(hwndTB, TB_ADDSTRING, 0, (LPARAM) (LPSTR) szBuf); 
 
    LoadString(hInst, IDS_COPY, (LPSTR) &szBuf, MAX_LEN); 
    iCopy = SendMessage(hwndTB, TB_ADDSTRING, (WPARAM) 0, 
        (LPARAM) (LPSTR) szBuf); 
 
    LoadString(hInst, IDS_PASTE, (LPSTR) &szBuf, MAX_LEN); 
    iPaste = SendMessage(hwndTB, TB_ADDSTRING, (WPARAM) 0, 
        (LPARAM) (LPSTR) szBuf); 
*/
	

    // Fill the TBBUTTON array with button information, and add the 
    // buttons to the toolbar. 
    tbb[0].iBitmap   = 0 ; 
    tbb[0].idCommand = IDM_TB1 ; 
    tbb[0].fsState   = TBSTATE_ENABLED ; 
    tbb[0].fsStyle   = TBSTYLE_BUTTON ; 
    tbb[0].dwData    = 0; 
    tbb[0].iString   = 0 ; 
 
    tbb[1].iBitmap   = 1 ; 
    tbb[1].idCommand = IDM_TB2; 
    tbb[1].fsState   = TBSTATE_ENABLED ; 
    tbb[1].fsStyle   = TBSTYLE_BUTTON ; 
    tbb[1].dwData    = 0; 
    tbb[1].iString   = 1 ; 

    tbb[2].iBitmap   = 2; 
    tbb[2].idCommand = IDM_TB3; 
    tbb[2].fsState   = TBSTATE_ENABLED; 
    tbb[2].fsStyle   = TBSTYLE_BUTTON; 
    tbb[2].dwData    = 0; 
    tbb[2].iString   = 2; 
 
    tbb[3].iBitmap   = 3; 
    tbb[3].idCommand = IDM_TB4; 
    tbb[3].fsState   = TBSTATE_ENABLED; 
    tbb[3].fsStyle   = TBSTYLE_BUTTON; 
    tbb[3].dwData    = 0; 
    tbb[3].iString   = 3; 
 
    tbb[4].iBitmap   = 4; 
    tbb[4].idCommand = IDM_TB5; 
    tbb[4].fsState   = TBSTATE_ENABLED; 
    tbb[4].fsStyle   = TBSTYLE_BUTTON; 
    tbb[4].dwData    = 0; 
    tbb[4].iString   = 4; 
 
    SendMessage(hwndTB, TB_ADDBUTTONS, (WPARAM) NUM_BUTTONS, 
        (LPARAM) (LPTBBUTTON) &tbb); 
 
    SendMessage(hwndTB, TB_AUTOSIZE, 0, 0); 

    ShowWindow(hwndTB, SW_SHOW);
    return hwndTB; 
	}
 
/****
// first look at Property Sheets

int CreatePropertySheet(HWND hwndOwner)
{
    PROPSHEETPAGE psp[2];
    PROPSHEETHEADER psh;

    psp[0].dwSize = sizeof(PROPSHEETPAGE);
    psp[0].dwFlags = PSP_USETITLE;
    psp[0].hInstance = hInst;
    psp[0].pszTemplate = MAKEINTRESOURCE(IDD_RANGE);
    psp[0].pszIcon = NULL;
    psp[0].pfnDlgProc = Range;
    psp[0].pszTitle = "Slider Range";
    psp[0].lParam = 0;

    psp[1].dwSize = sizeof(PROPSHEETPAGE);
    psp[1].dwFlags = PSP_USETITLE;
    psp[1].hInstance = hInst;
    psp[1].pszTemplate = MAKEINTRESOURCE(IDD_PROPS);
    psp[1].pszIcon = NULL;
    psp[1].pfnDlgProc = PageSize;
    psp[1].pszTitle = "Slider Page and Line Size";
    psp[1].lParam = 0;
    
    psh.dwSize = sizeof(PROPSHEETHEADER);
    psh.dwFlags = PSH_PROPSHEETPAGE;
    psh.hwndParent = hwndOwner;
    psh.hInstance = hInst;
    psh.pszIcon = NULL;
    psh.pszCaption = (LPSTR) "Slider Properties";
    psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE);
    psh.ppsp = (LPCPROPSHEETPAGE) &psp;

    return (PropertySheet(&psh));
}


BOOL APIENTRY Range(
    HWND hDlg,
    UINT message,
    UINT wParam,
    LONG lParam)
{
    static PROPSHEETPAGE * ps;
    BOOL bErr;
    static UINT uMin, uMax, uMinSave, uMaxSave;

    switch (message)
    {
        case WM_INITDIALOG:    
            // Save the PROPSHEETPAGE information.
            ps = (PROPSHEETPAGE *)lParam;
            return (TRUE);

        case WM_NOTIFY:
            switch (((NMHDR FAR *) lParam)->code) 
            {

                case PSN_SETACTIVE:
                    // Initialize the controls.
                    uMinSave = SendMessage( hWndSlider, TBM_GETRANGEMIN, 0L,
                        0L);
                    uMaxSave = SendMessage( hWndSlider, TBM_GETRANGEMAX, 0L, 
                        0L);
                    SetDlgItemInt(hDlg, IDE_MIN, uMinSave, TRUE);
                    SetDlgItemInt(hDlg, IDE_MAX, uMaxSave, TRUE);
                    break;

                case PSN_APPLY:
                    uMin = GetDlgItemInt(hDlg, IDE_MIN, &bErr, TRUE);
                    uMax = GetDlgItemInt(hDlg, IDE_MAX, &bErr, TRUE);
                    SendMessage( hWndSlider, TBM_SETRANGE, TRUE, 
                        MAKELONG(uMin, uMax));
                    SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
                    break;

                case PSN_KILLACTIVE:
                    SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
                    return 1;
                    break;

                case PSN_RESET:
                    // Reset to the original values.
                    SendMessage( hWndSlider, TBM_SETRANGE, TRUE, 
                        MAKELONG(uMinSave, uMaxSave));
                    SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
                    break;
        }
    }
    return (FALSE);
}
*****/

#include "BudTip.h"          // the tip routines
#include "BudUpDownCtrls.h"	 // up/down control routines
#include "BudProts.h"		 // the prototypes
#include "Archiving.h"		 // Archiving and Tree View routines

