module BOP
    contains
    
    subroutine BopStack_Init
        call BOP_StartUp
    end subroutine BopStack_Init

    subroutine BopStack_Step
        use SimulationVariables
        use CBopControlPanel
        use BopVariables
        use SimulationVariables !@
        ! USE CEquipmentsConstants
        use CSounds
        implicit none
    
    
        data%State%BopStackInput%BOP_timeCounter= data%State%BopStackInput%BOP_timeCounter + 1

        write(*,*) 'BOP_timeCounter=' , data%State%BopStackInput%BOP_timeCounter
    
        data%EquipmentControl%BopControlPanel%AirSupplyPressureGauge= (1 - data%State%BopStackAcc%AirSupplyPressureGaugeMalf)* (1 - data%State%BopStackAcc%RigAirMalf) *120. !psi
    
    
        if (data%State%BopStackAcc%pram_reg < 2300.) then
            data%State%ShearRAM%ShearIsNotAllowed= 1
        else
            data%State%ShearRAM%ShearIsNotAllowed= 0
        endif
    
        !write(*,*) 'ShearIsNotAllowed=' , ShearIsNotAllowed
    
    
        !TD_AnnularFillingFinal     ! (0.0 to 1.0) percentage filled by tool joint
    
              
    !======================================================================
    !                        MAIN BODY OF PROGRAM 
    !                        PURPOSE:  BOP Control   
    !======================================================================
    

    !=== Instantaneous Pipe Diameters in Each Ram (Input from TD Module):==
        data%State%Annular%ODDrillpipe_inAnnular= data%State%TD_BOP%AnnularPreventerDiam * 12.0        ! ft to inch
        data%State%PipeRam1%ODDrillpipe_in= data%State%TD_BOP%UpperRamDiam * 12.0  
        data%State%ShearRAM%ODDrillpipe_inShearRam= data%State%TD_BOP%BlindRamDiam * 12.0  
        data%State%PipeRam2%ODDrillpipe_in= data%State%TD_BOP%LowerRamDiam * 12.0   
   
   
   
        !IDshearBopFinal
        !IDPipeRam1Final
        !IDPipeRam2Final
        !IDAnnularFinal
   
        data%State%ShearRAM%OpenArea_shearBop=  PI*(data%State%ShearRAM%IDshearBopFinal**2-data%State%ShearRAM%ODDrillpipe_inShearRam**2)/4.0d0   !D(in), AREA(in^2)
        data%State%ShearRAM%OpenArea_PipeRam1= PI*(data%State%ShearRAM%IDPipeRam1Final**2-data%State%PipeRam1%ODDrillpipe_in**2)/4.0d0   !D(in), AREA(in^2)
        data%State%ShearRAM%OpenArea_PipeRam2= PI*(data%State%ShearRAM%IDPipeRam2Final**2-data%State%PipeRam2%ODDrillpipe_in**2)/4.0d0   !D(in), AREA(in^2)
        data%State%ShearRAM%OpenArea_Annular= PI*(data%State%ShearRAM%IDAnnularFinal**2-data%State%Annular%ODDrillpipe_inAnnular**2)/4.0d0   !D(in), AREA(in^2)
   
        data%State%ShearRAM%MinimumOpenArea_InBOP= min(data%State%ShearRAM%OpenArea_shearBop,data%State%ShearRAM%OpenArea_PipeRam1,data%State%ShearRAM%OpenArea_PipeRam2,data%State%ShearRAM%OpenArea_Annular)
   
        !TD_BOPConnectionPossibility(j)  =  0 or 1
    
        !!!AnnularPreventerDiam = TD_BOPConnectionPossibility(1)  >>   used in Annular code
        !!!UpperRamDiam         = TD_BOPConnectionPossibility(2)  >>   used in PipeRam1 code
        !!!BlindRamDiam         = TD_BOPConnectionPossibility(3)  >>   used in ShearRam code
        !!!LowerRamDiam         = TD_BOPConnectionPossibility(4)  >>   used in PipeRam2 code   

    !=====================================================================
    !============SEALING PRESSURES TO BE SET IN ANNULAR REGULATOR==========
        data%State%AnnularComputational%WellBorePressure=5000.
        if (data%State%Annular%ODDrillpipe_inAnnular>0.) then 
            if (data%State%Annular%ODDrillpipe_inAnnular>0. .and. data%State%Annular%ODDrillpipe_inAnnular<=1.99) then
                data%State%AnnularComputational%acoef=-0.2673
                data%State%AnnularComputational%Bcoef=994.3
                data%State%AnnularComputational%const=77
            elseif (data%State%Annular%ODDrillpipe_inAnnular>1.99 .and. data%State%Annular%ODDrillpipe_inAnnular<=2.375) then
                data%State%AnnularComputational%acoef=-0.2539
                data%State%AnnularComputational%Bcoef=994.3
                data%State%AnnularComputational%const=73.15
            elseif (data%State%Annular%ODDrillpipe_inAnnular>2.375 .and. data%State%Annular%ODDrillpipe_inAnnular<=2.875) then
                data%State%AnnularComputational%acoef=-0.2005
                data%State%AnnularComputational%Bcoef=745.9
                data%State%AnnularComputational%const=57.75
            elseif (data%State%Annular%ODDrillpipe_inAnnular>2.875 .and. data%State%Annular%ODDrillpipe_inAnnular<=3.5) then
                data%State%AnnularComputational%acoef=-0.1871
                data%State%AnnularComputational%Bcoef=696.1
                data%State%AnnularComputational%const=53.9
            elseif (data%State%Annular%ODDrillpipe_inAnnular>3.5 .and. data%State%Annular%ODDrillpipe_inAnnular<=5) then
                data%State%AnnularComputational%acoef=-0.1733
                data%State%AnnularComputational%Bcoef=647
                data%State%AnnularComputational%const=50
            elseif (data%State%Annular%ODDrillpipe_inAnnular>5 .and. data%State%Annular%ODDrillpipe_inAnnular<=10) then
                data%State%AnnularComputational%acoef=-0.1604
                data%State%AnnularComputational%Bcoef=596.7
                data%State%AnnularComputational%const=46.2
            endif
            data%State%AnnularComputational%AnnularSealingPressure= max((data%State%AnnularComputational%acoef*data%State%AnnularComputational%WellBorePressure+data%State%AnnularComputational%Bcoef), data%State%AnnularComputational%const)  !(psi)
        else    !CSO(COMPLETE SHUT OFF) ODDrillpipe_inAnnular=0
            data%State%AnnularComputational%AnnularSealingPressure= 1150. !(psi)
        endif
    
    !=====================================================================
    !                         BYPASS POSITION
    !=====================================================================          
        if(data%EquipmentControl%BopControlPanel%ByePassValve == -1.0 .and. data%EquipmentControl%BopControlPanel%AirMasterValve==1) then
            data%State%BopStackAcc%ByPassOld= -1.0
        !write(*,*) 'ByePassValve to -1' ,ByePassValve        
        elseif(data%EquipmentControl%BopControlPanel%ByePassValve == 1.0 .and. data%EquipmentControl%BopControlPanel%AirMasterValve==1) then
            data%State%BopStackAcc%ByPassOld= 1.0
        !write(*,*) 'ByePassValve to 1=' ,ByePassValve
        endif   
        !write(*,*) 'ByePassValve,ByPassOld=' ,ByePassValve,ByPassOld
    !=====================================================================     
    !WRITE(*,*) 'AnnularRegulatorSetControl====' , AnnularRegulatorSetControl
        data%State%Annular%Pannular_regset=min(data%EquipmentControl%BopControlPanel%AnnularRegulatorSetControl,1700.)  ! for changing its set conditions instantaneously
        if (data%State%Annular%Annular_closed==1) then 
            if (data%State%Annular%FirstSet==1) then      ! code start           
                data%State%Annular%Pannular_reg= data%State%Annular%Pannular_regset
            endif

            if (data%State%Annular%FirstSet==0) then           ! durig run, but annular is not closing or opening
                data%State%Annular%Pannular_reg= min(data%State%RamLine%P_ACC,data%State%Annular%Pannular_regset)          
            endif 
        endif
 
    !===================================================================
    !           Annular Preventer Pressure Rise On Tooljoint 
    !=================================================================== 
        if ( data%State%Annular%Annular_Situation_forTD == 1 .and. data%State%TD_BOP%AnnularFillingFinal==0.0 ) then     ! Annular_Situation_forTD= 1       ! closed - for TD code
            data%State%AnnularComputational%AnnPressureRise= .true.
        elseif ( data%State%Annular%Annular_Situation_forTD == 0 ) then
            data%State%AnnularComputational%AnnPressureRise= .false.
        endif
 
        if (data%State%AnnularComputational%AnnPressureRise == .true.) then
            data%State%Annular%Pannular_reg= data%State%Annular%Pannular_reg + 200. * data%State%TD_BOP%AnnularFillingFinal      ! 200 psi pressure rise when 100% of AnnPreventer is filled by tool joint
            !TD_AnnularFillingFinal     ! (0.0 to 1.0) percentage filled by tool joint 
        endif 
    !=================================================================== 
        if (data%State%Annular%FirstSet== 1) then
            !new= (1 - AnnularPressureGaugeMalf) * min(AnnularRegulatorSetControl,1700.)            
            CALL data%State%AnnularComputational%Pannular_regDelay%AddToFirst( (1 - data%State%Annular%AnnularPressureGaugeMalf) * min(data%EquipmentControl%BopControlPanel%AnnularRegulatorSetControl,1700.) )
            CALL data%State%AnnularComputational%Pannular_regDelay%Remove(data%State%AnnularComputational%Pannular_regDelay%Length())
            data%EquipmentControl%BopControlPanel%AnnularPressureGauge= data%State%AnnularComputational%Pannular_regDelay%Last()
            !AnnularPressureGauge= (1 - AnnularPressureGaugeMalf) * min(AnnularRegulatorSetControl,1700.)
            !write(*,*) 'set 1' , AnnularPressureGauge
        else     !FirstSet== 0
            !new= (1 - AnnularPressureGaugeMalf) * Pannular_reg
             
            CALL data%State%AnnularComputational%Pannular_regDelay%AddToFirst( (1 - data%State%Annular%AnnularPressureGaugeMalf) * data%State%Annular%Pannular_reg)
            CALL data%State%AnnularComputational%Pannular_regDelay%Remove(data%State%AnnularComputational%Pannular_regDelay%Length())
            data%EquipmentControl%BopControlPanel%AnnularPressureGauge= data%State%AnnularComputational%Pannular_regDelay%Last()              
            !AnnularPressureGauge= (1 - AnnularPressureGaugeMalf) * Pannular_reg
            !write(*,*) 'set 0' , AnnularPressureGauge
       endif  
    
    !===================================================
    !                AIR OPERATED PUMP CODE- START
    !===================================================     
         if (data%State%RamLine%P_ACC<data%State%Pumps%AIR_ON .and. data%State%RamLine%AIRP_SWITCH==0) then
             data%State%RamLine%AIRP_SWITCH=1
         endif
 
         if (data%State%RamLine%P_ACC>data%State%Pumps%AIR_OFF .and. data%State%RamLine%AIRP_SWITCH==1) then
             data%State%RamLine%AIRP_SWITCH=0
             call SetSoundKoomeyAirPump(data%State%RamLine%AIRP_SWITCH) 
         endif
 
          if (data%State%RamLine%P_ACC<data%State%Pumps%ELECTRIC_ON .and. data%State%RamLine%ELECP_SWITCH==0) then
             data%State%RamLine%ELECP_SWITCH=1
         endif
 
         if (data%State%RamLine%P_ACC>data%State%Pumps%ELECTRIC_OFF .and. data%State%RamLine%ELECP_SWITCH==1) then
             data%State%RamLine%ELECP_SWITCH=0
         endif

         !write(*,*) 'airp_switch,elecp_switch=' , airp_switch,elecp_switch
        !================CHARGING BOTTLES======================= 
        if (data%State%RamLine%AIRP_SWITCH==1 .or. data%State%RamLine%ELECP_SWITCH==1) then
            if (data%State%Annular%Annular_closed==1 .and. data%State%RamLine%ShearBop_closed==1 .and. data%State%PipeRam1%closed==1 .and. data%State%PipeRam2%closed==1 .and. data%State%ChokeLine%closed==1 .and. data%State%KillLine%closed==1) then
                call pumps_charge_bottle()
                ! increases volume and pressure in the bottles
                if (data%State%RamLine%P_ACC>data%State%BopStackAcc%acc_ChargedPressure) then
                    data%State%RamLine%P_ACC=data%State%BopStackAcc%acc_ChargedPressure
                    if (data%State%Annular%AnnularLeakMalf== 0) then
                        !finished_Annular=1
                        data%State%RAM(1)%Bottles_Charged_MalfActive= .false.
                    else
                            data%State%Annular%finished_Annular=0
                            data%State%RAM(1)%Bottles_Charged_MalfActive= .true.
                            !fvr=fvr-2.5
                    endif
                    if (data%State%PipeRam1%UpperRamsLeakMalf== 0) then
                        !finished_pipe1=1
                        data%State%RAM(2)%Bottles_Charged_MalfActive= .false.
                    else
                            data%State%PipeRam1%finished=0
                            data%State%RAM(2)%Bottles_Charged_MalfActive= .true.
                            !fvr=fvr-2.5
                    endif        
                
                    if (data%State%PipeRam2%LowerRamsLeakMalf== 0) then
                        !finished_pipe2=1
                        data%State%RAM(3)%Bottles_Charged_MalfActive= .false.
                    else
                            data%State%PipeRam2%finished=0
                            data%State%RAM(3)%Bottles_Charged_MalfActive= .true.
                            !fvr=fvr-2.5
                    endif        
                    if (data%State%ShearRAM%MiddleRamsLeakMalf== 0) then
                        !finished_shear=1
                        data%State%RAM(4)%Bottles_Charged_MalfActive= .false.
                    else
                            data%State%RamLine%FINISHED_shear=0
                            data%State%RAM(4)%Bottles_Charged_MalfActive= .true.
                            !fvr=fvr-2.5
                    endif
      
                    data%State%KillLine%finished=1        
                    data%State%ChokeLine%finished=1       
        
        
                    if (data%State%Annular%AnnularLeakMalf== 0 .and. data%State%PipeRam1%UpperRamsLeakMalf== 0 .and. data%State%PipeRam2%LowerRamsLeakMalf== 0 .and. data%State%ShearRAM%MiddleRamsLeakMalf== 0) then
                        data%State%RamLine%ELECP_SWITCH=0
                        data%State%RamLine%AIRP_SWITCH=0
                    endif
                endif
            endif 
        endif  

        !======================================================= 
        if (data%State%RamLine%ELECP_SWITCH==1 .and. data%State%BopStackAcc%AccPupmsFailMalf==0) then  !on position
            data%State%Pumps%DELTAV_ELECP=data%State%Pumps%QELECTRIC*data%State%RamLine%DeltaT_BOP/60.       !QELECTRIC_PUMP(gpm), deltav_elecp(gal), DeltaT_BOP(0.1 sec)
            data%State%Pumps%SoundKoomeyElectric= .True.
        else
            data%State%Pumps%DELTAV_ELECP=0
            data%State%Pumps%SoundKoomeyElectric= .false.   
        endif

        !call SetSoundKoomeyElectricPump(SoundKoomeyElectricPump)
         if (data%State%RamLine%AIRP_SWITCH==1 .and. data%State%BopStackAcc%AccPupmsFailMalf==0) then  !on position
             call airpump_code()   !ramtype=2
         end if   ! if (airp_switch==1) then  !on position


    !===============AIR OPERATED PUMP CODE- END================  
        if (data%State%RamLine%ShearBop_closed==1 .and. data%State%PipeRam1%closed==1 .and. data%State%PipeRam2%closed==1 .and. data%State%ChokeLine%closed==1 .and. data%State%KillLine%closed==1) then
     
            !write(*,*) ' All Rams are closed'
     
            if(data%State%BopStackAcc%ByPassOld== -1.0) then           ! (OPEN POSITION)
                !old=pram_reg
                !new=p_acc- MAXVAL(data%State%RAM%loss_before)
                !difference= new-old
                data%State%BopStackAcc%PressureDifference= data%State%RamLine%P_ACC- MAXVAL(data%State%RAM%loss_before) - data%State%BopStackAcc%pram_reg
                if (ABS(data%State%BopStackAcc%PressureDifference) > BaseDifferenceP) then       !BaseDifferenceP= 300. psi
                    data%State%BopStackAcc%pram_reg= data%State%BopStackAcc%pram_reg + (data%State%BopStackAcc%PressureDifference/PressureDifferenceSteps)      ! PressureDifferenceSteps = 20.
                else
                data%State%BopStackAcc%pram_reg= data%State%RamLine%P_ACC- MAXVAL(data%State%RAM%loss_before)       ! mishe khate paeen ye shart gozasht ke pacc=3000 shod, in adad dige kam nashe
                endif
         
            elseif (data%State%BopStackAcc%ByPassOld== 1.0) then       ! (CLOSE POSITION)
                !pram_reg= prams_regset
                !if (RamsFirstSet==1) then
                    !write(*,*) 'bypass CLOSE POSITION'
                !old=pram_reg
                !new=prams_regset
                !difference= new-old
                data%State%BopStackAcc%PressureDifference= data%State%BopStackAcc%PRAMS_REGSET - data%State%BopStackAcc%pram_reg
                    !write(*,*) 'PressureDifference, prams_regset , pram_reg=' , PressureDifference, prams_regset , pram_reg
         
                if (ABS(data%State%BopStackAcc%PressureDifference) > BaseDifferenceP) then        !BaseDifferenceP= 200. ! psi in starup
                    data%State%BopStackAcc%pram_reg= data%State%BopStackAcc%pram_reg + (data%State%BopStackAcc%PressureDifference/PressureDifferenceSteps)      ! PressureDifferenceSteps = 20. in startup
                else
                data%State%BopStackAcc%pram_reg= data%State%BopStackAcc%PRAMS_REGSET
                endif             
                    !write(*,*) 'pram_reg=' , pram_reg
             
                !endif      ! if (RamsFirstSet==1) then
            endif
     
     
        endif
 
        data%EquipmentControl%BopControlPanel%MiddleRamsStatus = data%State%ShearRAM%IDshearBop
        data%EquipmentControl%BopControlPanel%UpperRamsStatus = data%State%PipeRam1%ID
        data%EquipmentControl%BopControlPanel%LowerRamsStatus = data%State%PipeRam2%ID
        data%EquipmentControl%BopControlPanel%AnnularStatus = data%State%Annular%IDAnnular
        data%EquipmentControl%BopControlPanel%AccumulatorPressureGauge = (1 - data%State%BopStackAcc%AccumulatorPressureGaugeMalf) *   data%State%RamLine%P_ACC
        data%EquipmentControl%BopControlPanel%ManifoldPressureGauge= (1 - data%State%BopStackAcc%ManifoldPressureGaugeMalf) *  data%State%BopStackAcc%pram_reg
        !AnnularPressureGauge=Pannular_reg
        !
        !         WRITE(60,60) data%State%RAM(2)%time,data%State%RAM(2)%Q,data%State%RAM(2)%vdis_tot,p_acc, &
        !         pram_reg,Pannular_reg,data%State%RAM(2)%p_bop,IDshearBop, &
        !         IDPipeRam1,IDPipeRam2,IDAnnular
        !60       FORMAT(11(f18.5))
        !WRITE(*,*) 'IDAnnular=' , IDAnnular
        !write(*,*) 'elecp_switch=' , elecp_switch
        !call sleepqq(100)
    end subroutine BopStack_Step
    
end module BOP