/***************************************************************************
                          planetmoons.h  -  description
                             -------------------
    begin                : Sat Mar 13 2009
                         : by Vipul Kumar Singh, Médéric Boquien
    email                : vipulkrsingh@gmail.com, mboquien@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef PLANETMOONS_H_
#define PLANETMOONS_H_

#include <QString>
#include <QVector>

class KSNumbers;
class KSPlanet;
class KSSun;
class TrailObject;
class dms;

/**
  *@class PlanetMoons
  *Implements the moons of a planet.
  *
  *TODO: make the moons SkyObjects, rather than just points.
  *
  *@author Vipul Kumar Singh
  *@version 1.0
  */
class PlanetMoons {
public:
    /**
      *Constructor.  Assign the name of each moon,
      *and initialize their XYZ positions to zero.
      */
    PlanetMoons();

    /**
      *Destructor.  Delete moon objects.
      */
     virtual ~PlanetMoons();

    /**
      *@return pointer to a moon given the ID number.
      *@param id which moon?
      */
    inline TrailObject* moon( int id ) { return Moon[id]; }

    /**
      *@return the name of a moon.
      *@param id which moon?
      */
    QString name( int id ) const;

    /**
      *@return pointer to a moon, given its name:
      *@param name the name of the moon (Io, Europa, Ganymede, Callisto)
      */
    TrailObject* moonNamed( const QString &name ) const;

    /**
      *Convert the RA,Dec coordinates of each moon to Az,Alt
      *@param LSTh pointer to the current local sidereal time
      *@param lat pointer to the geographic latitude
      */
    void EquatorialToHorizontal( const dms *LSTh, const dms *lat );
    
    /**
      *@short Find the positions of each Moon, relative to the planet.
      *We use an XYZ coordinate system, centered on the planet,
      *where the X-axis corresponds to the planet's Equator, 
      *the Y-Axis is parallel to the planet's Poles, and the 
      *Z-axis points along the line joining the Earth and 
      *the planet. Once the XYZ positions are known, this 
      *function also computes the RA, Dec positions of each 
      *Moon, and sets the inFront bool variable to indicate 
      *whether the Moon is nearer to us than the planet or not
      *(this information is used to determine whether the 
      *Moon should be drawn on top of the planet, or vice versa).
      *
      *@param num pointer to the KSNumbers object describing 
      *the date/time at which to find the positions.
      *@param pla pointer to the planet object
      *@param sunptr pointer to the Sun object
      */
    virtual void findPosition( const KSNumbers *num, const KSPlanet *pla, const KSSun *sunptr )=0;

    /**
      *@return true if the Moon is nearer to Earth than Saturn.
      *@param id which moon? 0=Mimas,1=Enceladus,2=Tethys,3=Dione,4=Rhea,5=Titan,6=Hyperion,7=Lapetus
      */
    inline bool inFront( int id ) const { return InFront[id]; }    
    
    /**
      *@return the X-coordinate in the planet-centered coord. system.
      *@param i which moon?
      */
    double x( int i ) const { return XP[i]; }

    /**
      *@return the Y-coordinate in the planet-centered coord. system.
      *@param i which moon?
      */
    double y( int i ) const { return YP[i]; }

    /**
      *@return the Z-coordinate in the Planet-centered coord. system.
      *@param i which moon?
      */
    double z( int i ) const { return ZP[i]; }
    
    /**
      *@return the number of moons around the planet
      */
    int nMoons( ) const { return Moon.size(); }
    
  protected:
    QVector<TrailObject*> Moon;
    QVector<bool> InFront;
    //the rectangular position, relative to the planet. X-axis is equator of the planet; units are planet Radius
    QVector<double> XP, YP, ZP;
    
  private:
    PlanetMoons(const PlanetMoons&);
    PlanetMoons& operator = (const PlanetMoons&);
    };
#endif
