!***********************************************************************************
!	MODULE:	EulerEquation
!
!	PURPOSE: Contains subroutine EulerEq
!
!	AUTHOR:	Ben Malin
!
!	DATE:	6/2004
!       REVISED: 7/27/2007
!
!***********************************************************************************

module EulerEquation
  
  use Params
  use StaticFOC
  implicit none
  
contains
  
  !***********************************************************************************
  !
  !	SUBROUTINE:  EulerEq
  !
  !	PURPOSE: Specifies system of equations whose solution is the updated
  !               policy function.  These are the equilibrium conditions of the model.
  !
  !	AUTHOR:	 Ben Malin 
  !
  !	DATE:    6/2004
  !     REVISED: 7/27/2007
  !
  !***********************************************************************************

  subroutine EulerEq(pol,EulEq,count)
    
    ! inputs:
    !    pol -- Holds guess of nonlinear equation solver
    !    count -- size of pol vector -- N+1
    !
    ! output:
    !    EulEq -- Values of system of equations evaluated at pol.
    ! 
    ! remarks:
    !    Pol(1) is consumption of country 1.
    !    Pol(1+i) for i = {1,..,N} is tomorrow's capital of country i.
    !
    
    use Params
    use StaticFOC
    implicit none
        
    !Variable Declaration
    integer,intent(in) :: count	
    real(prec),dimension(count),intent(in) :: pol	
    real(prec),dimension(count),intent(out) :: EulEq
    
    integer :: i
    real(prec) :: BigNumb = 100
    real(prec) :: IntResult
    
    !Variables used in nonlinear equation solver to solve for country 1's labor supply
    integer, parameter :: itmaxA = 300
    integer, parameter :: countA = 1
    real(prec) :: RelerrA, fnormA
    real(prec), dimension(countA) :: guessA, finalA

    !Variables used in nonlinear equation solver to solve for cons and labor of countries 2-N
    integer, parameter :: itmaxB = 300
    integer, parameter :: countB = 2
    real(prec) :: RelerrB, fnormB
    real(prec), dimension(countB) :: guessB, finalB

    !IMSL routine used for pausing program in nle solver has an error
    integer, external :: IERCD

    !Initialize inputs to nle solver, DNEQNF
    RelerrA = 0.0001
    fnormA = 0
    guessA = 1.0
    finalA = 1.0

    !Initialize inputs to nle solver, DNEQNF
    RelerrB = 0.0001
    fnormB = 0
    guessB(1) = A_tfp
    guessB(2) = 1.0
    finalB = 1.0

    !Iter1 keeps track of the number of iterations of the nle solver (outer loop)
    iter1 = iter1+1
    
    !Make sure guesses for policy function are not out-of-bounds
    do i = 1,N
!       if (pol(1+i) < kmin(i)) then
!          !print*, 'error: capital below kmin in EulerEq', i, iter1, stind
!          !pause
!          ktemp(i) = kmin(i)    !Sets ktemp(i) at the boundary
!       elseif (pol(1+i) > kmax(i)) then
!          !print*, 'error: capital above kmax in EulerEq', i, iter1, stind
!          !pause
!          ktemp(i) = kmax(i)    !Sets ktemp(i) at the boundary
!       else
!          ktemp(i) = pol(1+i)
!       endif
       ktemp(i) = pol(1+i)
    enddo
    if (pol(1) < 0) then
       print*, 'error: consumption negative in EulerEq', 1, iter1
       pause
       EECons(1) = pol(1)  !Currently no change -- alter if case happens
    else
       EECons(1) = pol(1)
    endif

    !Compute labor supply of country 1
    iter2 = 0	!Used to keep track of number of iterations done by DNEQNF
     
    call DNEQNF(ConsLabOne, RelerrA, countA, itmaxA, guessA, finalA, fnormA)

    if (IERCD() == 3 .or. IERCD() == 1) then
       print*, 'inner loop fails to converge in EulerEquation'
       pause
    end if
     
    EELab(1) = finalA(1)
     
    !Error check to make sure solution is sensible
    if (EELab(1) <= 10.0**(-5)) then
       print*, 'negative labor in EulerEq for country', 1, EELab(1)
       pause
    elseif (EELab(1) > Le) then
       print*, 'labor supply above Le in EulerEq for country', 1, EELab(1)
       pause
    endif
    
    !Compute consumption and labor supply of countries 2 - N.
    do FOCi = 2,N
       iter2 = 0
       guessB(1) = log(EECons(1))
       guessB(2) = log(EELab(1))
       call DNEQNF(ConsLabOther, RelerrB, countB, itmaxB, guessB, finalB, fnormB)

       if (IERCD() == 3 .or. IERCD() == 1) then
          print*, 'inner loop fails to converge in EulerEquation'
          pause
       end if
       
       EECons(FOCi) = exp(finalB(1))
       EELab(FOCi) = exp(finalB(2))
!print*, 'Cons-smooth error'
!print*, Pareto(1)*Uc(EECons(1),EELab(1),1) - Pareto(FOCi)*Uc(EECons(FOCi),EELab(FOCi),FOCi)       
       !Error check to make sure solution is sensible
       if (EECons(FOCi) <= 10.0**(-5)) then
          print*, 'negative consumption in EulerEq for country', FOCi, EECons(FOCi)
          pause
       endif
       if (EELab(FOCi) <= 10.0**(-5)) then
          print*, 'negative labor in EulerEq for country', FOCi, EELab(FOCi)
          pause
       elseif (EELab(FOCi) > Le) then
          print*, 'labor supply above Le in EulerEq for country', FOCi, EELab(FOCi)
          pause
       endif
    end do

    !World Budget Constraint
    EulEq(1) = 0
    do i = 1,N
       EulEq(1) = F(k(stind(i),i),EELab(i),z(stind(N+i),i)) + k(stind(i),i) &
            & - EECons(i) - pol(1+i) - AdjCost(k(stind(i),i),pol(1+i)) + EulEq(1)
    end do

    !Euler Equation for each country
    call ChebPoly(N, ktemp, unitTtemp(:,:))
    
    do i = 1,N
       call MonIntegrate (i,IntResult,1)
       EulEq(1+i) = betah*IntResult/(1 + AdjCost_ktom(k(stind(i),i),ktemp(i))) &
            & - Pareto(1)*Uc(EECons(1),EELab(1),1)
    end do

    !Penalty if guess for capital is out-of-bounds
!    do i = 1,N
!       if (pol(1+i) < kmin(i)) then
!          !print*, EulEq(1+i)
!          EulEq(1+i) = EulEq(1+i) - (pol(1+i) - kmin(i)) * BigNumb
!          !print*, EulEq(1+i), pol(1+i)
!       elseif (pol(1+i) > kmax(i)) then
!          !print*, EulEq(1+i)
!          EulEq(1+i) = EulEq(1+i) + (kmax(i) - pol(1+i)) * BigNumb
!          !print*, EulEq(1+i), pol(1+i)
!       endif
!    enddo

  end subroutine EulerEq

end module EulerEquation
