!///////////////////////////////////////////////////////////////////
!//
!// class_circle.f90
!//
!// A module contianing type definitons for a circle and
!// a sphere used as an object
!//
!///////////////////////////////////////////////////////////////////


MODULE class_circle
  IMPLICIT NONE
  !// Only procedures which is a part of the module has
  !// access to the subroutines inside this module
  PRIVATE
  !// A type construct for a circle
  TYPE, PUBLIC                     :: circle
    !// The radius
    REAL                           :: radius
    !// The pi value
    REAL                           :: pi = (4*ATAN(1.))
    !// Containing the circumference after calculation
    REAL                           :: circumference = 0.
    !// Containing the surface area after calculation
    REAL                           :: surface_area = 0.
  CONTAINS
    !// The two procedures with aliases pointg to the
    !// subroutines peroforming the calculations
    PROCEDURE                      :: circ => calc_circum
    PROCEDURE                      :: area => calc_area
  END TYPE circle
  
  !// A type construct for a sphere using the circle
  !// as the parent class
  TYPE, PUBLIC, EXTENDS(circle)    :: sphere
    REAL                           :: volume = 0.
  CONTAINS
    PROCEDURE                      :: spvol => calc_volume  
  END TYPE sphere
CONTAINS

  !// Procedures belonging to the two classes
  SUBROUTINE calc_circum(this)
    !// An instance of the class circle
    CLASS(circle)                  :: this
    !// Calculate the circumference for this instance
    !// of class circle
    this%circumference = 2. * this%radius * this%pi
  END SUBROUTINE calc_circum

  SUBROUTINE calc_area(this)
    !// An instance of the class circle
    CLASS(circle)                  :: this
    !// Calculate the area for this instance
    !// of class circle
    this%surface_area = this%pi * this%radius**2
  END SUBROUTINE calc_area

  SUBROUTINE calc_volume(this)
    !// An instance of the class sphere
    CLASS(sphere)                  :: this
    !// Calculate the volume for this instance
    !// of class sphere
    this%volume = 4./3. * this%pi * this%radius**3
  END SUBROUTINE calc_volume
END MODULE class_circle