/*
 * wmSunMoon 2.0.0 (C) 2014-2015 Cezary M. Kruk <c.kruk@bigfoot.com>
 *
 * Displays Sun and Moon rise and set times
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 *   Includes
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include <regex.h>
#include "CalcEphem.h"

#include <X11/Xlib.h>
#include <X11/xpm.h>
#include <X11/extensions/shape.h>
#include "../wmgeneral/wmgeneral.h"
#include "wmSunMoon.xpm"
#include "wmSunMoonMono.xpm"

/*
 *  Delay between refreshes (in microseconds)
 */
#define DELAY 125000L
#define WMSUNMOON_VERSION "2.0.0"
#define WMSUNMOON_REVDATE "2015-04-02"
#define WMSUNMOON_REVYEAR "2014-2015"

#define DegPerRad       57.29577951308232087680
#define RadPerDeg        0.01745329251994329576

void	ParseCMDLine(int argc, char *argv[]);
void	PrintHelp();

double 	Glat, Glon, SinGlat, CosGlat, TimeZone, UserTimeDiff;
char	*LocalTimeZone, *DistTimeZone;
int	UseUserTimeDiff = 0;
int	UseTimeZone = 0;
int	UseUserDate = 0;
long	UserDate;

char	wmSunMoon_mask_bits[64*64];
int	wmSunMoon_mask_width = 64;
int	wmSunMoon_mask_height = 64;

XpmColorSymbol colors[1] = {{NULL, NULL, 0}};

int	ToggleWindow = 0;
int	OpenWindow = 1;
int	SunMoonType = 0;
int	Percentage = 0;
int	TimeString = 0;
int	TwilString = 0;
int	GoldString = 0;
int	Reverse = 0;
int	Clean = 0;
int	ForceSun = 0;
int	ForceMoon = 0;
int	Mono = 0;
int	TextMode = 0;

/*
 *   Main
 */
