module LifeSupportInterface
    use FluidInterfaces
    use RealTypes, only:RealType, assignment(=)
    implicit none
    private

    integer, parameter :: intSizePLSS=3
    integer, parameter :: intSizeLCVG=3

    type, public :: PLSSInterface
        type(GasLoop) :: VentLoop
        type(LiquidLoop) :: CoolingLoop
        type(GasLoop) :: BreathingLoop
    contains
        procedure, public :: initialize => initializePLSS
        procedure, public :: associate => associatePLSStoLCVG
        final :: finalizePLSS
    end type

    type, public, extends(PLSSInterface) :: LCVGInterface
        type(RealType) :: ventUAG
        type(RealType) :: liquidUAG
    contains
        procedure, public :: initialize => initializeLCVG
        procedure, public :: associate => associateLCVGtoPLSS
        final :: finalizeLCVG
    end type

    type, public :: EnvironmentInterface
        type(Gas) :: Convection
        type(Fluid) :: Immersion
        type(Vacuum) :: Radiation
    end type


    interface size
        module procedure  sizePLSS
    end interface
    public size

contains

    subroutine initializePLSS(self)
        class(PLSSInterface), intent(inout) :: self
        allocate(GAS::self%VentLoop%Inlet,self%VentLoop%Outlet)
        allocate(LIQUID::self%CoolingLoop%Inlet,self%CoolingLoop%Outlet)
        allocate(GAS::self%BreathingLoop%Inlet,self%BreathingLoop%Outlet)

        print *,allocated(self%VentLoop%Inlet)
        self%VentLoop%Inlet%Temperature=1.0
        self%VentLoop%Inlet%Dewpoint=70.0
        end subroutine

    subroutine associatePLSStoLCVG(self,other)
        class(PLSSInterface), intent(inout) :: self
        class(LCVGInterface), intent(inout) :: other
        call self%VentLoop%Inlet%pointTo(other%VentLoop%Outlet)
        call self%CoolingLoop%Inlet%pointTo(other%CoolingLoop%Outlet)
        call self%VentLoop%Outlet%pointTo(other%VentLoop%Inlet)
        call self%CoolingLoop%Outlet%pointTo(other%CoolingLoop%Inlet)
        call self%BreathingLoop%Inlet%pointTo(other%BreathingLoop%Outlet)
        call self%BreathingLoop%Outlet%pointTo(other%BreathingLoop%Inlet)
        end subroutine

    subroutine finalizePLSS(self)
        type(PLSSInterface), intent(inout) :: self
        deallocate(self%VentLoop%Inlet, self%VentLoop%Outlet)
        deallocate(self%CoolingLoop%Inlet, self%CoolingLoop%Outlet)
        end subroutine

    subroutine initializeLCVG(self)
        class(LCVGInterface), intent(inout) :: self
        call self%PLSSInterface%initialize()
        end subroutine

    subroutine associateLCVGtoPLSS(self,other)
        class(LCVGInterface), intent(inout) :: self
        class(PLSSInterface), intent(inout) :: other
        call other%associate(self)
        end subroutine

    subroutine finalizeLCVG(self)
        type(LCVGInterface), intent(inout) :: self
        deallocate(self%VentLoop%Inlet, self%VentLoop%Outlet)
        deallocate(self%CoolingLoop%Inlet, self%CoolingLoop%Outlet)
        end subroutine

    pure function sizePLSS(self)
        type(PLSSInterface), intent(in) :: self
        integer :: sizePLSS
        sizePLSS=intSizePLSS
        end function

    pure function sizeLCVG(self)
        type(LCVGInterface), intent(in) :: self
        integer :: sizeLCVG
        sizeLCVG=intSizeLCVG
        end function


end module LifeSupportInterface
