#ifndef __JANGLE3D__
#define __JANGLE3D__

#include <cmath>

#include "JIO/JSerialisable.hh"
#include "JGeometry2D/JAngle2D.hh"


namespace JGEOMETRY3D {

  namespace {
    using JIO::JReader;
    using JIO::JWriter;
    using JGEOMETRY2D::JAngle2D;
  }


  /**
   * Data structure for angles in three dimensions.
   */
  class JAngle3D :
    public JAngle2D
  {
  public:
    /**
     * Default constructor.
     */
    JAngle3D() :
      JAngle2D(0.0),
      __theta (0.0)
    {}


    /**
     * Constructor.
     *
     * \param  theta    theta angle [rad]
     * \param  phi      phi   angle [rad]
     */
    JAngle3D(const double theta,
	     const double phi) :
      JAngle2D(phi),
      __theta (theta)
    {}


    /**
     * Read JAngle3D from input.
     *
     * \param  in         JReader
     * \param  angle      JAngle3D
     * \return            JReader
     */
    friend inline JReader& operator>>(JReader& in, JAngle3D& angle)
    {
      in >> angle.__theta;
      in >> static_cast<JAngle2D&>(angle);

      return in;
    }


    /**
     * Write JAngle3D to output.
     *
     * \param  out        JWriter
     * \param  angle      JAngle3D
     * \return            JWriter
     */
    friend inline JWriter& operator<<(JWriter& out, const JAngle3D& angle)
    {
      out << angle.__theta;
      out << static_cast<const JAngle2D&>(angle);

      return out;
    }


    /**
     * Get theta angle.
     *
     * \return          theta angle
     */
    double getTheta() const { return __theta; }


    /**
     * Get x direction.
     *
     * \return          x direction
     */
    double getDX() const { return sin(__theta) * cos(__phi); }


    /**
     * Get y direction.
     *
     * \return          y direction
     */
    double getDY() const { return sin(__theta) * sin(__phi); }


    /**
     * Get z direction.
     *
     * \return          y direction
     */
    double getDZ() const { return cos(__theta); }


  protected:
    double __theta;
  };
}

#endif