!///////////////////////////////////////////////////////////////////
!//
!// class_example.f90
!//
!// A module contianing type definitons for a circle, sphere,
!// a rectangle and a box
!//
!///////////////////////////////////////////////////////////////////

MODULE class_example
  IMPLICIT NONE
  PRIVATE
  !// Define the circle class
  TYPE, PUBLIC                     :: circle
    !// The radius
    REAL(KIND=8)                   :: radius
    !// the value of pi initialized using a formula
    REAL(KIND=8)                   :: pi = 4.0D0*ATAN(1.0D0)
    !// The circumference initialized to zero
    REAL(KIND=8)                   :: circumference = 0.0D0
    !// The surface_area initialized to zero
    REAL(KIND=8)                   :: surface_area = 0.0D0
  CONTAINS
    !// The procedure names assocoated with the subroutines
    PROCEDURE                      :: circ => calc_circum
    PROCEDURE                      :: area => calc_area
  END TYPE circle
  
  TYPE, PUBLIC, EXTENDS(circle)    :: sphere
    !// The volume initialized to zero
    REAL(KIND=8)                   :: volume = 0.0D0
  CONTAINS
    !// The procedure name assocoated with the subroutine
    PROCEDURE                      :: spvol => calc_volume
  END TYPE sphere
  
  TYPE, PUBLIC                     :: rectangle
    !// The length in the x-direction
    REAL(KIND=8)                   :: x_direction
    !// The length in the y-direction
    REAL(KIND=8)                   :: y_direction
    !// The area initialized to zero
    REAL(KIND=8)                   :: area = 0.0D0
  CONTAINS
    !// The procedure name assocoated with the subroutine
    PROCEDURE                      :: rarea => rect_area
  END TYPE rectangle
  
  TYPE, PUBLIC, EXTENDS(rectangle) :: box
    !// The length of the height of the box
    REAL(KIND=8)                   :: height
    !// The volume initialized to zero
    REAL(KIND=8)                   :: volume = 0.0D0
  CONTAINS
    !// The procedure name assocoated with the subroutine
    PROCEDURE                      :: bvol => box_volume
  END TYPE box
  
CONTAINS

  !// Subroutine to calculate the circumference of the
  !// circle
  SUBROUTINE calc_circum(this)
    CLASS(circle)               :: this
    this%circumference = 2. * this%radius * this%pi
  END SUBROUTINE calc_circum

  !// Subroutine to calculate the area of the
  !// circle
  SUBROUTINE calc_area(this)
    CLASS(circle)               :: this
    this%surface_area = this%pi * this%radius**2
  END SUBROUTINE calc_area
  
  !// Subroutine to calculate the volume of the
  !// spher
  SUBROUTINE calc_volume(this)
    CLASS(sphere)               :: this
    this%volume = 4./3. * this%pi * this%radius**3
  END SUBROUTINE calc_volume
  
  !// Subroutine to calculate the area of the
  !// rectangle
  SUBROUTINE rect_area(this)
    CLASS(rectangle)            :: this
    this%area = this%x_direction * this%y_direction
  END SUBROUTINE rect_area
  
  !// Subroutine to calculate the volume of the
  !// box
  SUBROUTINE box_volume(this)
    CLASS(box)                  :: this
    this%volume = this%x_direction * this%y_direction &
                  * this%height
  END SUBROUTINE box_volume
END MODULE class_example