program shift_main
  use gildas_def
  use gbl_format
  use image_def
  use gkernel_interfaces
  !---------------------------------------------------------------------
  ! GILDAS
  !	Main program for shifting a 2D image by phase factor in Fourier plane.
  !---------------------------------------------------------------------
  ! Local
  character(len=*), parameter :: pname = 'SHIFT'
  real(8), parameter :: pi=3.141592653589793d0
  !
  character(len=filename_length) :: namex,namey
  logical :: error
  real :: xx,yy,xshift,yshift
  complex :: shift
  integer :: i, j, nxy, ndim, dims(2), ier
  complex, allocatable :: cdata(:,:)
  real, allocatable :: work(:), rdata(:,:)
  type(gildas) :: x,y
  !
  call gildas_open
  call gildas_char('Y_NAME$',namey)
  call gildas_char('X_NAME$',namex)
  call gildas_real('X_SHIFT$',xshift,1)
  call gildas_real('Y_SHIFT$',yshift,1)
  call gildas_close
  !
  call gildas_null(y)
  call gdf_read_gildas(y,namey,'.gdf',error,data=.false.)
  if (error) then
    write(6,*) 'F-'//pname//',  Cannot read input file '//trim(y%file) 
    goto 100
  endif
  !
  call gildas_null(x)
  call gdf_copy_header(y,x,error)
  call sic_parsef(namex,x%file,' ','.gdf')
  call gdf_create_image(x,error)
  if (error) then
    write(6,*) 'F-'//pname//',  Cannot create output image'
    goto 100
  endif
  !
  ! Check if work space is needed.
  nxy = 2*max(x%gil%dim(1),x%gil%dim(2))
  allocate (work(nxy), cdata(x%gil%dim(1), x%gil%dim(2)), &
       & rdata(x%gil%dim(1), x%gil%dim(2)), stat=ier)
  nxy = x%gil%dim(1)*x%gil%dim(2)
  if (ier.ne.0) goto 100
  !
  ! Compute shift factor
  xx = 2.d0*pi*xshift/x%gil%inc(1)
  yy = 2.d0*pi*yshift/x%gil%inc(2)
  shift = cmplx(cos(xx),sin(xx))*cmplx(cos(yy),sin(yy))
  !
  ! Prepare FFTW
  dims = x%gil%dim(1:2)
  ndim = 2
  call fourt_plan (cdata,dims,ndim,1,0)
  call fourt_plan (cdata,dims,ndim,-1,1)
  !
  do j=1,x%gil%dim(4)
    x%blc(4) = j
    x%trc(4) = j
    do i=1,x%gil%dim(3)
      x%blc(3) = i
      x%trc(3) = i
      y%blc = x%blc
      y%trc = x%trc
      call gdf_read_data(y,rdata,error)
      !
      cdata(:,:) = cmplx(rdata,0.0)
      call fourt(cdata,dims,ndim,1,0,work)
      cdata(:,:) = cdata*shift         ! Apply phase shift
      call fourt(cdata,dims,ndim,-1,+1,work) 
      rdata(:,:) = real(cdata)/nxy     ! Normalize fft
      !
      call gdf_write_data(x,rdata,error)
    enddo
  enddo
  call gagout ('S-'//pname//',  Successful completion')
  call sysexi (1)
  !
100 call sysexi (fatale)
end program shift_main