int main(int argc, char *argv[]) {

	struct tm	*GMTTime, *LocalTime;
	XEvent		Event;
	int		but_stat = -1;
	int		i, n, k, j, ImageNumber;
	int		Year, Month, DayOfWeek, DayOfMonth;
	int		tempYear, tempMonth, tempDayOfMonth;
	int		Hours, Mins, Secs, digit, xoff, xsize;
	long		CurrentLocalTime, CurrentGMTTime, date, tempdate;
	double		UT, val, RA, DEC, LTRise, LTSet, CTBeg, CTEnd, GHBeg, GHEnd, UTRise, UTSet, LocalHour, hour24();
	int		D, H, M, S, sgn, A, a, B, b, q;
	char		*sign = "";
	char		str[10];
	int		LocalDayOfMonth, OldHours, OldMins;
	CTrans		c;

	char		HourMinute[80];
	int		AssumeDay = -1;
	int		Twilight = -1;
	int		Golden = -1;
	double		UserTimeDiffInt = 0;
	double		UserTimeDiffDec = 0;
	int		counter = 0;
	int		counter_updated = 0;

	int		HH, MM, HTB, MTB, HGB, MGB, HR, MR, HS, MS, HTE, MTE, HGE, MGE, HG, MG, HT, MT, HU, MU;
	int		TheTime, Dawn, Rise, MornGH, EvenGH, Set, Dusk, DayLength, NightLength;
	int		DawnDur, DuskDur, MGHDur, EGHDur;
	int		Font;
	int		Loop = 0;

	long		savedate;
	int		LocalDate;
	char		TZLocAbbr[10];
	char		TZDistAbbr[10];
	int		UniversalDate;
	int		DateDiff = 0;

	char		*moonphase;

	/*
	 *  Parse any command line arguments.
	 */
	Glat = Glon = 0.0;
	ParseCMDLine(argc, argv);
	c.Glat = Glat, c.Glon = Glon;
	Glat *= RadPerDeg; SinGlat = sin( Glat ); CosGlat = cos( Glat );

	/*
	 *  Loop until we die
	 */
	Hours = -999;
	OldHours = -999;
	OldMins = -999;

	while(1) {

		CurrentGMTTime = time(CurrentTime);
		GMTTime = gmtime(&CurrentGMTTime);
		UT = GMTTime->tm_hour + GMTTime->tm_min/60.0 + GMTTime->tm_sec/3600.0;
		Year = GMTTime->tm_year+1900;
		Month = GMTTime->tm_mon+1;
		DayOfMonth = GMTTime->tm_mday;

		time_t lt;

		lt = time(0);
		struct tm *LTime = localtime(&lt);
		char LD[64];
		strftime(LD, sizeof(LD), "%Y%m%d", LTime);
		LocalDate = atoi(LD);
		strftime(TZLocAbbr, sizeof(TZLocAbbr), "%Z", LTime);

		if (UseTimeZone == 1) {
			time_t dt;
			int DistDate, DistHour, DistTzone;

			savedate = Year*10000 + Month*100 + DayOfMonth;

			setenv("TZ", LocalTimeZone, 1);
			tzset();

			strftime(TZLocAbbr, sizeof(TZLocAbbr), "%Z", LTime);

			setenv("TZ", DistTimeZone, 1);
			tzset();

			dt = time(0);
			struct tm *DTime = localtime(&dt);
			char DD[64];
			char DH[64];
			char DZ[64];
			strftime(DD, sizeof(DD), "%Y%m%d", DTime);
			strftime(DZ, sizeof(DZ), "%z", DTime);
			strftime(TZDistAbbr, sizeof(TZDistAbbr), "%Z", LTime);
			DistDate = atoi(DD);
			DistTzone = atoi(DZ);

			regex_t regex;
			int reti;
			char msgbuf[100];

			reti = regcomp(&regex, "^[A-Zh]+$", REG_EXTENDED);
			if (reti) {
				fprintf(stderr, "wmSunMoon: can not compile regex.\n");
				exit(1);
			}

			reti = regexec(&regex, TZLocAbbr, 0, NULL, 0);

			if (reti == REG_NOMATCH) {
				printf("wmSunMoon: invalid local time zone name.\n");
				exit(1);
			}

			reti = regexec(&regex, TZDistAbbr, 0, NULL, 0);

			if (reti == REG_NOMATCH) {
				printf("wmSunMoon: invalid distant time zone name.\n");
				exit(1);
			}

			setenv("TZ", LocalTimeZone, 1);
			tzset();

			double HourDiff, MinDiff;
			DateDiff = DistDate - LocalDate;
			HourDiff = (DistTzone / 100);
			MinDiff = 100 * (DistTzone - HourDiff * 100) / 60;
			UserTimeDiff = HourDiff + MinDiff / 100;
			UserTimeDiff = -1 * UserTimeDiff;

			UserDate = DistDate;
			UseUserDate = 1;
			UseUserTimeDiff = 1;
		}

		if (UseUserDate) {
			date = UserDate;
			Year = date/10000;
			date -= Year*10000;
			Month = date/100;
			date -= Month*100;
			DayOfMonth = date;
			date = UserDate;
		} else {
			date = Year*10000 + Month*100 + DayOfMonth;
		}

		CurrentLocalTime = CurrentGMTTime;
		LocalTime = localtime(&CurrentLocalTime);
		LocalHour = LocalTime->tm_hour + LocalTime->tm_min/60.0 + LocalTime->tm_sec/3600.0;
		TimeZone = UT - LocalHour;

		if (UseUserTimeDiff == 1) {
			TimeZone = (UseUserTimeDiff) ? UserTimeDiff : UT - LocalHour;
		}
		LocalDayOfMonth = LocalTime->tm_mday;
		Mins = LocalTime->tm_min;
		Secs = LocalTime->tm_sec;

		if (UseUserTimeDiff == 1) {
			val = UT;
			HH = (int)val; val = (val-HH)*60.0;
			MM = (int)val;
			HH = HH - UserTimeDiff;
			UserTimeDiffInt = (int)UserTimeDiff;
			UserTimeDiffDec = UserTimeDiff - UserTimeDiffInt;
			UserTimeDiffDec = UserTimeDiffDec * 60;
			MM = MM - UserTimeDiffDec;
		} else {
			val = LocalHour;
			HH = (int)val; val = (val-HH)*60.0;
			MM = (int)val;
		}

		if ((Secs == 3) || (Secs == 7) || (Secs == 11) || (Secs == 15) || (Secs == 19) || (Secs == 23) || (Secs == 27) || (Secs == 31) || (Secs == 35) || (Secs == 39) || (Secs == 43) || (Secs == 47) || (Secs == 51) || (Secs == 55) || (Secs == 59)) {
			if (counter_updated == 0) {
				counter = 0;
				counter_updated = 1;
			}
		} else {
			counter_updated = 0;
		}

		counter = counter + 1;

		if (counter > 17) {
			counter = -17;
		}

		if (MM < 60) {
		    MM = MM + 60;
		    HH = HH - 1;
		}
		if (MM >= 60) {
		    MM = MM - 60;
		    HH = HH + 1;
		}
		if (HH < 0) {
		    HH = HH + 24;
		}
		if (HH >= 24) {
		    HH = HH - 24;
		}

		TheTime = 60 * HH + MM;

		val = UT;
		HU = (int)val; val = (val-HU)*60.0;
		MU = (int)val;

		Loop = Loop - 1;

		if (OldMins != Mins) {

			if (UseTimeZone == 1) {
				CalcEphem(savedate, UT, &c);
			} else {
				CalcEphem(date, UT, &c);
			}
			OldMins = Mins;

			/*
			 *  Compute Sun Rise/Set Times in Local Time
			 */
			SunRise(Year, Month, DayOfMonth, LocalHour, &LTRise, &LTSet);

			val = LTRise;
			HR = (int)val; val = (val-HR)*60.0;
			MR = (int)val;

			Rise = 60 * HR + MR;

			val = LTSet;
			HS = (int)val; val = (val-HS)*60.0;
			MS = (int)val;

			Set = 60 * HS + MS;

			if (Set > Rise) {
				DayLength = Set - Rise;
			} else if (Set < Rise) {
				DayLength = Rise - Set;
				DayLength = 1440 - DayLength;
			}
			NightLength = 1440 - DayLength;

			if ((TheTime >= Rise) && (TheTime < Set)) {
				/*
				 *  Day
				 */
				AssumeDay = 1;
			} else {
				/*
				 *  Night
				 */
				AssumeDay = 0;
			}

			/*
			 *  Compute Civil Twilight Beginning/End Times in Local Time
			 */
			CivTwil(Year, Month, DayOfMonth, LocalHour, &CTBeg, &CTEnd);

			val = CTBeg;
			HTB = (int)val; val = (val-HTB)*60.0;
			MTB = (int)val;

			Dawn = 60 * HTB  + MTB;

			val = CTEnd;
			HTE = (int)val; val = (val-HTE)*60.0;
			MTE = (int)val;

			Dusk = 60 * HTE + MTE;

			DawnDur = Rise - Dawn;
			DuskDur = Dusk - Set;

			Twilight = (DawnDur + DuskDur) / 2;
			HT = Twilight/60;
			MT = Twilight - HT*60;

			/*
			 *  Compute Golden Hour Beginning/End Times in Local Time
			 */
			GoldHour(Year, Month, DayOfMonth, LocalHour, &GHBeg, &GHEnd);

			val = GHBeg;
			HGB = (int)val; val = (val-HGB)*60.0;
			MGB = (int)val;

			MornGH = 60 * HGB  + MGB;

			val = GHEnd;
			HGE = (int)val; val = (val-HGE)*60.0;
			MGE = (int)val;

			EvenGH = 60 * HGE + MGE;

			MGHDur = MornGH - Rise;
			EGHDur = Set - EvenGH;

			Golden = (MGHDur + EGHDur) / 2;
			HG = Golden/60;
			MG = Golden - HG*60;

			/*
			 *  Compute Moon Rise/Set Times in Local Time
			 */
			MoonRise(Year, Month, DayOfMonth, LocalHour, &UTRise, &UTSet);

		}

		if ((Glat >= 1.147118) || (Glat <= -1.147118)) {
				if (
				(TheTime >= Rise) && (TheTime < Set) ||
				(TheTime >= Rise) && (Rise > Set) ||
				(Rise == -60) && (Set == -60)
				)
				{
					AssumeDay = 1;
					if ((Rise == -60) && (Set == -60)) {
						DayLength = 1440;
						NightLength = 0;
					}
				} else {
					AssumeDay = 0;
					if ((Rise == -59940) && (Set == -59940)) {
						DayLength = 0;
						NightLength = 1440;
					}
				}
		}

		if (TextMode == 1) {
			printf("                       latitude: %f\n", c.Glat);
			printf("                      longitude: %f\n\n", c.Glon);
			if (UseTimeZone == 1) {
				printf("                local time zone: %s\t%s\n", TZLocAbbr, LocalTimeZone);
				printf("              distant time zone: %s\t%s\n\n", TZDistAbbr, DistTimeZone);
			} else {
				printf("                local time zone: %s\n\n", TZLocAbbr);
			}
			strftime (HourMinute,80,"%H%M",LocalTime);
			printf("                     local time: %d%d:%d%d\n", HourMinute[0] - '0', HourMinute[1] - '0', HourMinute[2] - '0', HourMinute[3] - '0');
			tempdate = LocalDate;
			tempYear = tempdate/10000;
			tempdate -= tempYear*10000;
			tempMonth = tempdate/100;
			tempdate -= tempMonth*100;
			tempDayOfMonth = tempdate;
			printf("                     local date: %d/%d%d/%d%d\n", tempYear, tempMonth/10, tempMonth%10, tempDayOfMonth/10, tempDayOfMonth%10);
			if (UseUserTimeDiff == 1) {
				if (DateDiff > 0) {
					sign=" +";
				} else if (DateDiff == 0) {
					sign="";
				} else if (DateDiff < 0) {
					sign=" -";
				}
				printf("                   distant time: %d%d:%d%d     %s\n", HH/10, HH%10, MM/10, MM%10, sign);
				tempdate = UserDate;
				tempYear = tempdate/10000;
				tempdate -= tempYear*10000;
				tempMonth = tempdate/100;
				tempdate -= tempMonth*100;
				tempDayOfMonth = tempdate;
				printf("                   distant date: %d/%d%d/%d%d%s\n", tempYear, tempMonth/10, tempMonth%10, tempDayOfMonth/10, tempDayOfMonth%10, sign);
			}
			time_t ut;
			setenv("TZ", "GMT", 1);
			tzset();
			ut = time(0);
			struct tm *UTime = localtime(&ut);
			char UD[64];
			strftime(UD, sizeof(UD), "%Y%m%d", UTime);
			UniversalDate = atoi(UD);
			if (UniversalDate > LocalDate) {
				sign=" +";
			} else if (UniversalDate == LocalDate) {
				sign="";
			} else if (UniversalDate < LocalDate) {
				sign=" -";
			}
			printf("                 universal time: %d%d:%d%d     %s\n", HU/10, HU%10, MU/10, MU%10, sign);
			tempdate = UniversalDate;
			tempYear = tempdate/10000;
			tempdate -= tempYear*10000;
			tempMonth = tempdate/100;
			tempdate -= tempMonth*100;
			tempDayOfMonth = tempdate;
			printf("                 universal date: %d/%d%d/%d%d%s\n", tempYear, tempMonth/10, tempMonth%10, tempDayOfMonth/10, tempDayOfMonth%10, sign);
			printf("               time zone offset: %f\n\n", TimeZone);
			if ((HTB < 0)  || (MTB < 0)) {
				printf("          civil twilight begins: --:--\n");
			} else {
				printf("          civil twilight begins: %d%d:%d%d\n", HTB/10, HTB%10, MTB/10, MTB%10);
			}
			if ((HR < 0)  || (MR < 0)) {
				printf("                        sunrise: --:--\n");
			} else {
				printf("                        sunrise: %d%d:%d%d\n", HR/10, HR%10, MR/10, MR%10);
			}
			val = MornGH;
			A = (int)val/60;
			val = val - A*60.0;
			B = (int)val;
			if ((A < 0)  || (B < 0)) {
				printf("       morning golden hour ends: --:--\n");
			} else {
				printf("       morning golden hour ends: %d%d:%d%d\n", A/10, A%10, B/10, B%10);
			}
			val = EvenGH;
			A = (int)val/60;
			val = val - A*60.0;
			B = (int)val;
			if ((A < 0)  || (B < 0)) {
				printf("     evening golden hour begins: --:--\n");
			} else {
				printf("     evening golden hour begins: %d%d:%d%d\n", A/10, A%10, B/10, B%10);
			}
			if ((HS < 0)  || (MS < 0)) {
				printf("                         sunset: --:--\n");
			} else {
				printf("                         sunset: %d%d:%d%d\n", HS/10, HS%10, MS/10, MS%10);
			}
			if ((HTE < 0)  || (MTE < 0)) {
				printf("            civil twilight ends: --:--\n\n");
			} else {
				printf("            civil twilight ends: %d%d:%d%d\n\n", HTE/10, HTE%10, MTE/10, MTE%10);
			}
			if (AssumeDay == 1) {
				printf("             is it day or night: day\n");
				if ((Glat < 1.147118) && (Glat > -1.147118)) {
					if ((TheTime >= Rise) && (TheTime < MornGH)) {
						printf("              is it golden hour: morning golden hour\n");
					} else if ((TheTime >= EvenGH) && (TheTime < Set)) {
						printf("              is it golden hour: evening golden hour\n");
					} else {
						printf("              is it golden hour: it is not\n");
					}
				}
			} else {
				printf("             is it day or night: night\n");
				if ((Glat < 1.147118) && (Glat > -1.147118)) {
					if ((TheTime >= Dawn) && (TheTime < Rise)) {
						printf("           is it civil twilight: morning civil twilight\n");
					} else if ((TheTime >= Set) && (TheTime < Dusk)) {
						printf("           is it civil twilight: evening civil twilight\n");
					} else {
						printf("           is it civil twilight: it is not\n");
					}
				}
			}
			if (UseUserTimeDiff == 1) {
				if (DateDiff > 0) {
					printf("                    is it today: tomorrow\n");
				} else if (DateDiff == 0) {
					printf("                    is it today: today\n");
				} else if (DateDiff < 0) {
					printf("                    is it today: yesterday\n");
				}
			}
			if ((HT >= 0) && (MT >= 0)) {
				printf("          civil twilight offset: ±%d%d:%d%d\n", HT/10, HT%10, MT/10, MT%10);
			} else {
				printf("          civil twilight offset: ±--:--\n");
			}
			if ((HG >= 0) && (MG >= 0)) {
				printf("             golden hour offset: ±%d%d:%d%d\n\n", HG/10, HG%10, MG/10, MG%10);
			} else {
				printf("             golden hour offset: ±--:--\n\n");
			}
			val = DayLength;
			A = (int)val/60;
			val = val - A*60.0;
			a = (int)val;
			val = NightLength;
			B = (int)val/60;
			val = val - B*60.0;
			b = (int)val;
			printf("           day and night length: %d%d:%d%d / %d%d:%d%d\n\n", A/10, A%10, a/10, a%10, B/10, B%10, b/10, b%10);
			val = c.MoonAge;
			A = (int)val;
			val = (val - A)*100.0;
			B = (int)val;
			printf("               moon age in days: %d.%d%d days\n", A, B/10, B%10);
			A = (int)(c.MoonPhase * 10000.0 + 0.5);
			B = A/100;
			B = A - B*100;
			a = (int)(c.MoonPhase * 100.0 + 0.5);
			printf("            moon cycle fraction: %d.%d%d%%\t(%d%%)\n", A/100, B/10, B%10, a);
			if (c.MoonPhase < 0 + 0.0625) {
				moonphase="new moon";
			} else if (c.MoonPhase < 0.125 + 0.0625) {
				moonphase="waxing crescent";
			} else if (c.MoonPhase < 0.25 + 0.0625) {
				moonphase="1st quarter";
			} else if (c.MoonPhase < 0.375 + 0.0625) {
				moonphase="waxing gibbous";
			} else if (c.MoonPhase < 0.5 + 0.0625) {
				moonphase="full moon";
			} else if (c.MoonPhase < 0.625 + 0.0625) {
				moonphase="waning gibbous";
			} else if (c.MoonPhase < 0.75 + 0.0625) {
				moonphase="3rd quarter";
			} else if (c.MoonPhase < 0.875 + 0.0625) {
				moonphase="waning crescent";
			} else {
				moonphase="new moon";
			}
			printf("                     moon phase: %s\n", moonphase);
			val = 0.5*( 1.0 - cos(c.MoonPhase*6.2831853) );
			A = (int)(val * 10000.0);
			a = A - 100*(int)(val*100.0);
			B = (int)(val * 100.0 + 0.5);
			printf(" illuminated moon disc fraction: %d.%d%d%%\t(%d%%)\n", A/100, a/10, a%10, B);
			if (c.Visible) {
				printf("                is moon visible: visible\n\n");
			} else {
				printf("                is moon visible: invisible\n\n");
			}
			MoonRise(Year, Month, DayOfMonth-1, LocalHour, &UTRise, &UTSet); 
			UTTohhmm(UTRise, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("           yesterday's moonrise: --:--\n");
			} else {
				printf("           yesterday's moonrise: %d%d:%d%d\n", H/10, H%10, M/10, M%10);
			}
			UTTohhmm(UTSet, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("            yesterday's moonset: --:--\n");
			} else {
				printf("            yesterday's moonset: %d%d:%d%d\n", H/10, H%10, M/10, M%10);
			}
			MoonRise(Year, Month, DayOfMonth, LocalHour, &UTRise, &UTSet); 
			UTTohhmm(UTRise, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("               today's moonrise: --:--\n");
			} else {
				printf("               today's moonrise: %d%d:%d%d\n", H/10, H%10, M/10, M%10);
			}
			UTTohhmm(UTSet, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("                today's moonset: --:--\n");
			} else {
				printf("                today's moonset: %d%d:%d%d\n", H/10, H%10, M/10, M%10);
			}
			MoonRise(Year, Month, DayOfMonth+1, LocalHour, &UTRise, &UTSet);
			UTTohhmm(UTRise, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("            tomorrow's moonrise: --:--\n");
			} else {
				printf("            tomorrow's moonrise: %d%d:%d%d\n", H/10, H%10, M/10, M%10);
			}
			UTTohhmm(UTSet, &H, &M);
			if ((H < 0)  || (M < 0)) {
				printf("             tomorrow's moonset: --:--\n\n");
			} else {
				printf("             tomorrow's moonset: %d%d:%d%d\n\n", H/10, H%10, M/10, M%10);
			}
			val = c.A_moon;
			if (val < 0.0) {
				sign="-";
			} else {
				sign="";
			}
			val = fabs(val);
			D = (int)val;
			val = (val-(double)D)*100.0;
			M = (int)val;
			printf("        moon azimuth in degrees: %s%d.%d%d°\n", sign, D, M/10, M%10);
			val = c.h_moon;
			if (val < 0.0) {
				sign="-";
			} else {
				sign="";
			}
			val = fabs(val);
			D = (int)val;
			val = (val-(double)D)*100.0;
			M = (int)val;
			printf("       moon altitude in degrees: %s%d.%d%d°\n", sign, D, M/10, M%10);
			val = c.EarthMoonDistance * 6371;
			A = (int)val;
			val = (val - A)*100.0;
			B = (int)val;
			printf("    moon distance in kilometers: %d.%d%d km\n", A, B/10, B%10);
			val = c.EarthMoonDistance * 3959;
			A = (int)val;
			val = (val - A)*100.0;
			B = (int)val;
			printf("         moon distance in miles: %d.%d%d mi\n\n", A, B/10, B%10);
			RA = c.RA_moon/15.0;
			H = (int)RA;
			RA = (RA-(double)H)*60.0;
			M = (int)RA; RA = (RA-(double)M)*60.0;
			S = (int)(RA+0.5);
			printf("       moon ascention in hhmmss: %d%d:%d%d:%d%d\n", H/10, H%10, M/10, M%10, S/10, S%10);
			DEC = c.DEC_moon;
			if (DEC < 0.0) {
				sign="-";
			} else {
				sign="";
			}
			DEC = fabs(DEC);
			D = (int)DEC;
			DEC = (DEC-(double)D)*60.0;
			M = (int)DEC;
			DEC = (DEC-(double)M)*60.0;
			S = (int)(DEC+0.5);
			printf("    moon declination in degrees: %s%d°%d%d'%d%d\"\n", sign, D, M/10, M%10, S/10, S%10);
			val = c.EarthMoonDistance;
			A = (int)val;
			val = (val - A)*10000.0;
			B = (int)val;
			printf(" moon distance in earth's radii: %f Re\n", c.EarthMoonDistance);
			exit(0);
		}

		if ((ForceSun == 1) && (ForceMoon == 0)) {
			AssumeDay = 1;
		} else if ((ForceSun == 0) && (ForceMoon == 1)) {
			AssumeDay = 0;
		} else if ((ForceSun == 1) && (ForceMoon == 1)) {
			if (counter >= 0) {
				AssumeDay = 1;
			} else {
				AssumeDay = 0;
			}
			ToggleWindow = 0;
			Loop = 0;
		}

		if (Reverse == 1) {
			if (AssumeDay == 1) {
				AssumeDay = 0;
			} else {
				AssumeDay = 1;
			}
		}

		if ((ToggleWindow == 1) || (Loop > 0)) {
			if (AssumeDay == 1) {
				AssumeDay = 0;
			} else {
				AssumeDay = 1;
			}
			ToggleWindow = 0;
		}

		if (OpenWindow == 1) {
			if (Mono == 0) {
				createXBMfromXPM(wmSunMoon_mask_bits, wmSunMoon_xpm, wmSunMoon_mask_width, wmSunMoon_mask_height);
				openXwindow(argc, argv, wmSunMoon_xpm, wmSunMoon_mask_bits, wmSunMoon_mask_width, wmSunMoon_mask_height, colors);
				AddMouseRegion(0, 5, 5, 58, 58);
				OpenWindow = 0;
			} else {
				createXBMfromXPM(wmSunMoon_mask_bits, wmSunMoonMono_xpm, wmSunMoon_mask_width, wmSunMoon_mask_height);
				openXwindow(argc, argv, wmSunMoonMono_xpm, wmSunMoon_mask_bits, wmSunMoon_mask_width, wmSunMoon_mask_height, colors);
				AddMouseRegion(0, 5, 5, 58, 58);
				OpenWindow = 0;
			}
		}

		/*
		 *  Draw image
		 */

		if (AssumeDay == 1) {
			/*
			 *  Update Sun image
			 */
			if ((Glat < 1.147118) && (Glat > -1.147118)) {
				// outside polar circles
				if ((TheTime >= Dawn) && (TheTime < Rise)) {
					copyXPMArea(5, 232, 54, 54, 5, 5);
					Font = 370;
				} else if ((TheTime >= Rise) && (TheTime < MornGH)) {
					copyXPMArea(5, 174, 54, 54, 5, 5);
					Font = 360;
				} else if ((TheTime >= MornGH) && (TheTime < EvenGH)) {
					copyXPMArea(5, 116, 54, 54, 5, 5);
					Font = 350;
				} else if ((TheTime >= EvenGH) && (TheTime < Set)) {
					copyXPMArea(5, 174, 54, 54, 5, 5);
					Font = 360;
				} else if ((TheTime >= Set) && (TheTime < Dusk)) {
					copyXPMArea(5, 232, 54, 54, 5, 5);
					Font = 370;
				} else {
					copyXPMArea(5, 290, 54, 54, 5, 5);
					Font = 380;
				}
				} else {
					// inside polar circles
					if (
					(TheTime >= Rise) && (TheTime < Set) ||
					(TheTime >= Rise) && (Rise > Set) ||
					(Rise == -60) && (Set == -60)
					)
					{
						copyXPMArea(5, 116, 54, 54, 5, 5);
						Font = 350;
					} else {
						copyXPMArea(5, 290, 54, 54, 5, 5);
						Font = 380;
					}
				}
		} else if (AssumeDay == 0) {
			/*
			 *  Update Moon image
			 */
			ImageNumber = (int)(c.MoonPhase * 60.0 + 0.5);

			if (ImageNumber > 59) ImageNumber = ImageNumber - 60;

			if (Glat < 0) {
				if (((ImageNumber >= 10) && (ImageNumber <= 19)) || ((ImageNumber >= 40) && (ImageNumber <= 49))) {
					ImageNumber = 60 - ImageNumber;
				} else {
					ImageNumber = 59 - ImageNumber;
				}
			}

			j = ImageNumber/10;
			i = ImageNumber%10;
			copyXPMArea(66+58*i, 0+58*j, 54, 54, 5, 5);
			Font = 380;
		}

		// 1=xpmwidth, 2=xpmheight, 3=charwidth, 4=charheight, 5=posx 6=posy

		if (AssumeDay == 1) {

				if (LTRise > 0.0) {
					val = LTRise;
					H = (int)val; val = (val-H)*60.0;
					M = (int)val;
					copyXPMArea(H/10 * 6 + 96, Font, 6, 9, 17, 5);
					copyXPMArea(H%10 * 6 + 96, Font, 6, 9, 23, 5);
					copyXPMArea(10 * 6 + 96, Font, 6, 9, 29, 5);
					copyXPMArea(M/10 * 6 + 96, Font, 6, 9, 35, 5);
					copyXPMArea(M%10 * 6 + 96, Font, 7, 9, 41, 5);
				} else {
					copyXPMArea(78, Font, 6, 9, 17, 5);
					copyXPMArea(78, Font, 6, 9, 23, 5);
					copyXPMArea(156, Font, 6, 9, 29, 5);
					copyXPMArea(78, Font, 6, 9, 35, 5);
					copyXPMArea(78, Font, 7, 9, 41, 5);
				}

				if ((TimeString == 1) && (TwilString == 0) && (GoldString == 0)) {
					if (UseUserTimeDiff == 0) {
						strftime (HourMinute,80,"%H%M",LocalTime);
						copyXPMArea((HourMinute[0] - '0') * 6 + 96, Font, 6, 9, 17, 28);
						copyXPMArea((HourMinute[1] - '0') * 6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(10 * 6 + 96, Font, 6, 9, 29, 28);
						copyXPMArea((HourMinute[2] - '0') * 6 + 96, Font, 6, 9, 35, 28);
						copyXPMArea((HourMinute[3] - '0') * 6 + 96, Font, 7, 9, 41, 28);
					} else {
						digit = HH/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 28);
						digit = HH%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						digit = MM/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 28);
						digit = MM%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 28);
					}
					if (DateDiff > 0) {
						copyXPMArea(66, Font, 6, 9, 52, 28);
					}
					if (DateDiff < 0) {
						copyXPMArea(78, Font, 6, 9, 52, 28);
					}
				}

				if ((TimeString == 0) && (TwilString == 1) && (GoldString == 0)) {
					if ((HT >= 0) && (MT >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 28);
						digit = HT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 28);
						digit = HT%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						digit = MT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 28);
						digit = MT%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 28);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 28);
						copyXPMArea(78, Font, 6, 9, 17, 28);
						copyXPMArea(78, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						copyXPMArea(78, Font, 6, 9, 35, 28);
						copyXPMArea(78, Font, 7, 9, 41, 28);
					}
				}

				if ((TimeString == 0) && (TwilString == 0) && (GoldString == 1)) {
					if ((HG >= 0) && (MG >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 28);
						digit = HG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 28);
						digit = HG%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						digit = MG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 28);
						digit = MG%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 28);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 28);
						copyXPMArea(78, Font, 6, 9, 17, 28);
						copyXPMArea(78, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						copyXPMArea(78, Font, 6, 9, 35, 28);
						copyXPMArea(78, Font, 7, 9, 41, 28);
					}
				}

				if ((TimeString == 1) && (TwilString == 1) && (GoldString == 0)) {
					if (UseUserTimeDiff == 0) {
						strftime (HourMinute,80,"%H%M",LocalTime);
						copyXPMArea((HourMinute[0] - '0') * 6 + 96, Font, 6, 9, 17, 23);
						copyXPMArea((HourMinute[1] - '0') * 6 + 96, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						copyXPMArea((HourMinute[2] - '0') * 6 + 96, Font, 6, 9, 35, 23);
						copyXPMArea((HourMinute[3] - '0') * 6 + 96, Font, 7, 9, 41, 23);
					} else {
						digit = HH/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 23);
						digit = HH%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						digit = MM/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 23);
						digit = MM%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 23);
					}
					if ((HT >= 0) && (MT >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						digit = HT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 32);
						digit = HT%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						digit = MT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 32);
						digit = MT%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 32);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						copyXPMArea(78, Font, 6, 9, 17, 32);
						copyXPMArea(78, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						copyXPMArea(78, Font, 6, 9, 35, 32);
						copyXPMArea(78, Font, 7, 9, 41, 32);
					}
					if (DateDiff > 0) {
						copyXPMArea(66, Font, 6, 9, 52, 23);
					}
					if (DateDiff < 0) {
						copyXPMArea(78, Font, 6, 9, 52, 23);
					}
				}

				if ((TimeString == 1) && (TwilString == 0) && (GoldString == 1)) {
					if (UseUserTimeDiff == 0) {
						strftime (HourMinute,80,"%H%M",LocalTime);
						copyXPMArea((HourMinute[0] - '0') * 6 + 96, Font, 6, 9, 17, 23);
						copyXPMArea((HourMinute[1] - '0') * 6 + 96, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						copyXPMArea((HourMinute[2] - '0') * 6 + 96, Font, 6, 9, 35, 23);
						copyXPMArea((HourMinute[3] - '0') * 6 + 96, Font, 7, 9, 41, 23);
					} else {
						digit = HH/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 23);
						digit = HH%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						digit = MM/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 23);
						digit = MM%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 23);
					}
					if ((HG >= 0) && (MG >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						digit = HG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 32);
						digit = HG%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						digit = MG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 32);
						digit = MG%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 32);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						copyXPMArea(78, Font, 6, 9, 17, 32);
						copyXPMArea(78, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						copyXPMArea(78, Font, 6, 9, 35, 32);
						copyXPMArea(78, Font, 7, 9, 41, 32);
					}
					if (DateDiff > 0) {
						copyXPMArea(66, Font, 6, 9, 52, 23);
					}
					if (DateDiff < 0) {
						copyXPMArea(78, Font, 6, 9, 52, 23);
					}
				}

				if ((TwilString == 1) && (GoldString == 1)) {
					if ((HT >= 0) && (MT >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 23);
						digit = HT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 23);
						digit = HT%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						digit = MT/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 23);
						digit = MT%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 23);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 23);
						copyXPMArea(78, Font, 6, 9, 17, 23);
						copyXPMArea(78, Font, 6, 9, 23, 23);
						copyXPMArea(156, Font, 6, 9, 29, 23);
						copyXPMArea(78, Font, 6, 9, 35, 23);
						copyXPMArea(78, Font, 7, 9, 41, 23);
					}
					if ((HG >= 0) && (MG >= 0)) {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						digit = HG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 32);
						digit = HG%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						digit = MG/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 32);
						digit = MG%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 32);
					} else {
						copyXPMArea(576, Font, 6, 9, 5, 32);
						copyXPMArea(78, Font, 6, 9, 17, 32);
						copyXPMArea(78, Font, 6, 9, 23, 32);
						copyXPMArea(156, Font, 6, 9, 29, 32);
						copyXPMArea(78, Font, 6, 9, 35, 32);
						copyXPMArea(78, Font, 7, 9, 41, 32);
					}
				}

				if (LTSet > 0.0) {
					val = LTSet;
					H = (int)val; val = (val-H)*60.0;
					M = (int)val;
					copyXPMArea(H/10 * 6 + 96, Font, 6, 9, 17, 50);
					copyXPMArea(H%10 * 6 + 96, Font, 6, 9, 23, 50);
					copyXPMArea(156, Font, 6, 9, 29, 50);
					copyXPMArea(M/10 * 6 + 96, Font, 6, 9, 35, 50);
					copyXPMArea(M%10 * 6 + 96, Font, 7, 9, 41, 50);
				} else {
					copyXPMArea(78, Font, 6, 9, 17, 50);
					copyXPMArea(78, Font, 6, 9, 23, 50);
					copyXPMArea(156, Font, 6, 9, 29, 50);
					copyXPMArea(78, Font, 6, 9, 35, 50);
					copyXPMArea(78, Font, 7, 9, 41, 50);
				}

				if (DateDiff > 0) {
					copyXPMArea(66, Font, 6, 9, 52, 5);
					copyXPMArea(66, Font, 6, 9, 52, 50);
				}

				if (DateDiff < 0) {
					copyXPMArea(78, Font, 6, 9, 52, 5);
					copyXPMArea(78, Font, 6, 9, 52, 50);
				}

		}

		if (AssumeDay == 0) {

				UTTohhmm(UTRise, &H, &M);
				if (H >= 0) {
					digit = H/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 5);
					digit = H%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 5);
					copyXPMArea(156, Font, 6, 9, 29, 5);
					digit = M/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 5);
					digit = M%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 5);
				} else {
					copyXPMArea(78, Font, 6, 9, 17, 5);
					copyXPMArea(78, Font, 6, 9, 23, 5);
					copyXPMArea(156, Font, 6, 9, 29, 5);
					copyXPMArea(78, Font, 6, 9, 35, 5);
					copyXPMArea(78, Font, 7, 9, 41, 5);
				}

				if (((TimeString == 0) && (Percentage == 1)) 
				|| ((TimeString == 1) && (Percentage == 1) && (counter < 0))) {
					A = (int)(c.MoonPhase * 100.0 + 0.5);
					if (A == 100) {
						copyXPMArea(1*6 + 96, Font, 6, 9, 20, 28);
						copyXPMArea(0*6 + 96, Font, 6, 9, 26, 28);
						copyXPMArea(0*6 + 96, Font, 6, 9, 32, 28);
						copyXPMArea(30, Font, 7, 9, 38, 28);
					} else if (A >= 10) {
						digit = A/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 28);
						digit = A%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 29, 28);
						copyXPMArea(30, Font, 7, 9, 35, 28);
					} else {
						digit = A; copyXPMArea(digit*6 + 96, Font, 6, 9, 26, 28);
						copyXPMArea(30, Font, 7, 9, 32, 28);
					}
				}

				if (((TimeString == 1) && (Percentage == 0)) 
				|| ((TimeString == 1) && (Percentage == 1) && (counter >= 0))) {
					if (UseUserTimeDiff == 0) {
						strftime (HourMinute,80,"%H%M",LocalTime);
						copyXPMArea((HourMinute[0] - '0') * 6 + 96, Font, 6, 9, 17, 28);
						copyXPMArea((HourMinute[1] - '0') * 6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						copyXPMArea((HourMinute[2] - '0') * 6 + 96, Font, 6, 9, 35, 28);
						copyXPMArea((HourMinute[3] - '0') * 6 + 96, Font, 7, 9, 41, 28);
					} else {
						digit = HH/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 28);
						digit = HH%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 28);
						copyXPMArea(156, Font, 6, 9, 29, 28);
						digit = MM/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 28);
						digit = MM%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 28);
					}
				if (DateDiff > 0) {
					copyXPMArea(66, Font, 6, 9, 52, 28);
				}
				if (DateDiff < 0) {
					copyXPMArea(78, Font, 6, 9, 52, 28);
				}
				}

				if (Clean == 0) {
					if (c.Visible)
						copyXPMArea(582, Font, 6, 9, 5, 28);
					else
						copyXPMArea(588, Font, 6, 9, 5, 28);
				}

				UTTohhmm(UTSet, &H, &M);
				if (H >= 0){
					digit = H/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 17, 50);
					digit = H%10; copyXPMArea(digit*6 + 96, Font, 6, 9, 23, 50);
					copyXPMArea(156, Font, 6, 9, 29, 50);
					digit = M/10; copyXPMArea(digit*6 + 96, Font, 6, 9, 35, 50);
					digit = M%10; copyXPMArea(digit*6 + 96, Font, 7, 9, 41, 50);
				} else {
					copyXPMArea(78, Font, 6, 9, 17, 50);
					copyXPMArea(78, Font, 6, 9, 23, 50);
					copyXPMArea(156, Font, 6, 9, 29, 50);
					copyXPMArea(78, Font, 6, 9, 35, 50);
					copyXPMArea(78, Font, 7, 9, 41, 50);
				}

				if (DateDiff > 0) {
					copyXPMArea(66, Font, 6, 9, 52, 5);
					copyXPMArea(66, Font, 6, 9, 52, 50);
				}

				if (DateDiff < 0) {
					copyXPMArea(78, Font, 6, 9, 52, 5);
					copyXPMArea(78, Font, 6, 9, 52, 50);
				}

		}

		/*
		 *   Process any pending X events
		 */
		while(XPending(display)) {
			XNextEvent(display, &Event);
			switch(Event.type) {
				case Expose:
					RedrawWindow();
					break;
				case DestroyNotify:
					XCloseDisplay(display);
					exit(0);
					break;
				case ButtonPress:
					i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
					but_stat = i;
					break;
				case ButtonRelease:
					i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
					if (but_stat == 0) {
						ToggleWindow = 1;
						Loop = 33;		// four seconds
					}
					but_stat = -1;
					break;
			}
		}

		/*
		 *  Redraw and wait for next update 
		 */
		RedrawWindow();
		usleep(DELAY);

	}

}

