/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
 *  Unit SGP4SDP4
 *           Author:  Dr TS Kelso 
 * Original Version:  1991 Oct 30
 * Current Revision:  1992 Sep 03
 *          Version:  1.50 
 *        Copyright:  1991-1992, All Rights Reserved 
 *
 *   Ported to C by:  Neoklis Kyriazis  April 10  2001
 *   Reentrancy mods by Alexandru Csete OZ9AEC
 */

#include "sgp4sdp4.h"

/* SGP4 */
/* This function is used to calculate the position and velocity */
/* of near-earth (period < 225 minutes) satellites. tsince is   */
/* time since epoch in minutes, tle is a pointer to a tle_t     */
/* structure with Keplerian orbital elements and pos and vel    */
/* are vector_t structures returning ECI satellite position and */
/* velocity. Use Convert_Sat_State() to convert to km and km/s.*/
void
SGP4 (sat_t *sat, double tsince)
{
	double
		cosuk,sinuk,rfdotk,vx,vy,vz,ux,uy,uz,xmy,xmx,
		cosnok,sinnok,cosik,sinik,rdotk,xinck,xnodek,uk,
		rk,cos2u,sin2u,u,sinu,cosu,betal,rfdot,rdot,r,pl,
		elsq,esine,ecose,epw,cosepw,x1m5th,xhdot1,tfour,
		sinepw,capu,ayn,xlt,aynl,xll,axn,xn,beta,xl,e,a,
		tcube,delm,delomg,templ,tempe,tempa,xnode,tsq,xmp,
		omega,xnoddf,omgadf,xmdf,a1,a3ovk2,ao,betao,betao2,
		c1sq,c2,c3,coef,coef1,del1,delo,eeta,eosq,etasq,
		perige,pinvsq,psisq,qoms24,s4,temp,temp1,temp2,
		temp3,temp4,temp5,temp6,theta2,theta4,tsi;

	int i;  

	/* Initialization */
	if (~sat->flags & SGP4_INITIALIZED_FLAG) {
	//if (!(sat->flags & SGP4_INITIALIZED_FLAG)) {
		
		sat->flags |= SGP4_INITIALIZED_FLAG;

		//g_print ("SAT %d INITIALISED.\n", sat->tle.catnr);

		/* Recover original mean motion (xnodp) and   */
		/* semimajor axis (aodp) from input elements. */
		a1 = pow (xke/sat->tle.xno, tothrd);
		sat->sgps.cosio = cos (sat->tle.xincl);
		theta2 = sat->sgps.cosio * sat->sgps.cosio;
		sat->sgps.x3thm1 = 3 * theta2 - 1.0;
		eosq = sat->tle.eo * sat->tle.eo;
		betao2 = 1 - eosq;
		betao = sqrt (betao2);
		del1 = 1.5 * ck2 * sat->sgps.x3thm1 / (a1*a1*betao*betao2);
		ao = a1*(1-del1*(0.5*tothrd+del1*(1+134.0/81.0*del1)));
		delo = 1.5 * ck2 * sat->sgps.x3thm1 / (ao*ao*betao*betao2);
		sat->sgps.xnodp = sat->tle.xno / (1.0 + delo);
		sat->sgps.aodp = ao / (1.0 - delo);

		/* For perigee less than 220 kilometers, the "simple" flag is set */
		/* and the equations are truncated to linear variation in sqrt a  */
		/* and quadratic variation in mean anomaly.  Also, the c3 term,   */
		/* the delta omega term, and the delta m term are dropped.        */
		if ((sat->sgps.aodp * (1.0 - sat->tle.eo) / ae) < (220.0 / xkmper + ae))
			sat->flags |= SIMPLE_FLAG;
		else
			sat->flags &= ~SIMPLE_FLAG;

		/* For perigee below 156 km, the       */ 
		/* values of s and qoms2t are altered. */
		s4 = __s__;
		qoms24 = qoms2t;
		perige = (sat->sgps.aodp * (1 - sat->tle.eo) - ae) * xkmper;
		if (perige < 156.0) {
			if (perige <= 98.0)
				s4 = 20.0;
			else
				s4 = perige - 78.0;
			qoms24 = pow ((120.0 - s4) * ae / xkmper, 4);
			s4 = s4 / xkmper + ae;
		}; /* FIXME FIXME: End of if(perige <= 98) NO WAY!!!! */

		pinvsq = 1.0 / (sat->sgps.aodp * sat->sgps.aodp * betao2 * betao2);
		tsi = 1.0 / (sat->sgps.aodp - s4);
		sat->sgps.eta = sat->sgps.aodp * sat->tle.eo * tsi;
		etasq = sat->sgps.eta * sat->sgps.eta;
		eeta = sat->tle.eo * sat->sgps.eta;
		psisq = fabs (1.0 - etasq);
		coef = qoms24 * pow (tsi, 4);
		coef1 = coef / pow (psisq, 3.5);
		c2 = coef1 * sat->sgps.xnodp * (sat->sgps.aodp *
						(1.0 + 1.5 * etasq + eeta * (4.0 + etasq)) +
						0.75 * ck2 * tsi / psisq * sat->sgps.x3thm1 *
						(8.0 + 3.0 * etasq * (8 + etasq)));
		sat->sgps.c1 = c2 * sat->tle.bstar;
		sat->sgps.sinio = sin (sat->tle.xincl);
		a3ovk2 = -xj3 / ck2 * pow (ae, 3);
		c3 = coef * tsi * a3ovk2 * sat->sgps.xnodp * ae * sat->sgps.sinio / sat->tle.eo;
		sat->sgps.x1mth2 = 1.0 - theta2;
		sat->sgps.c4 = 2.0 * sat->sgps.xnodp * coef1 * sat->sgps.aodp * betao2 *
			(sat->sgps.eta * (2.0 + 0.5 * etasq) +
			 sat->tle.eo * (0.5 + 2.0 * etasq) -
			 2.0 * ck2 * tsi / (sat->sgps.aodp * psisq) *
			 (-3.0 * sat->sgps.x3thm1 * (1.0 - 2.0 * eeta + etasq * (1.5 - 0.5 * eeta)) + 
			  0.75 * sat->sgps.x1mth2 * (2.0 * etasq - eeta * (1.0 + etasq)) * 
			  cos (2.0 * sat->tle.omegao)));
		sat->sgps.c5 = 2.0 * coef1 * sat->sgps.aodp * betao2 *
			(1.0 + 2.75 * (etasq + eeta) + eeta * etasq);
		theta4 = theta2 * theta2;
		temp1 = 3.0 * ck2 * pinvsq * sat->sgps.xnodp;
		temp2 = temp1 * ck2 * pinvsq;
		temp3 = 1.25 * ck4 * pinvsq * pinvsq * sat->sgps.xnodp;
		sat->sgps.xmdot = sat->sgps.xnodp + 0.5 * temp1 * betao * sat->sgps.x3thm1 +
			0.0625 * temp2 * betao * (13.0 - 78.0 * theta2 + 137.0 * theta4);
		x1m5th = 1.0 - 5.0 * theta2;
		sat->sgps.omgdot = -0.5 * temp1 * x1m5th +
			0.0625 * temp2 * (7.0 - 114.0 * theta2 + 395.0 * theta4) +
			temp3 * (3.0 - 36.0 * theta2 + 49.0 * theta4);
		xhdot1 = -temp1 * sat->sgps.cosio;
		sat->sgps.xnodot = xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * theta2) +
					     2.0 * temp3 * (3.0 - 7.0 * theta2)) * sat->sgps.cosio;
		sat->sgps.omgcof = sat->tle.bstar * c3 * cos (sat->tle.omegao);
		sat->sgps.xmcof = -tothrd * coef * sat->tle.bstar * ae / eeta;
		sat->sgps.xnodcf = 3.5 * betao2 * xhdot1 * sat->sgps.c1;
		sat->sgps.t2cof = 1.5 * sat->sgps.c1;
		sat->sgps.xlcof = 0.125 * a3ovk2 * sat->sgps.sinio *
			(3.0 + 5.0 * sat->sgps.cosio) / (1.0 + sat->sgps.cosio);
		sat->sgps.aycof = 0.25 * a3ovk2 * sat->sgps.sinio;
		sat->sgps.delmo = pow (1.0 + sat->sgps.eta * cos (sat->tle.xmo), 3);
		sat->sgps.sinmo = sin (sat->tle.xmo);
		sat->sgps.x7thm1 = 7.0 * theta2 - 1.0;
		if (~sat->flags & SIMPLE_FLAG) {
			c1sq = sat->sgps.c1 * sat->sgps.c1;
			sat->sgps.d2 = 4.0 * sat->sgps.aodp * tsi * c1sq;
			temp = sat->sgps.d2 * tsi * sat->sgps.c1 / 3.0;
			sat->sgps.d3 = (17.0 * sat->sgps.aodp + s4) * temp;
			sat->sgps.d4 = 0.5 * temp * sat->sgps.aodp * tsi *
				(221.0 * sat->sgps.aodp + 31.0 * s4) * sat->sgps.c1;
			sat->sgps.t3cof = sat->sgps.d2 + 2.0 * c1sq;
			sat->sgps.t4cof = 0.25 * (3.0 * sat->sgps.d3 + sat->sgps.c1 *
						  (12.0 * sat->sgps.d2 + 10.0 * c1sq));
			sat->sgps.t5cof = 0.2 * (3.0 * sat->sgps.d4 +
						 12.0 * sat->sgps.c1 * sat->sgps.d3 +
						 6.0 * sat->sgps.d2 * sat->sgps.d2 +
						 15.0 * c1sq * (2.0 * sat->sgps.d2 + c1sq));
		}; /* End of if (isFlagClear(SIMPLE_FLAG)) */
	}; /* End of SGP4() initialization */

	/* Update for secular gravity and atmospheric drag. */
	xmdf = sat->tle.xmo + sat->sgps.xmdot * tsince;
	omgadf = sat->tle.omegao + sat->sgps.omgdot * tsince;
	xnoddf = sat->tle.xnodeo + sat->sgps.xnodot * tsince;
	omega = omgadf;
	xmp = xmdf;
	tsq = tsince*tsince;
	xnode = xnoddf + sat->sgps.xnodcf * tsq;
	tempa = 1.0 - sat->sgps.c1 * tsince;
	tempe = sat->tle.bstar * sat->sgps.c4 * tsince;
	templ = sat->sgps.t2cof * tsq;
	if (~sat->flags & SIMPLE_FLAG) {
		delomg = sat->sgps.omgcof * tsince;
		delm = sat->sgps.xmcof * (pow (1 + sat->sgps.eta * cos (xmdf), 3) - sat->sgps.delmo);
		temp = delomg + delm;
		xmp = xmdf + temp;
		omega = omgadf - temp;
		tcube = tsq * tsince;
		tfour = tsince * tcube;
		tempa = tempa - sat->sgps.d2 * tsq - sat->sgps.d3 * tcube - sat->sgps.d4 * tfour;
		tempe = tempe + sat->tle.bstar * sat->sgps.c5 * (sin (xmp) - sat->sgps.sinmo);
		templ = templ + sat->sgps.t3cof * tcube + tfour *
			(sat->sgps.t4cof + tsince * sat->sgps.t5cof);
	}; /* End of if (isFlagClear(SIMPLE_FLAG)) */

	a = sat->sgps.aodp * pow (tempa, 2);
	e = sat->tle.eo - tempe;
	xl = xmp + omega + xnode + sat->sgps.xnodp * templ;
	beta = sqrt (1.0 - e*e);
	xn = xke / pow (a, 1.5);

	/* Long period periodics */
	axn = e * cos (omega);
	temp = 1.0 / (a * beta * beta);
	xll = temp * sat->sgps.xlcof * axn;
	aynl = temp * sat->sgps.aycof;
	xlt = xl + xll;
	ayn = e * sin (omega) + aynl;

	/* Solve Kepler's' Equation */
	capu = FMod2p (xlt - xnode);
	temp2 = capu;

	i = 0;
	do {
		sinepw = sin (temp2);
		cosepw = cos (temp2);
		temp3 = axn * sinepw;
		temp4 = ayn * cosepw;
		temp5 = axn * cosepw;
		temp6 = ayn * sinepw;
		epw = (capu - temp4 + temp3 - temp2) / (1.0 - temp5 - temp6) + temp2;
		if (fabs (epw - temp2) <= e6a)
			break;
		temp2 = epw;
	}
	while( i++ < 10 );

	/* Short period preliminary quantities */
	ecose = temp5 + temp6;
	esine = temp3 - temp4;
	elsq = axn*axn + ayn*ayn;
	temp = 1.0 - elsq;
	pl = a * temp;
	r = a * (1.0 - ecose);
	temp1 = 1.0 / r;
	rdot = xke * sqrt (a) * esine * temp1;
	rfdot = xke * sqrt (pl) * temp1;
	temp2 = a * temp1;
	betal = sqrt (temp);
	temp3 = 1.0 / (1.0 + betal);
	cosu = temp2 * (cosepw - axn + ayn * esine * temp3);
	sinu = temp2 * (sinepw - ayn - axn * esine * temp3);
	u = AcTan (sinu, cosu);
	sin2u = 2.0 * sinu * cosu;
	cos2u = 2.0 * cosu * cosu - 1.0;
	temp = 1.0 / pl;
	temp1 = ck2 * temp;
	temp2 = temp1 * temp;

	/* Update for short periodics */
	rk = r * (1.0 - 1.5 * temp2 * betal * sat->sgps.x3thm1) +
		0.5 * temp1 * sat->sgps.x1mth2 * cos2u;
	uk = u - 0.25 * temp2 * sat->sgps.x7thm1 * sin2u;
	xnodek = xnode + 1.5 * temp2 * sat->sgps.cosio * sin2u;
	xinck = sat->tle.xincl + 1.5 * temp2 * sat->sgps.cosio * sat->sgps.sinio * cos2u;
	rdotk = rdot - xn * temp1 * sat->sgps.x1mth2 * sin2u;
	rfdotk = rfdot + xn * temp1 * (sat->sgps.x1mth2 * cos2u + 1.5 * sat->sgps.x3thm1);


	/* Orientation vectors */
	sinuk = sin (uk);
	cosuk = cos (uk);
	sinik = sin (xinck);
	cosik = cos (xinck);
	sinnok = sin (xnodek);
	cosnok = cos (xnodek);
	xmx = -sinnok * cosik;
	xmy = cosnok * cosik;
	ux = xmx * sinuk + cosnok * cosuk;
	uy = xmy * sinuk + sinnok * cosuk;
	uz = sinik * sinuk;
	vx = xmx * cosuk - cosnok * sinuk;
	vy = xmy * cosuk - sinnok * sinuk;
	vz = sinik * cosuk;

	/* Position and velocity */
	sat->pos.x = rk*ux;
	sat->pos.y = rk*uy;
	sat->pos.z = rk*uz;
	sat->vel.x = rdotk*ux+rfdotk*vx;
	sat->vel.y = rdotk*uy+rfdotk*vy;
	sat->vel.z = rdotk*uz+rfdotk*vz;

	sat->phase = xlt - xnode - omgadf + twopi;
	if (sat->phase < 0)
		sat->phase += twopi;
	sat->phase = FMod2p (sat->phase);

	sat->tle.omegao1 = omega;
	sat->tle.xincl1  = xinck;
	sat->tle.xnodeo1 = xnodek;

} /*SGP4*/

