!-------------------------------------------------
!  CTRlib Module
!-------------------------------------------------
module ctrlib
  use dcl_common

  interface DclConv2D
    module procedure DclP2C, DclE2C, DclB2C, DclH2C
  end interface
  private :: DclP2C, DclE2C, DclB2C, DclH2C

  contains
!-------------------------------------------------
  function DclP2C(point)    !極座標->直角座標
    type(polar), intent(in) :: point 
    type(cartesian)         :: DclP2C

    call prcopn('DclConv2D')
    call ct2pc(point%r, point%theta, DclP2C%x, DclP2C%y)
    call prccls('DclConv2D')
  end function
!-------------------------------------------------
  function DclE2C(point)  !楕円座標->直角座標
    type(elliptic), intent(in) :: point
    type(cartesian)            :: DclE2C

    call prcopn('DclConv2D')
    call ct2ec(point%u, point%v, DclE2C%x, DclE2C%y)
    call prccls('DclConv2D')
  end function
!-------------------------------------------------
  function DclB2C(point)   !双極座標->直角座標
    type(bipolar), intent(in) :: point
    type(cartesian)           :: DclB2C

    call prcopn('DclConv2D')
    call ct2bc(point%u, point%v,DclB2C%x, DclB2C%y)
    call prccls('DclConv2D')
  end function
!-------------------------------------------------
  function DclH2C(point)    !直角双曲線座標->直角座標
    type(hyperbolic), intent(in) :: point
    type(cartesian)              :: DclH2C

    call prcopn('DclConv2D')
    call ct2hc(point%u, point%v, DclH2C%x, DclH2C%y)   
    call prccls('DclConv2D')
  end function
!-------------------------------------------------
  function DclConvPolar(point)  !直角座標->極座標
    type(cartesian), intent(in) :: point
    type(polar)                 :: DclConvPolar

    call prcopn('DclConvPolar')
    call ct2cp(point%x, point%y, DclConvPolar%r, DclConvPolar%theta)
    call prccls('DclConvPolar')
  end function
!-------------------------------------------------
  function DclConvHyperbolic(point)   !直角双曲線座標->直角座標
    type(cartesian), intent(in) :: point
    type(hyperbolic)            :: DclConvHyperbolic

    call prcopn('DclConvHyperbolic')
    call ct2ch(point%x, point%y, DclConvHyperbolic%u, DclConvHyperbolic%v) 
    call prccls('DclConvHyperbolic')
  end function
!-------------------------------------------------
  function DclConv3D(point)   !3次元球面座標->直角座標
    type(spherical),intent(in) :: point
    type(cartesian3D)          :: DclConv3D

    call prcopn('DclConv3D')
    call ct3sc(point%r, point%theta, point%phi, &
           &   DclConv3D%x, DclConv3D%y,     DclConv3D%z) 
    call prccls('DclConv3D')
  end function
!-------------------------------------------------
  function DclConvSpherical(point)    !3次元球面座標と直角座標の変換をする．
    type(cartesian3D), intent(in) :: point
    type(spherical)               :: DclConvSpherical

    call prcopn('DclConvSpherical')
    call ct3cs(point%x, point%y, point%z, & 
      &DclConvSpherical%r, DclConvSpherical%theta, DclConvSpherical%phi)
    call prccls('DclConvSpherical')
  end function
!-------------------------------------------------
  function DclRotate2D(theta,point)   !2次元直角座標を回転する．
    real, intent(in) :: theta
    type(cartesian), intent(in) :: point
    type(cartesian)             :: DclRotate2D

    call prcopn('DclRotate2D')
    call cr2c(theta, point%x, point%y, &
            & DclRotate2D%x, DclRotate2D%y) 
    call prccls('DclRotate2D')
  end function
!-------------------------------------------------
  function DclRotate3D(theta,phi,psi, point) !3次元直角座標を回転する．
    real,        intent(in) :: theta, phi, psi   !euler の回転角 (θ, φ, ψ)
    type(cartesian3D), intent(in) :: point
    type(cartesian3D)             :: DclRotate3D
    
    call prcopn('DclRotate3D')
    call cr3c(theta,phi,psi, point%x, point%y, point%z, &
          &   DclRotate3D%x, DclRotate3D%y, DclRotate3D%z)
    call prccls('DclRotate3D')
  end function
!-------------------------------------------------
  function DclRotateSpherical(theta,phi,psi,point) !球面座標を回転する．
    real,      intent(in) :: theta, phi, psi           !euler の回転角 (θ, φ, ψ)
    type(spherical), intent(in) :: point
    type(spherical)             :: DclRotateSpherical

    call prcopn('DclRotateSpherical')
    DclRotateSpherical%r = point%r
    call cr3s(theta,phi,psi, point%theta, point%phi, &
      & DclRotateSpherical%theta, DclRotateSpherical%phi)
    call prccls('DclRotateSpherical')
  end function

end module