/*
 *   ParseCMDLine()
 */
void ParseCMDLine(int argc, char *argv[]) {
	int  i;
	if (argc >= 5) {
		for (i = 1; i < argc; i++) {
			if (!strcmp(argv[i], "-display")) {
				++i;
			} else if (!strcmp(argv[i], "-lat")) {
				Glat = atof(argv[++i]);
			} else if (!strcmp(argv[i], "-lon")) {
				Glon = atof(argv[++i]);
			} else if (!strcmp(argv[i], "-tzone")) {
				UseTimeZone = 1;
				LocalTimeZone = argv[++i];
				DistTimeZone = argv[++i];
			} else if (!strcmp(argv[i], "-perc")) {
				Percentage = 1;
			} else if (!strcmp(argv[i], "-time")) {
				TimeString = 1;
			} else if (!strcmp(argv[i], "-twil")) {
				TwilString = 1;
			} else if (!strcmp(argv[i], "-gold")) {
				GoldString = 1;
			} else if (!strcmp(argv[i], "-rev")) {
				Reverse = 1;
			} else if (!strcmp(argv[i], "-clean")) {
				Clean = 1;
			} else if (!strcmp(argv[i], "-sun")) {
				ForceSun = 1;
			} else if (!strcmp(argv[i], "-moon")) {
				ForceMoon = 1;
			} else if (!strcmp(argv[i], "-mono")) {
				Mono = 1;
			} else if (!strcmp(argv[i], "-text")) {
				TextMode = 1;
			} else {
				PrintHelp();
			}
		}
	} else {
		PrintHelp();
	}
}