/*------------------------------------------------------------------*/

/* SDP4 */
/* This function is used to calculate the position and velocity */
/* of deep-space (period > 225 minutes) satellites. tsince is   */
/* time since epoch in minutes, tle is a pointer to a tle_t     */
/* structure with Keplerian orbital elements and pos and vel    */
/* are vector_t structures returning ECI satellite position and */
/* velocity. Use Convert_Sat_State() to convert to km and km/s. */
void 
SDP4 (sat_t *sat, double tsince)
{
	int i;


	double
		a,axn,ayn,aynl,beta,betal,capu,cos2u,cosepw,cosik,
		cosnok,cosu,cosuk,ecose,elsq,epw,esine,pl,theta4,
		rdot,rdotk,rfdot,rfdotk,rk,sin2u,sinepw,sinik,
		sinnok,sinu,sinuk,tempe,templ,tsq,u,uk,ux,uy,uz,
		vx,vy,vz,xinck,xl,xlt,xmam,xmdf,xmx,xmy,xnoddf,
		xnodek,xll,a1,a3ovk2,ao,c2,coef,coef1,x1m5th,
		xhdot1,del1,r,delo,eeta,eta,etasq,perige,
		psisq,tsi,qoms24,s4,pinvsq,temp,tempa,temp1,
		temp2,temp3,temp4,temp5,temp6;


	/* Initialization */
	if (~sat->flags & SDP4_INITIALIZED_FLAG) {

		sat->flags |= SDP4_INITIALIZED_FLAG;

		/* Recover original mean motion (xnodp) and   */
		/* semimajor axis (aodp) from input elements. */
		a1 = pow (xke / sat->tle.xno, tothrd);
		sat->deep_arg.cosio = cos (sat->tle.xincl);
		sat->deep_arg.theta2 = sat->deep_arg.cosio * sat->deep_arg.cosio;
		sat->sgps.x3thm1 = 3.0 * sat->deep_arg.theta2 - 1.0;
		sat->deep_arg.eosq = sat->tle.eo * sat->tle.eo;
		sat->deep_arg.betao2 = 1.0 - sat->deep_arg.eosq;
		sat->deep_arg.betao = sqrt (sat->deep_arg.betao2);
		del1 = 1.5 * ck2 * sat->sgps.x3thm1 /
			(a1 * a1 * sat->deep_arg.betao * sat->deep_arg.betao2);
		ao = a1 * (1.0 - del1 * (0.5 * tothrd + del1 * (1.0 + 134.0 / 81.0 * del1)));
		delo = 1.5 * ck2 * sat->sgps.x3thm1 /
			(ao * ao * sat->deep_arg.betao * sat->deep_arg.betao2);
		sat->deep_arg.xnodp = sat->tle.xno / (1.0 + delo);
		sat->deep_arg.aodp = ao / (1.0 - delo);

		/* For perigee below 156 km, the values */
		/* of s and qoms2t are altered.         */
		s4 = __s__;
		qoms24 = qoms2t;
		perige = (sat->deep_arg.aodp * (1.0 - sat->tle.eo) - ae) * xkmper;
		if (perige < 156.0) {
			if (perige <= 98.0)
				s4 = 20.0;
			else
				s4 = perige - 78.0;
			qoms24 = pow ((120.0 - s4) * ae / xkmper, 4);
			s4 = s4 / xkmper + ae;
		}
		pinvsq = 1.0 / (sat->deep_arg.aodp * sat->deep_arg.aodp *
				sat->deep_arg.betao2 * sat->deep_arg.betao2);
		sat->deep_arg.sing = sin (sat->tle.omegao);
		sat->deep_arg.cosg = cos (sat->tle.omegao);
		tsi = 1.0 / (sat->deep_arg.aodp - s4);
		eta = sat->deep_arg.aodp * sat->tle.eo * tsi;
		etasq = eta * eta;
		eeta = sat->tle.eo * eta;
		psisq = fabs (1.0 - etasq);
		coef = qoms24 * pow (tsi, 4);
		coef1 = coef / pow (psisq, 3.5);
		c2 = coef1 * sat->deep_arg.xnodp * (sat->deep_arg.aodp *
						    (1.0 + 1.5 * etasq + eeta *
						     (4.0 + etasq)) + 0.75 * ck2 * tsi / psisq * 
						    sat->sgps.x3thm1 * (8.0 + 3.0 * etasq *
									(8.0 + etasq)));
		sat->sgps.c1 = sat->tle.bstar * c2;
		sat->deep_arg.sinio = sin (sat->tle.xincl);
		a3ovk2 = -xj3 / ck2 * pow (ae, 3);
		sat->sgps.x1mth2 = 1.0 - sat->deep_arg.theta2;
		sat->sgps.c4 = 2.0 * sat->deep_arg.xnodp * coef1 *
			sat->deep_arg.aodp * sat->deep_arg.betao2 *
			(eta * (2.0 + 0.5 * etasq) + sat->tle.eo *
			 (0.5 + 2.0 * etasq) - 2.0 * ck2 * tsi /
			 (sat->deep_arg.aodp * psisq) * (-3.0 * sat->sgps.x3thm1 *
							 (1.0 - 2.0 * eeta + etasq *
							  (1.5 - 0.5 * eeta)) +
							 0.75 * sat->sgps.x1mth2 * 
							 (2.0 * etasq - eeta * (1.0 + etasq)) *
							 cos (2.0 * sat->tle.omegao)));
		theta4 = sat->deep_arg.theta2 * sat->deep_arg.theta2;
		temp1 = 3.0 * ck2 * pinvsq * sat->deep_arg.xnodp;
		temp2 = temp1 * ck2 * pinvsq;
		temp3 = 1.25 * ck4 * pinvsq * pinvsq * sat->deep_arg.xnodp;
		sat->deep_arg.xmdot = sat->deep_arg.xnodp + 0.5 * temp1 * sat->deep_arg.betao *
			sat->sgps.x3thm1 + 0.0625 * temp2 * sat->deep_arg.betao *
			(13.0 - 78.0 * sat->deep_arg.theta2 + 137.0 * theta4);
		x1m5th = 1.0 - 5.0 * sat->deep_arg.theta2;
		sat->deep_arg.omgdot = -0.5 * temp1 * x1m5th + 0.0625 * temp2 *
                        (7.0 - 114.0 * sat->deep_arg.theta2 + 395.0 * theta4) +
	                temp3 * (3.0 - 36.0 * sat->deep_arg.theta2 + 49.0 * theta4);
		xhdot1 = -temp1 * sat->deep_arg.cosio;
		sat->deep_arg.xnodot = xhdot1 + (0.5 * temp2 * (4.0 - 19.0 * sat->deep_arg.theta2) +
						 2.0 * temp3 * (3.0 - 7.0 * sat->deep_arg.theta2)) *
			sat->deep_arg.cosio;
		sat->sgps.xnodcf = 3.5 * sat->deep_arg.betao2 * xhdot1 * sat->sgps.c1;
		sat->sgps.t2cof = 1.5 * sat->sgps.c1;
		sat->sgps.xlcof = 0.125 * a3ovk2 * sat->deep_arg.sinio *
			(3.0 + 5.0 * sat->deep_arg.cosio) / (1.0 + sat->deep_arg.cosio);
		sat->sgps.aycof = 0.25 * a3ovk2 * sat->deep_arg.sinio;
		sat->sgps.x7thm1 = 7.0 * sat->deep_arg.theta2 - 1.0;

		/* initialize Deep() */
		Deep (dpinit, sat);
	}; /*End of SDP4() initialization */

	/* Update for secular gravity and atmospheric drag */
	xmdf = sat->tle.xmo + sat->deep_arg.xmdot * tsince;
	sat->deep_arg.omgadf = sat->tle.omegao + sat->deep_arg.omgdot * tsince;
	xnoddf = sat->tle.xnodeo + sat->deep_arg.xnodot * tsince;
	tsq = tsince * tsince;
	sat->deep_arg.xnode = xnoddf + sat->sgps.xnodcf * tsq;
	tempa = 1.0 - sat->sgps.c1 * tsince;
	tempe = sat->tle.bstar * sat->sgps.c4 * tsince;
	templ = sat->sgps.t2cof * tsq;
	sat->deep_arg.xn = sat->deep_arg.xnodp;

	/* Update for deep-space secular effects */
	sat->deep_arg.xll = xmdf;
	sat->deep_arg.t = tsince;

	Deep (dpsec, sat);

	xmdf = sat->deep_arg.xll;
	a = pow (xke / sat->deep_arg.xn, tothrd) * tempa * tempa;
	sat->deep_arg.em = sat->deep_arg.em - tempe;
	xmam = xmdf + sat->deep_arg.xnodp * templ;

	/* Update for deep-space periodic effects */
	sat->deep_arg.xll = xmam;

	Deep (dpper, sat);

	xmam = sat->deep_arg.xll;
	xl = xmam + sat->deep_arg.omgadf + sat->deep_arg.xnode;
	beta = sqrt (1.0 - sat->deep_arg.em * sat->deep_arg.em);
	sat->deep_arg.xn = xke / pow( a, 1.5);

	/* Long period periodics */
	axn = sat->deep_arg.em * cos (sat->deep_arg.omgadf);
	temp = 1.0 / (a * beta * beta);
	xll = temp * sat->sgps.xlcof * axn;
	aynl = temp * sat->sgps.aycof;
	xlt = xl + xll;
	ayn = sat->deep_arg.em * sin (sat->deep_arg.omgadf) + aynl;

	/* Solve Kepler's Equation */
	capu = FMod2p (xlt - sat->deep_arg.xnode);
	temp2 = capu;

	i = 0;
	do {
		sinepw = sin (temp2);
		cosepw = cos (temp2);
		temp3 = axn * sinepw;
		temp4 = ayn * cosepw;
		temp5 = axn * cosepw;
		temp6 = ayn * sinepw;
		epw = (capu - temp4 + temp3 - temp2) / (1.0 - temp5 - temp6) + temp2;
		if (fabs (epw-temp2) <= e6a)
			break;
		temp2 = epw;
	}
	     while (i++ < 10);

	/* Short period preliminary quantities */
	ecose = temp5 + temp6;
	esine = temp3 - temp4;
	elsq = axn * axn + ayn * ayn;
	temp = 1.0 - elsq;
	pl = a * temp;
	r = a * (1.0 - ecose);
	temp1 = 1.0 / r;
	rdot = xke * sqrt (a) * esine * temp1;
	rfdot = xke * sqrt (pl) *temp1;
	temp2 = a * temp1;
	betal = sqrt (temp);
	temp3 = 1.0 / (1.0 + betal);
	cosu = temp2 * (cosepw - axn + ayn * esine * temp3);
	sinu = temp2 * (sinepw - ayn - axn * esine * temp3);
	u = AcTan (sinu, cosu);
	sin2u = 2.0 * sinu * cosu;
	cos2u = 2.0 * cosu * cosu - 1.0;
	temp = 1.0 / pl;
	temp1 = ck2 * temp;
	temp2 = temp1 * temp;

	/* Update for short periodics */
	rk = r * (1.0 - 1.5 * temp2 * betal * sat->sgps.x3thm1) +
	     0.5 * temp1 * sat->sgps.x1mth2 * cos2u;
	uk = u - 0.25 * temp2 * sat->sgps.x7thm1 * sin2u;
	xnodek = sat->deep_arg.xnode + 1.5 * temp2 * sat->deep_arg.cosio * sin2u;
	xinck = sat->deep_arg.xinc + 1.5 * temp2 *
	     sat->deep_arg.cosio * sat->deep_arg.sinio * cos2u;
	rdotk = rdot - sat->deep_arg.xn * temp1 * sat->sgps.x1mth2 * sin2u;
	rfdotk = rfdot + sat->deep_arg.xn * temp1 *
	     (sat->sgps.x1mth2 * cos2u + 1.5 * sat->sgps.x3thm1);

	/* Orientation vectors */
	sinuk = sin (uk);
	cosuk = cos (uk);
	sinik = sin (xinck);
	cosik = cos (xinck);
	sinnok = sin (xnodek);
	cosnok = cos (xnodek);
	xmx = -sinnok * cosik;
	xmy = cosnok * cosik;
	ux = xmx * sinuk + cosnok * cosuk;
	uy = xmy * sinuk + sinnok * cosuk;
	uz = sinik * sinuk;
	vx = xmx * cosuk - cosnok * sinuk;
	vy = xmy * cosuk - sinnok * sinuk;
	vz = sinik*cosuk;

	/* Position and velocity */
	sat->pos.x = rk * ux;
	sat->pos.y = rk * uy;
	sat->pos.z = rk * uz;
	sat->vel.x = rdotk * ux + rfdotk * vx;
	sat->vel.y = rdotk * uy + rfdotk * vy;
	sat->vel.z = rdotk * uz + rfdotk * vz;

	/* Phase in rads */
	sat->phase = xlt - sat->deep_arg.xnode - sat->deep_arg.omgadf + twopi;
	if (sat->phase < 0.0)
		sat->phase += twopi;
	sat->phase = FMod2p (sat->phase);

	sat->tle.omegao1 = sat->deep_arg.omgadf;
	sat->tle.xincl1  = sat->deep_arg.xinc;
	sat->tle.xnodeo1 = sat->deep_arg.xnode;
} /* SDP4 */

