subroutine tspace_diago(vstate,vstate_r,fc)
! this subroutine solves teh BSE equation in transition space

USE bse_wannier, ONLY : num_nbndv
USE transitions, ONLY : ttab,itiv,itic,exch
USE wvfct,       ONLY : nbnd
USE io_global,   ONLY : stdout,ionode
USE kinds,       ONLY : DP
USE constants,   ONLY : RYTOEV
USE mp,          ONLY : mp_barrier
USE mp_world,             ONLY : world_comm
USE bse_basic_structures 
USE fft_custom_gwl 


implicit none
type(v_state) vstate
type(v_state_r) vstate_r
type(fft_cus) :: fc

integer                         :: nt,it ! number of transitions
real(kind=DP),    allocatable   :: eig(:)

! for zheev
integer                         :: info
real(kind=DP), allocatable   :: work(:)

call start_clock('tspace_diago')
! compute the number of transitions
nt=num_nbndv(1)*(nbnd-num_nbndv(1))
if(ionode) write(stdout,*) 'number of transitions nt:', nt

! allocate and build the transition table (c,v)-->it
allocate(ttab(nbnd,num_nbndv(1)))
allocate(itiv(nt))
allocate(itic(nt))

call build_ttab

! allocate and build the excitonic Hamiltonian in transition space
allocate(exch(nt,nt))
exch(1:nt,1:nt)=0.d0

call mp_barrier(world_comm)
call build_exch(vstate,vstate_r,fc)

call mp_barrier(world_comm)
! diagonalize (not parallel so only one proc will do it)

allocate(eig(nt))
if(ionode) then
   allocate(work(3*nt-1))
   call dsyev('V', 'U', nt, exch, nt, eig, work, 3*nt-1 , info)
   eig(1:nt)=eig(1:nt)*RYTOEV 
   deallocate(work)
endif

call mp_barrier(world_comm)

if(ionode) then
   do it=1,nt 
      write(stdout,*) 'Eigenvalue number', it, eig(it)
   enddo
endif

deallocate(ttab,itic,itiv,exch,eig)
call stop_clock('tspace_diago')
return
end subroutine

!--------------------!
subroutine build_exch(vstate,vstate_r,fc)
!this subroutine builds the excitonic Hamiltonian in transition space

USE bse_wannier,           ONLY : num_nbndv
USE wvfct,                 ONLY : nbnd, npwx,npw,et
USE lsda_mod,              ONLY : nspin
USE wavefunctions,  ONLY : evc
USE io_files,              ONLY : prefix, iunwfc, nwordwfc
USE transitions,           ONLY : ttab,exch
USE io_global,             ONLY : stdout,ionode
USE bse_basic_structures 
USE fft_custom_gwl 
USE exciton 


implicit none
type(v_state),intent(in)    :: vstate
type(v_state_r), intent(in) :: vstate_r
type(fft_cus), intent(in)   :: fc

!internal
type(exc) :: phic
type(exc) :: phicp
type(exc) :: hphic
integer   :: iv,ivp,ic,icp,is

call start_clock('build_exch')

call initialize_exc(phic)
phic%label=1
phic%npw=npw
phic%numb_v=num_nbndv(1)
allocate(phic%a(phic%npw,phic%numb_v))

call initialize_exc(hphic)
hphic%label=1
hphic%npw=npw
hphic%numb_v=num_nbndv(1)
allocate(hphic%a(hphic%npw,hphic%numb_v))

call initialize_exc(phicp)
phicp%label=1
phicp%npw=npw
phicp%numb_v=num_nbndv(1)
allocate(phicp%a(phicp%npw,phicp%numb_v))

allocate( evc( npwx, nbnd ) )

!read wavefunctions
do is=1,nspin
   call davcio(evc,2*nwordwfc,iunwfc,is,-1)
enddo

if(ionode) write(stdout,*) 'wfns read from disk'

do iv=1,num_nbndv(1)
   do ic=num_nbndv(1)+1,nbnd
      
      if(ionode) write(stdout,*) 'iv ic', iv, ic
      phic%a(1:phic%npw,1:phic%numb_v)=dcmplx(0.d0,0.d0)
      phic%a(1:phic%npw,iv)=evc(1:npw,ic)
      call normalize_exc(phic)
      !apply tyhe excitonic Hamiltonian to this ic,iv state
      call exc_h_a(phic,hphic,vstate,vstate_r,fc) 
     
      do ivp=iv,num_nbndv(1)
          do icp= ic,nbnd
             if(ionode) write(stdout,*) 'ivp icp', ivp, icp
             phicp%a(1:phicp%npw,1:phicp%numb_v)=dcmplx(0.d0,0.d0)
             phicp%a(1:phicp%npw,ivp)=evc(1:npw,icp)
             call normalize_exc(phicp)
             call sproduct_exc(phicp,hphic,exch(ttab(ic,iv),ttab(icp,ivp)))
             if(ionode) write(stdout,*) 'Exc. Hamiltonian built for transition:', ttab(ic,iv),ttab(icp,ivp) 
          enddo !icp
      enddo !ivp
   enddo !ic
enddo !iv

call free_memory_exc_a(phic)
deallocate(evc)

call stop_clock('build_exch')
return
endsubroutine

!--------------------!
subroutine build_ttab
!this subroutine builds the transition table

USE wvfct,    ONLY : nbnd
USE bse_wannier, ONLY:num_nbndv
use transitions, ONLY:ttab,itiv,itic
USE io_global, ONLY : stdout,ionode

implicit none
integer       :: it,iv,ic

it=1

do iv=1,num_nbndv(1)
   do ic=num_nbndv(1)+1,nbnd
      ttab(ic,iv)=it
      itiv(it)=iv
      itic(it)=ic
      it=it+1
   enddo
enddo

it=it-1

if(ionode) write(stdout,*) 'ttab built, number of transitions found:', it
if(ionode) write(stdout,*) 'total number of bands', nbnd
if(ionode) write(stdout,*) 'number of valence bands', num_nbndv(1)
return
end subroutine
!--------------------!