void PrintHelp() {
	printf("\nwmSunMoon %s (C) %s Cezary M. Kruk (%s)\n\n", WMSUNMOON_VERSION, WMSUNMOON_REVYEAR, WMSUNMOON_REVDATE);
	printf("  Usage: wmSunMoon [-lat <latitude>] [-lon <longitude>]\n\n");
	printf("  -lat   <latitude>      : observer's latitude -- positive to the north.\n");
	printf("  -lon   <longitude>     : observer's longitude -- positive to the west.\n");
	printf("  -tzone <local distant> : the local and distant time zones.\n");
	printf("  -time                  : display the current time.\n");
	printf("  -twil                  : display the civil twilight offset.\n");
	printf("  -gold                  : display the golden hour offset.\n");
	printf("  -perc                  : display the lunar cycle percentage.\n");
	printf("  -clean                 : supress displaying the arrow indicator.\n");
	printf("  -sun                   : force displaying the Sun.\n");
	printf("  -moon                  : force displaying the Moon.\n");
	printf("  -rev                   : reverse the display (Sun vs Moon).\n");
	printf("  -mono                  : use monochrome images.\n");
	printf("  -text                  : display the complete data on the console.\n");
	printf("  -h                     : display help screen.\n\n");
	printf("  SAMPLE COMMAND FOR PARIS, FRANCE WHEN YOU ARE IN THE SAME TIME ZONE:\n\n");
	printf("  wmSunMoon -lat 48.85 -lon -2.35 -time\n\n");
	printf("  SAMPLE COMMAND FOR PARIS, FRANCE WHEN YOU ARE IN EST/EDT TIME ZONE:\n\n");
	printf("  wmSunMoon -lat 48.85 -lon -2.35 -time -tzone America/New_York Europe/Paris\n\n");
	exit(1);
}

