            // JavaScript MoonPhase and SunSign
            // Aion, 12.1.2000 
            // MoonPhases and Sun positions are proximate only.

            // Julian Day Routines by Tim Harris

            // This is a growing collection of astronomical routines written in JavaScript
            // that can be used by other web-page authors. Most are adapted from other
            // sources who are referenced.  

            // toInt() - our own casting routine that always truncates the number passed
            //               in regardless of sign.

            function toInt(number)

            {
            var negative = false;

            if (number < 0)

                negative = true;

            number = Math.floor(Math.abs(number));

            if (negative)

                number *= -1;

            return number;
            }


            // julianDay() - takes in year, month and date and returns the julian day number
            //                 will return -1 on an illegal incoming date.  
            //

            function julianDay(year, month, date)
            {
            var a;  //  components of julian day formula
            var b = 0;
            var c;
            var d;
            var nDate;
            var nMonth;
            var nYear;
            var nJulDay;

            // first get everything into the proper format to avoid weirdo casting rules
            // inherent in JavaScript

            nYear = parseInt(year);
            nMonth = parseInt(month);

            // check to see what format our date is in and get it in a numeric state

            // if (date.indexOf(".") > 0)
            if (date > 0)
                {nDate = parseFloat(date);}
            else
            {nDate = parseInt(date);}       

            // do some basic error handling for illegal dates you can't have year 0 in Julian 

            // if (nYear == 0)
            //      return -1;

            // do basic adjustments on month & year

            if (nYear < 1)
            {nYear  += 1;}

            if (nMonth < 3)
            {nMonth += 12;
            nYear-= 1;}

            // now deal with the gregorian calendar changes 
            // first check for illegal dates from Oct. 5-14 , 1582  

            if (nYear == 1582 && nMonth == 10  && (nDate >= 5 || nDate <= 14)) 
                return -1;

            if (nYear > 1582 || (nYear == 1582 && (nMonth > 10 || (nMonth == 10 && nDate > 15))))
            {
                // follow rules to generate component b

                a = Math.floor(nYear / 100);
                b = 2 - a + Math.floor(a / 4);
            }

            // follow rules to generate components c & d

            if (year > 0)
                c = Math.floor(365.25 * nYear) - 694025;
            else
                c = toInt((365.25 * nYear) - 0.75) - 694025;
            d = Math.floor(30.6001 * (nMonth + 1));
            julday = b + c + d + nDate + 2415020.0 - 0.5;
            return julday;
            }

            // calcMoonAge() - calculate the age of the moon in days from new
            //
            // Adapted from MOON EFFECTS BASIC application by Bradley E. Schaefer
            // from Sky & Telescope magazine, April 1994.

            function calcMoonAge(year, month, date)

            {
            var jDate;
            var tempVal;

            // get julian date and fudge it a bit, this is a hueristic algorithm 
            // and isn't exact science.

            jDate = julianDay(year, month, date)+ 0.5;
            tempVal = (jDate - 2451550.1) / 29.530588853;
            tempVal -= Math.floor(tempVal);
            if (tempVal < 0) tempVal += 1;
            age = (tempVal * 29.530588853);
            return age;
            }

            // based on formula in Foundations of Astronomy, 1999 ed.
            // doMoonPhase() - the calcMoonAge function to get a simple output of phase 

            function doMoonPhase(MoonAge)
            { 
            // do simple phase output 
            if (age <= 0.5) return "new"
            if (age > 0.5 && age < 7.0) return "waxing cresent"
            if (age > 7.0 && age < 8.0) return "first quarter"
            if (age > 8.0 && age < 14.0) return "waxing"
            if (age > 14.0 && age < 15.0) return "full"
            if (age > 15.0 && age < 21.5) return "waning"
            if (age > 21.5 && age < 22.7) return "last quarter"
            if (age > 22.7 && age < 29.5) return "waning cresent"
            if (age >= 29.5) return "new"
            }

            function makeArray()    {
            this[0] = makeArray.arguments.length;
            for (i = 0; i<makeArray.arguments.length; i++)
            this[i+1] = makeArray.arguments[i];
            }


            var monthNames = new makeArray('Jan.','Feb.','Mar.','Apr.','May','June','July','Aug.','Sept.','Oct.','Nov.','Dec.');
            var daysofmonth   = new makeArray( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
            var daysofmonthLY = new makeArray( 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
            var horoscopes = new makeArray( 21, 20, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22);
            var starsigns   = new makeArray('Capricorn','Aquarius','Pisces','Aries','Taurus','Gemini','Cancer','Leo','Virgo','Libra','Scorpio','Sagittarius');                       
            var dayNames   = new makeArray('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');

            // 2yk fix

            function y2k(number) 
            { 
            return (number < 1000) ? number + 1900 : number; 
            }

            function LeapYear(year) {
            if ((year/4)   != Math.floor(year/4))   return false;
            if ((year/100) != Math.floor(year/100)) return true;
            if ((year/400) != Math.floor(year/400)) return false;
            return true;
            }

            function ValidDate(day,month,year) {
            if ( (LeapYear(year) && (day > daysofmonthLY[month])) ||
            (!LeapYear(year) && (day > daysofmonth[month])) )
            return false;
            else
            return true;
            }


            function StarSign(day,month) {
            if (day < horoscopes[month])
            return month;
            else if (month == 12)
            return 1;
            else
            return month + 1;
            }
                 
            function getLongDate(dateObj)
            {       
            theDay = dayNames[dateObj.getDay()+1]
            theMonth = monthNames[dateObj.getMonth()+1]
            theDate = dateObj.getDate()
            // needs y2k fix to work for all browsers 
            // theYear = dateObj.getYear()
            theYear = y2k(dateObj.getYear())
            return ""+theDay+", <br />"+theMonth+" "+theDate+", "+theYear
            }

            function getMidDate(dateObj)
            {       
            theDay = dayNames[dateObj.getDay()+1]
            theMonth = monthNames[dateObj.getMonth()+1]
            theDate = dateObj.getDate()
            // needs y2k fix to work for all browsers 
            // theYear = dateObj.getYear()
            theYear = y2k(dateObj.getYear())
            return ""+theMonth+" "+theDate+", "+theYear
            }
                
            function getNextFull(moonAge)
            {       
            currMilSecs = (new Date()).getTime()
            daysToGo = 14.73 - moonAge
            while(daysToGo<2)
            {       
                daysToGo = daysToGo+29.53
            }
            milSecsToGo = daysToGo*24*60*60*1000
            nextMoonTime = currMilSecs+milSecsToGo
            nextMoonDate = new Date(nextMoonTime)
            return nextMoonDate
            }
                
            function getNextNew(moonAge)
            {       
            currMilSecs = (new Date()).getTime()
            daysToGo = 29.53 - moonAge
            while(daysToGo<2)
            {       
                daysToGo = daysToGo+29.53
            }
            milSecsToGo = daysToGo*24*60*60*1000
            nextMoonTime = currMilSecs+milSecsToGo
            nextMoonDate = new Date(nextMoonTime)
            return nextMoonDate
            }