/*------------------------------------------------------------------*/

/* DEEP */
/* This function is used by SDP4 to add lunar and solar */
/* perturbation effects to deep-space orbit objects.    */
void
Deep (int ientry, sat_t *sat)
{

	double
		a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,ainv2,alfdp,aqnv,
		sgh,sini2,sinis,sinok,sh,si,sil,day,betdp,dalf,
		bfact,c,cc,cosis,cosok,cosq,ctem,f322,zx,zy,
		dbet,dls,eoc,eq,f2,f220,f221,f3,f311,f321,xnoh,
		f330,f441,f442,f522,f523,f542,f543,g200,g201,
		g211,pgh,ph,s1,s2,s3,s4,s5,s6,s7,se,sel,ses,xls,
		g300,g310,g322,g410,g422,g520,g521,g532,g533,gam,
		sinq,sinzf,sis,sl,sll,sls,stem,temp,temp1,x1,x2,
		x2li,x2omi,x3,x4,x5,x6,x7,x8,xl,xldot,xmao,xnddt,
		xndot,xno2,xnodce,xnoi,xomi,xpidot,z1,z11,z12,z13,
		z2,z21,z22,z23,z3,z31,z32,z33,ze,zf,zm,zn,
		zsing,zsinh,zsini,zcosg,zcosh,zcosi,delt=0,ft=0;

	switch (ientry) {
	case dpinit : /* Entrance for deep space initialization */
		sat->dps.thgr = ThetaG (sat->tle.epoch, &sat->deep_arg);
		eq = sat->tle.eo;
		sat->dps.xnq = sat->deep_arg.xnodp;
		aqnv = 1.0 / sat->deep_arg.aodp;
		sat->dps.xqncl = sat->tle.xincl;
		xmao = sat->tle.xmo;
		xpidot = sat->deep_arg.omgdot + sat->deep_arg.xnodot;
		sinq = sin (sat->tle.xnodeo);
		cosq = cos (sat->tle.xnodeo);
		sat->dps.omegaq = sat->tle.omegao;
		sat->dps.preep = 0;

		/* Initialize lunar solar terms */
		day = sat->deep_arg.ds50 + 18261.5;  /*Days since 1900 Jan 0.5*/
		if (day != sat->dps.preep) {
			sat->dps.preep = day;
			xnodce = 4.5236020 - 9.2422029E-4 * day;
			stem = sin (xnodce);
			ctem = cos (xnodce);
			sat->dps.zcosil = 0.91375164 - 0.03568096 * ctem;
			sat->dps.zsinil = sqrt (1.0 - sat->dps.zcosil * sat->dps.zcosil);
			sat->dps.zsinhl = 0.089683511 * stem / sat->dps.zsinil;
			sat->dps.zcoshl = sqrt (1.0 - sat->dps.zsinhl * sat->dps.zsinhl);
			c = 4.7199672 + 0.22997150 * day;
			gam = 5.8351514 + 0.0019443680 * day;
			sat->dps.zmol = FMod2p (c - gam);
			zx = 0.39785416 * stem / sat->dps.zsinil;
			zy = sat->dps.zcoshl * ctem + 0.91744867 * sat->dps.zsinhl * stem;
			zx = AcTan (zx,zy);
			zx = gam + zx - xnodce;
			sat->dps.zcosgl = cos (zx);
			sat->dps.zsingl = sin (zx);
			sat->dps.zmos = 6.2565837 + 0.017201977 * day;
			sat->dps.zmos = FMod2p (sat->dps.zmos);
		} /* End if(day != preep) */

		/* Do solar terms */
		sat->dps.savtsn = 1E20;
		zcosg = zcosgs;
		zsing = zsings;
		zcosi = zcosis;
		zsini = zsinis;
		zcosh = cosq;
		zsinh = sinq;
		cc = c1ss;
		zn = zns;
		ze = zes;
		xnoi = 1.0 / sat->dps.xnq;

		/* Loop breaks when Solar terms are done a second */
		/* time, after Lunar terms are initialized        */
		for(;;) {
			/* Solar terms done again after Lunar terms are done */
			a1 = zcosg * zcosh + zsing * zcosi * zsinh;
			a3 = -zsing * zcosh + zcosg * zcosi * zsinh;
			a7 = -zcosg * zsinh + zsing * zcosi * zcosh;
			a8 = zsing * zsini;
			a9 = zsing * zsinh + zcosg * zcosi * zcosh;
			a10 = zcosg * zsini;
			a2 = sat->deep_arg.cosio * a7 + sat->deep_arg.sinio * a8;
			a4 = sat->deep_arg.cosio * a9 + sat->deep_arg.sinio * a10;
			a5 = -sat->deep_arg.sinio * a7 + sat->deep_arg.cosio * a8;
			a6 = -sat->deep_arg.sinio*a9+ sat->deep_arg.cosio*a10;
			x1 = a1*sat->deep_arg.cosg+a2*sat->deep_arg.sing;
			x2 = a3*sat->deep_arg.cosg+a4*sat->deep_arg.sing;
			x3 = -a1*sat->deep_arg.sing+a2*sat->deep_arg.cosg;
			x4 = -a3*sat->deep_arg.sing+a4*sat->deep_arg.cosg;
			x5 = a5*sat->deep_arg.sing;
			x6 = a6*sat->deep_arg.sing;
			x7 = a5*sat->deep_arg.cosg;
			x8 = a6*sat->deep_arg.cosg;
			z31 = 12*x1*x1-3*x3*x3;
			z32 = 24*x1*x2-6*x3*x4;
			z33 = 12*x2*x2-3*x4*x4;
			z1 = 3*(a1*a1+a2*a2)+z31*sat->deep_arg.eosq;
			z2 = 6*(a1*a3+a2*a4)+z32*sat->deep_arg.eosq;
			z3 = 3*(a3*a3+a4*a4)+z33*sat->deep_arg.eosq;
			z11 = -6*a1*a5+sat->deep_arg.eosq*(-24*x1*x7-6*x3*x5);
			z12 = -6*(a1*a6+a3*a5)+ sat->deep_arg.eosq*
				(-24*(x2*x7+x1*x8)-6*(x3*x6+x4*x5));
			z13 = -6*a3*a6+sat->deep_arg.eosq*(-24*x2*x8-6*x4*x6);
			z21 = 6*a2*a5+sat->deep_arg.eosq*(24*x1*x5-6*x3*x7);
			z22 = 6*(a4*a5+a2*a6)+ sat->deep_arg.eosq*
				(24*(x2*x5+x1*x6)-6*(x4*x7+x3*x8));
			z23 = 6*a4*a6+sat->deep_arg.eosq*(24*x2*x6-6*x4*x8);
			z1 = z1+z1+sat->deep_arg.betao2*z31;
			z2 = z2+z2+sat->deep_arg.betao2*z32;
			z3 = z3+z3+sat->deep_arg.betao2*z33;
			s3 = cc*xnoi;
			s2 = -0.5*s3/sat->deep_arg.betao;
			s4 = s3*sat->deep_arg.betao;
			s1 = -15*eq*s4;
			s5 = x1*x3+x2*x4;
			s6 = x2*x3+x1*x4;
			s7 = x2*x4-x1*x3;
			se = s1*zn*s5;
			si = s2*zn*(z11+z13);
			sl = -zn*s3*(z1+z3-14-6*sat->deep_arg.eosq);
			sgh = s4*zn*(z31+z33-6);
			sh = -zn*s2*(z21+z23);
			if (sat->dps.xqncl < 5.2359877E-2)
				sh = 0;
			sat->dps.ee2 = 2*s1*s6;
			sat->dps.e3 = 2*s1*s7;
			sat->dps.xi2 = 2*s2*z12;
			sat->dps.xi3 = 2*s2*(z13-z11);
			sat->dps.xl2 = -2*s3*z2;
			sat->dps.xl3 = -2*s3*(z3-z1);
			sat->dps.xl4 = -2*s3*(-21-9*sat->deep_arg.eosq)*ze;
			sat->dps.xgh2 = 2*s4*z32;
			sat->dps.xgh3 = 2*s4*(z33-z31);
			sat->dps.xgh4 = -18*s4*ze;
			sat->dps.xh2 = -2*s2*z22;
			sat->dps.xh3 = -2*s2*(z23-z21);

			if (sat->flags & LUNAR_TERMS_DONE_FLAG)
				break;

			/* Do lunar terms */
			sat->dps.sse = se;
			sat->dps.ssi = si;
			sat->dps.ssl = sl;
			sat->dps.ssh = sh/sat->deep_arg.sinio;
			sat->dps.ssg = sgh-sat->deep_arg.cosio*sat->dps.ssh;
			sat->dps.se2 = sat->dps.ee2;
			sat->dps.si2 = sat->dps.xi2;
			sat->dps.sl2 = sat->dps.xl2;
			sat->dps.sgh2 = sat->dps.xgh2;
			sat->dps.sh2 = sat->dps.xh2;
			sat->dps.se3 = sat->dps.e3;
			sat->dps.si3 = sat->dps.xi3;
			sat->dps.sl3 = sat->dps.xl3;
			sat->dps.sgh3 = sat->dps.xgh3;
			sat->dps.sh3 = sat->dps.xh3;
			sat->dps.sl4 = sat->dps.xl4;
			sat->dps.sgh4 = sat->dps.xgh4;
			zcosg = sat->dps.zcosgl;
			zsing = sat->dps.zsingl;
			zcosi = sat->dps.zcosil;
			zsini = sat->dps.zsinil;
			zcosh = sat->dps.zcoshl*cosq+sat->dps.zsinhl*sinq;
			zsinh = sinq*sat->dps.zcoshl-cosq*sat->dps.zsinhl;
			zn = znl;
			cc = c1l;
			ze = zel;
			sat->flags |= LUNAR_TERMS_DONE_FLAG;
		} /* End of for(;;) */

		sat->dps.sse = sat->dps.sse+se;
		sat->dps.ssi = sat->dps.ssi+si;
		sat->dps.ssl = sat->dps.ssl+sl;
		sat->dps.ssg = sat->dps.ssg+sgh-sat->deep_arg.cosio/sat->deep_arg.sinio*sh;
		sat->dps.ssh = sat->dps.ssh+sh/sat->deep_arg.sinio;

		/* Geopotential resonance initialization for 12 hour orbits */
		sat->flags &= ~RESONANCE_FLAG;
		sat->flags &= ~SYNCHRONOUS_FLAG;

		if( !((sat->dps.xnq < 0.0052359877) && (sat->dps.xnq > 0.0034906585)) ) {
			if( (sat->dps.xnq < 0.00826) || (sat->dps.xnq > 0.00924) )
				return;
			if (eq < 0.5)
				return;
			sat->flags |= RESONANCE_FLAG;
			eoc = eq*sat->deep_arg.eosq;
			g201 = -0.306-(eq-0.64)*0.440;
			if (eq <= 0.65) {
				g211 = 3.616-13.247*eq+16.290*sat->deep_arg.eosq;
				g310 = -19.302+117.390*eq-228.419*
					sat->deep_arg.eosq+156.591*eoc;
				g322 = -18.9068+109.7927*eq-214.6334*
					sat->deep_arg.eosq+146.5816*eoc;
				g410 = -41.122+242.694*eq-471.094*
					sat->deep_arg.eosq+313.953*eoc;
				g422 = -146.407+841.880*eq-1629.014*
					sat->deep_arg.eosq+1083.435*eoc;
				g520 = -532.114+3017.977*eq-5740*
					sat->deep_arg.eosq+3708.276*eoc;
			}
			else {
				g211 = -72.099+331.819*eq-508.738*
					sat->deep_arg.eosq+266.724*eoc;
				g310 = -346.844+1582.851*eq-2415.925*
					sat->deep_arg.eosq+1246.113*eoc;
				g322 = -342.585+1554.908*eq-2366.899*
					sat->deep_arg.eosq+1215.972*eoc;
				g410 = -1052.797+4758.686*eq-7193.992*
					sat->deep_arg.eosq+3651.957*eoc;
				g422 = -3581.69+16178.11*eq-24462.77*
					sat->deep_arg.eosq+ 12422.52*eoc;
				if (eq <= 0.715)
					g520 = 1464.74-4664.75*eq+3763.64*sat->deep_arg.eosq;
				else
					g520 = -5149.66+29936.92*eq-54087.36*
						sat->deep_arg.eosq+31324.56*eoc;
			} /* End if (eq <= 0.65) */

			if (eq < 0.7) {
				g533 = -919.2277+4988.61*eq-9064.77*
					sat->deep_arg.eosq+5542.21*eoc;
				g521 = -822.71072+4568.6173*eq-8491.4146*
					sat->deep_arg.eosq+5337.524*eoc;
				g532 = -853.666+4690.25*eq-8624.77*
					sat->deep_arg.eosq+ 5341.4*eoc;
			}
			else {
				g533 = -37995.78+161616.52*eq-229838.2*
					sat->deep_arg.eosq+109377.94*eoc;
				g521 = -51752.104+218913.95*eq-309468.16*
					sat->deep_arg.eosq+146349.42*eoc;
				g532 = -40023.88+170470.89*eq-242699.48*
					sat->deep_arg.eosq+115605.82*eoc;
			} /* End if (eq <= 0.7) */

			sini2 = sat->deep_arg.sinio*sat->deep_arg.sinio;
			f220 = 0.75*(1+2*sat->deep_arg.cosio+sat->deep_arg.theta2);
			f221 = 1.5*sini2;
			f321 = 1.875*sat->deep_arg.sinio*(1-2*\
						      sat->deep_arg.cosio-3*sat->deep_arg.theta2);
			f322 = -1.875*sat->deep_arg.sinio*(1+2*
						       sat->deep_arg.cosio-3*sat->deep_arg.theta2);
			f441 = 35*sini2*f220;
			f442 = 39.3750*sini2*sini2;
			f522 = 9.84375*sat->deep_arg.sinio*(sini2*(1-2*sat->deep_arg.cosio-5*
							       sat->deep_arg.theta2)+0.33333333*(-2+4*sat->deep_arg.cosio+
											     6*sat->deep_arg.theta2));
			f523 = sat->deep_arg.sinio*(4.92187512*sini2*(-2-4*
								  sat->deep_arg.cosio+10*sat->deep_arg.theta2)+6.56250012
						*(1+2*sat->deep_arg.cosio-3*sat->deep_arg.theta2));
			f542 = 29.53125*sat->deep_arg.sinio*(2-8*
							 sat->deep_arg.cosio+sat->deep_arg.theta2*
							 (-12+8*sat->deep_arg.cosio+10*sat->deep_arg.theta2));
			f543 = 29.53125*sat->deep_arg.sinio*(-2-8*sat->deep_arg.cosio+
							 sat->deep_arg.theta2*(12+8*sat->deep_arg.cosio-10*
									   sat->deep_arg.theta2));
			xno2 = sat->dps.xnq*sat->dps.xnq;
			ainv2 = aqnv*aqnv;
			temp1 = 3*xno2*ainv2;
			temp = temp1*root22;
			sat->dps.d2201 = temp*f220*g201;
			sat->dps.d2211 = temp*f221*g211;
			temp1 = temp1*aqnv;
			temp = temp1*root32;
			sat->dps.d3210 = temp*f321*g310;
			sat->dps.d3222 = temp*f322*g322;
			temp1 = temp1*aqnv;
			temp = 2*temp1*root44;
			sat->dps.d4410 = temp*f441*g410;
			sat->dps.d4422 = temp*f442*g422;
			temp1 = temp1*aqnv;
			temp = temp1*root52;
			sat->dps.d5220 = temp*f522*g520;
			sat->dps.d5232 = temp*f523*g532;
			temp = 2*temp1*root54;
			sat->dps.d5421 = temp*f542*g521;
			sat->dps.d5433 = temp*f543*g533;
			sat->dps.xlamo = xmao+sat->tle.xnodeo+sat->tle.xnodeo-sat->dps.thgr-sat->dps.thgr;
			bfact = sat->deep_arg.xmdot+sat->deep_arg.xnodot+
				sat->deep_arg.xnodot-thdt-thdt;
			bfact = bfact+sat->dps.ssl+sat->dps.ssh+sat->dps.ssh;
		} /* if( !(sat->dps.xnq < 0.0052359877) && (sat->dps.xnq > 0.0034906585) ) */
		else {
			sat->flags |= RESONANCE_FLAG;
			sat->flags |= SYNCHRONOUS_FLAG;
			/* Synchronous resonance terms initialization */
			g200 = 1+sat->deep_arg.eosq*(-2.5+0.8125*sat->deep_arg.eosq);
			g310 = 1+2*sat->deep_arg.eosq;
			g300 = 1+sat->deep_arg.eosq*(-6+6.60937*sat->deep_arg.eosq);
			f220 = 0.75*(1+sat->deep_arg.cosio)*(1+sat->deep_arg.cosio);
			f311 = 0.9375*sat->deep_arg.sinio*sat->deep_arg.sinio*
				(1+3*sat->deep_arg.cosio)-0.75*(1+sat->deep_arg.cosio);
			f330 = 1+sat->deep_arg.cosio;
			f330 = 1.875*f330*f330*f330;
			sat->dps.del1 = 3*sat->dps.xnq*sat->dps.xnq*aqnv*aqnv;
			sat->dps.del2 = 2*sat->dps.del1*f220*g200*q22;
			sat->dps.del3 = 3*sat->dps.del1*f330*g300*q33*aqnv;
			sat->dps.del1 = sat->dps.del1*f311*g310*q31*aqnv;
			sat->dps.fasx2 = 0.13130908;
			sat->dps.fasx4 = 2.8843198;
			sat->dps.fasx6 = 0.37448087;
			sat->dps.xlamo = xmao+sat->tle.xnodeo+sat->tle.omegao-sat->dps.thgr;
			bfact = sat->deep_arg.xmdot+xpidot-thdt;
			bfact = bfact+sat->dps.ssl+sat->dps.ssg+sat->dps.ssh;
		} /* End if( !(xnq < 0.0052359877) && (xnq > 0.0034906585) ) */

		sat->dps.xfact = bfact-sat->dps.xnq;

		/* Initialize integrator */
		sat->dps.xli = sat->dps.xlamo;
		sat->dps.xni = sat->dps.xnq;
		sat->dps.atime = 0;
		sat->dps.stepp = 720;
		sat->dps.stepn = -720;
		sat->dps.step2 = 259200;
		/* End case dpinit: */
		return;

	case dpsec: /* Entrance for deep space secular effects */
		sat->deep_arg.xll = sat->deep_arg.xll+sat->dps.ssl*sat->deep_arg.t;
		sat->deep_arg.omgadf = sat->deep_arg.omgadf+sat->dps.ssg*sat->deep_arg.t;
		sat->deep_arg.xnode = sat->deep_arg.xnode+sat->dps.ssh*sat->deep_arg.t;
		sat->deep_arg.em = sat->tle.eo+sat->dps.sse*sat->deep_arg.t;
		sat->deep_arg.xinc = sat->tle.xincl+sat->dps.ssi*sat->deep_arg.t;
		if (sat->deep_arg.xinc < 0) {
			sat->deep_arg.xinc = -sat->deep_arg.xinc;
			sat->deep_arg.xnode = sat->deep_arg.xnode + pi;
			sat->deep_arg.omgadf = sat->deep_arg.omgadf-pi;
		}
		if( ~sat->flags & RESONANCE_FLAG ) return;

		do {
			if( (sat->dps.atime == 0) ||
			    ((sat->deep_arg.t >= 0) && (sat->dps.atime < 0)) || 
			    ((sat->deep_arg.t < 0) && (sat->dps.atime >= 0)) ) {
				/* Epoch restart */
				if( sat->deep_arg.t >= 0 )
					delt = sat->dps.stepp;
				else
					delt = sat->dps.stepn;

				sat->dps.atime = 0;
				sat->dps.xni = sat->dps.xnq;
				sat->dps.xli = sat->dps.xlamo;
			}
			else {	  
				if( fabs(sat->deep_arg.t) >= fabs(sat->dps.atime) ) {
					if ( sat->deep_arg.t > 0 )
						delt = sat->dps.stepp;
					else
						delt = sat->dps.stepn;
				}
			}

			do {
				if ( fabs(sat->deep_arg.t-sat->dps.atime) >= sat->dps.stepp ) {
					sat->flags |= DO_LOOP_FLAG;
					sat->flags &= ~EPOCH_RESTART_FLAG;
				}
				else {
					ft = sat->deep_arg.t-sat->dps.atime;
					sat->flags &= ~DO_LOOP_FLAG;
				}

				if( fabs(sat->deep_arg.t) < fabs(sat->dps.atime) ) {
					if (sat->deep_arg.t >= 0)
						delt = sat->dps.stepn;
					else
						delt = sat->dps.stepp;
					sat->flags |= (DO_LOOP_FLAG | EPOCH_RESTART_FLAG);
				}

				/* Dot terms calculated */
				if (sat->flags & SYNCHRONOUS_FLAG) {
					xndot = sat->dps.del1*sin(sat->dps.xli-sat->dps.fasx2)+sat->dps.del2*sin(2*(sat->dps.xli-sat->dps.fasx4))
						+sat->dps.del3*sin(3*(sat->dps.xli-sat->dps.fasx6));
					xnddt = sat->dps.del1*cos(sat->dps.xli-sat->dps.fasx2)+2*sat->dps.del2*cos(2*(sat->dps.xli-sat->dps.fasx4))
						+3*sat->dps.del3*cos(3*(sat->dps.xli-sat->dps.fasx6));
				}
				else {
					xomi = sat->dps.omegaq+sat->deep_arg.omgdot*sat->dps.atime;
					x2omi = xomi+xomi;
					x2li = sat->dps.xli+sat->dps.xli;
					xndot = sat->dps.d2201*sin(x2omi+sat->dps.xli-g22)
						+sat->dps.d2211*sin(sat->dps.xli-g22)
						+sat->dps.d3210*sin(xomi+sat->dps.xli-g32)
						+sat->dps.d3222*sin(-xomi+sat->dps.xli-g32)
						+sat->dps.d4410*sin(x2omi+x2li-g44)
						+sat->dps.d4422*sin(x2li-g44)
						+sat->dps.d5220*sin(xomi+sat->dps.xli-g52)
						+sat->dps.d5232*sin(-xomi+sat->dps.xli-g52)
						+sat->dps.d5421*sin(xomi+x2li-g54)
						+sat->dps.d5433*sin(-xomi+x2li-g54);
					xnddt = sat->dps.d2201*cos(x2omi+sat->dps.xli-g22)
						+sat->dps.d2211*cos(sat->dps.xli-g22)
						+sat->dps.d3210*cos(xomi+sat->dps.xli-g32)
						+sat->dps.d3222*cos(-xomi+sat->dps.xli-g32)
						+sat->dps.d5220*cos(xomi+sat->dps.xli-g52)
						+sat->dps.d5232*cos(-xomi+sat->dps.xli-g52)
						+2*(sat->dps.d4410*cos(x2omi+x2li-g44)
						    +sat->dps.d4422*cos(x2li-g44)
						    +sat->dps.d5421*cos(xomi+x2li-g54)
						    +sat->dps.d5433*cos(-xomi+x2li-g54));
				} /* End of if (isFlagSet(SYNCHRONOUS_FLAG)) */

				xldot = sat->dps.xni+sat->dps.xfact;
				xnddt = xnddt*xldot;

				if(sat->flags & DO_LOOP_FLAG) {
					sat->dps.xli = sat->dps.xli+xldot*delt+xndot*sat->dps.step2;
					sat->dps.xni = sat->dps.xni+xndot*delt+xnddt*sat->dps.step2;
					sat->dps.atime = sat->dps.atime+delt;
				}
			}
			while ( (sat->flags & DO_LOOP_FLAG) &&
				(~sat->flags & EPOCH_RESTART_FLAG));
		}
		while ((sat->flags & DO_LOOP_FLAG) && (sat->flags & EPOCH_RESTART_FLAG));

		sat->deep_arg.xn = sat->dps.xni+xndot*ft+xnddt*ft*ft*0.5;
		xl = sat->dps.xli+xldot*ft+xndot*ft*ft*0.5;
		temp = -sat->deep_arg.xnode+sat->dps.thgr+sat->deep_arg.t*thdt;

		if (~sat->flags & SYNCHRONOUS_FLAG)
			sat->deep_arg.xll = xl+temp+temp;
		else
			sat->deep_arg.xll = xl-sat->deep_arg.omgadf+temp;

		return;
		/*End case dpsec: */

	case dpper: /* Entrance for lunar-solar periodics */
		sinis = sin(sat->deep_arg.xinc);
		cosis = cos(sat->deep_arg.xinc);
		if (fabs(sat->dps.savtsn-sat->deep_arg.t) >= 30) {
			sat->dps.savtsn = sat->deep_arg.t;
			zm = sat->dps.zmos+zns*sat->deep_arg.t;
			zf = zm+2*zes*sin(zm);
			sinzf = sin(zf);
			f2 = 0.5*sinzf*sinzf-0.25;
			f3 = -0.5*sinzf*cos(zf);
			ses = sat->dps.se2*f2+sat->dps.se3*f3;
			sis = sat->dps.si2*f2+sat->dps.si3*f3;
			sls = sat->dps.sl2*f2+sat->dps.sl3*f3+sat->dps.sl4*sinzf;
			sat->dps.sghs = sat->dps.sgh2*f2+sat->dps.sgh3*f3+sat->dps.sgh4*sinzf;
			sat->dps.shs = sat->dps.sh2*f2+sat->dps.sh3*f3;
			zm = sat->dps.zmol+znl*sat->deep_arg.t;
			zf = zm+2*zel*sin(zm);
			sinzf = sin(zf);
			f2 = 0.5*sinzf*sinzf-0.25;
			f3 = -0.5*sinzf*cos(zf);
			sel = sat->dps.ee2*f2+sat->dps.e3*f3;
			sil = sat->dps.xi2*f2+sat->dps.xi3*f3;
			sll = sat->dps.xl2*f2+sat->dps.xl3*f3+sat->dps.xl4*sinzf;
			sat->dps.sghl = sat->dps.xgh2*f2+sat->dps.xgh3*f3+sat->dps.xgh4*sinzf;
			sat->dps.sh1 = sat->dps.xh2*f2+sat->dps.xh3*f3;
			sat->dps.pe = ses+sel;
			sat->dps.pinc = sis+sil;
			sat->dps.pl = sls+sll;
		}

		pgh = sat->dps.sghs+sat->dps.sghl;
		ph = sat->dps.shs+sat->dps.sh1;
		sat->deep_arg.xinc = sat->deep_arg.xinc+sat->dps.pinc;
		sat->deep_arg.em = sat->deep_arg.em+sat->dps.pe;

		if (sat->dps.xqncl >= 0.2) {
			/* Apply periodics directly */
			ph = ph/sat->deep_arg.sinio;
			pgh = pgh-sat->deep_arg.cosio*ph;
			sat->deep_arg.omgadf = sat->deep_arg.omgadf+pgh;
			sat->deep_arg.xnode = sat->deep_arg.xnode+ph;
			sat->deep_arg.xll = sat->deep_arg.xll+sat->dps.pl;
		}
		else {
			/* Apply periodics with Lyddane modification */
			sinok = sin(sat->deep_arg.xnode);
			cosok = cos(sat->deep_arg.xnode);
			alfdp = sinis*sinok;
			betdp = sinis*cosok;
			dalf = ph*cosok+sat->dps.pinc*cosis*sinok;
			dbet = -ph*sinok+sat->dps.pinc*cosis*cosok;
			alfdp = alfdp+dalf;
			betdp = betdp+dbet;
			sat->deep_arg.xnode = FMod2p(sat->deep_arg.xnode);
			xls = sat->deep_arg.xll+sat->deep_arg.omgadf+cosis*sat->deep_arg.xnode;
			dls = sat->dps.pl+pgh-sat->dps.pinc*sat->deep_arg.xnode*sinis;
			xls = xls+dls;
			xnoh = sat->deep_arg.xnode;
			sat->deep_arg.xnode = AcTan(alfdp,betdp);

			/* This is a patch to Lyddane modification */
			/* suggested by Rob Matson. */
			if(fabs(xnoh-sat->deep_arg.xnode) > pi) {
				if(sat->deep_arg.xnode < xnoh)
					sat->deep_arg.xnode +=twopi;
				else
					sat->deep_arg.xnode -=twopi;
			}

			sat->deep_arg.xll = sat->deep_arg.xll+sat->dps.pl;
			sat->deep_arg.omgadf = xls-sat->deep_arg.xll-cos(sat->deep_arg.xinc)*
				sat->deep_arg.xnode;
		} /* End case dpper: */
		return;

	} /* End switch(ientry) */

} /* End of Deep() */

/*------------------------------------------------------------------*/

/* Functions for testing and setting/clearing flags */

/* An int variable holding the single-bit flags */
static int Flags = 0;

int
isFlagSet(int flag)
{
  return (Flags & flag);
}

int
isFlagClear(int flag)
{
  return (~Flags & flag);
}

void
SetFlag(int flag)
{
  Flags |= flag;
}

void
ClearFlag(int flag)
{
  Flags &= ~flag;
}

/*------------------------------------------------------------------*/
