//////////////////////////////////////////////////////////////////////////////////////////
/// \class RAT::SNOAV
///
/// \brief G4VSolid geometry class describing the SNO acrylic vessel.
///
/// \author Aksel Hallin aksel.hallin@ualberta.ca
///
/// Revision History: \n
/// 2014-06-30  Aksel Hallin
///
///\detail This class describes the outer surface of the acrylic vessel, including the neck, belly plates, and rope grooves. It is typically
/// the mother class of a SNOSV, which describes the inner acrylic/scintillator volumes and boundaries.
///
/////////////////////////////////////////////////////////////////////////////////////////

#ifndef __RAT_SNOAV__
#define __RAT_SNOAV__

#include <RAT/SphericalSubregionList.hh>
#include <G4VSolid.hh>
#include <list>

namespace RAT{
class SNOAV:public SphericalSubregionList{
public:

    /// Constructor
    /// @param[in] aTitle  Name of this solid.  This is the name in the geometry definition file (eg. snoplusalh2.geo)
    SNOAV(const G4String &aTitle);
    /// Implementation of the G4VSolid method.
    /// @param[in] EAxis The axis
    G4bool CalculateExtent(const EAxis, const G4VoxelLimits &, const G4AffineTransform &, G4double &, G4double &) const;
    /// Implements the G4VSolid method
    G4Polyhedron* CreatePolyhedron() const;
    /// Implements the G4VSolid method
    void DescribeYourselfTo(G4VGraphicsScene &)const;
    /// Routine that is used by both DistanceToIn and DistanceToOut to calculate next intersection
    /// Finds the distance to the next intersection by looking up the reference position=p+referenceDistance*n.  It goes through the relevent
    /// list of subregions, to see if there are any intersections at a value less than the proposedDistance.
    /// @param[in]p The starting point
    /// @param[in]v The direction of the path of the particle
    /// @returns Distance to the intersection, or the proposed distance if no intersection is found.
    G4double DistanceToNext(const G4ThreeVector &p, const G4ThreeVector &v, NextMode aNextMode)const;
    G4GeometryType GetEntityType(void)const;
    /// Implements the G4VSolid method
    G4VisExtent GetExtent() const;
    /// Implements the G4VSolid method
    G4ThreeVector GetPointOnSurface() const;
    /// Implements the G4VSolid method
    EInside Inside(const G4ThreeVector &p)const;
    /// Implements the G4VSolid method
    std::ostream& StreamInfo(std::ostream &)const;
        /// Implements the G4VSolid method
    G4ThreeVector SurfaceNormal(const G4ThreeVector &p, G4bool &isValid)const;
    G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const{ G4bool isValid=false; return SurfaceNormal(p,isValid);}
private:
    class SNOAVBellyPlate *fBellyPlates[10];  ///< List of BellyPlates
    G4double fRadii[2];  ///< Radii to check for spherical intersections.  Basically the outer diameter of the AV and the outer diameter of the belly plates.
    G4double fNeckZ1, fNeckZ2, fNeckZ3; ///< location of base, top of neck boss and top of neck;
    G4double fNeckOuterRadius;  ///< (cylindrical) radius of neck
    G4double fNeckBossOuterRadius; ///< cylindrical radius
    G4int iAddBellyPlates;
};
} //::RAT
#endif