!****************************************************************************
!
!   Program: Main
!
!   Purpose: Runs testing function
!            (uses hybrd.f to solve nonlinear equations)
!
!   Author:  Ben Malin
!
!   Date:    11/2007
!*****************************************************************************
!!$program Main
!!$
!!$  use Params  !Contains global variables/functions
!!$
!!$  implicit none
!!$
!!$  !Variable Declaration
!!$  character(len=6) :: cofile
!!$  character(len=3) :: infile
!!$  character(len=4) :: outfile
!!$
!!$  real(prec),dimension(2*N) :: state
!!$  real(prec),dimension(4*N) :: control
!!$  integer :: i
!!$
!!$  !Sets parameters not initialized in Params
!!$  call ParamUpdate
!!$
!!$  !Read in coefficients of policy functions
!!$  cofile = "coeff2"
!!$  call InCoeffs(cofile)
!!$
!!$  !Read in state variables
!!$  infile = "in1"
!!$  call Input(infile)
!!$  
!!$  !Output
!!$  state = instate  !Note: instate is a global variable.
!!$  call Test(state,control)
!!$  Results = control  !Note: Results is a global variable.
!!$
!!$  !Output results to file
!!$  outfile = "out1"
!!$  call Output(outfile)
!!$
!!$end program Main

!**************************************************************************
!
!    Subroutine:  ParamUpdate
!
!    Purpose:    Constructs country-specific parameters, bounds for state
!                variables, and weights for the interpolation formula.
!**************************************************************************

subroutine ParamUpdate
  
  use Params
  
  implicit none
  
  !Variable Declaration
  integer :: i

 !Constants used in f.o.c. for labor supply
  psi = 1.0/((1.0-alpha) * (Le - 1.0) + 1.0)  
  Lfoc = A_tfp * (1.0-alpha) * psi / (1.0 - psi)
  psigam1 = psi * (1.0 - xgamma)
  psigam2 = (1.0 - psi) * (1.0 - xgamma)

 !Pareto (Negishi) Weights for each country
  lss = 1.0
  do i = 1,N
     Pareto(i) = 1.0 / Uc(A_tfp, lss)
  end do

 !Specify lower and upper bounds for technological shock, e^(z)
  zmin = -0.8 * sigma / (1.0 - rho)    !Note: this may truncate innovations.
  zmax = 0.8 * sigma / (1.0 - rho)
  
 !Compute deterministic steady state (no adjustment costs), 
 !and specify lower and upper bounds for capital stock.
  kss = 1.0
  
  kmin = 0.8*kss
  kmax = 1.2*kss

 !Construct weights for low-dimensional cheb polynomials in smolyak interpolation
  if (d == 2) then
     coc1 = 1
     coc2 = 1
  else 
     coc1 = d-1
     coc2 = (d-1)*(d-2)/2
  endif
 
end subroutine ParamUpdate

!****************************************************************************
!	SUBROUTINE:  InCoeffs
!
!	PURPOSE:  Reads in coefficients for policy rules
!****************************************************************************

subroutine InCoeffs(filename)
  
  ! inputs:
  !   filename -- name of file that contains coefficients for policy rules
  !
  ! output:
  ! 
  ! remarks:

  use Params
  
  implicit none
  
  ! Variable Declaration
  character(len=30), intent(IN) :: filename 
  integer :: i,j,i1,j1

  ! read the data
  !open (1, file = filename//".csv")      ! Open file with name filename
  
  open(unit = 40, file = filename//".csv", status = 'old', action = 'read')
  
  !CoeffsCons3
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsCons3(i,1,j), CoeffsCons3(i,2,j),CoeffsCons3(i,3,j), & 
             & CoeffsCons3(i,4,j), CoeffsCons3(i,5,j)
     end do
  end do
  !CoeffsCap3
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsCap3(i,1,j), CoeffsCap3(i,2,j),CoeffsCap3(i,3,j), & 
             & CoeffsCap3(i,4,j), CoeffsCap3(i,5,j)
     end do
  end do
  !CoeffsLab3
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsLab3(i,1,j), CoeffsLab3(i,2,j),CoeffsLab3(i,3,j), & 
             & CoeffsLab3(i,4,j), CoeffsLab3(i,5,j)
     end do
  end do
  !CoeffsCons1
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsCons1(i,1,j), CoeffsCons1(i,2,j),CoeffsCons1(i,3,j)
     end do
  end do
  !CoeffsCap1
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsCap1(i,1,j), CoeffsCap1(i,2,j),CoeffsCap1(i,3,j)
     end do
  end do
  !CoeffsLab1
  do i = 1, d
     do j = 1,N
        read(40,*) CoeffsLab1(i,1,j), CoeffsLab1(i,2,j),CoeffsLab1(i,3,j)
     end do
  end do
  !CoeffsCons2
  do i = 1, d-1
     do i1 = i+1,d
        do j = 1,N
           do j1 = 1,3
              read(40,*) CoeffsCons2(i,i1,1,j1,j), CoeffsCons2(i,i1,2,j1,j), &
                   & CoeffsCons2(i,i1,3,j1,j)
           end do
        end do
     end do
  end do
  !CoeffsCap2
  do i = 1, d-1
     do i1 = i+1,d
        do j = 1,N
           do j1 = 1,3
              read(40,*) CoeffsCap2(i,i1,1,j1,j), CoeffsCap2(i,i1,2,j1,j), &
                   & CoeffsCap2(i,i1,3,j1,j)
           end do
        end do
     end do
  end do
  !CoeffsLab2
  do i = 1, d-1
     do i1 = i+1,d
        do j = 1,N
           do j1 = 1,3
              read(40,*) CoeffsLab2(i,i1,1,j1,j), CoeffsLab2(i,i1,2,j1,j), &
                   & CoeffsLab2(i,i1,3,j1,j)
           end do
        end do
     end do
  end do
  !yCons0
  do i = 1,N
     read(40,*) yCons0(i)
  end do
  !yCap0
  do i = 1,N
     read(40,*) yCap0(i)
  end do
  !yLab0
  do i = 1,N
     read(40,*) yLab0(i)
  end do

  close(40)
  
end subroutine InCoeffs

!****************************************************************************
!	SUBROUTINE:  Input
!
!	PURPOSE:  Reads in state variable
!****************************************************************************

subroutine Input(filename)
  
  ! inputs:
  !   filename -- name of output file
  !
  ! output:
  ! 
  ! remarks:

  use Params		!Contains global variables 
  
  implicit none
  
  ! Variable Declaration
  character(len=3), intent(IN) :: filename 
  integer :: i
  
  ! read the data
  open (1, file = filename//".txt")      ! Open file with name filename
  
  open(unit = 30, file = filename//".txt", status = 'old', action = 'read')
  
  do i = 1, 2*N
     read(30,*) instate(i)
  end do
  
  close(30)
  
end subroutine Input

!*********************************************************************
!
!    Subroutine:  Output
!
!    Purpose:    Produces Output File
!                Writes output to a .csv file.
!*********************************************************************

subroutine Output(filename)

  ! inputs:
  !   filename -- name of output file
  !
  ! output:
  ! 
  ! remarks:
  
  use Params

  implicit none
  
  ! Variable Declaration
  character(len=4), intent(IN) :: filename 
  integer :: i
  
  ! Write output to file
  print*,""
  print*,""
  print*,""
  print*,"Make sure the output file -> ", filename, ".csv <- is closed!"
  print*,""
  print*,""
  print*,""
  
  open (1, file = filename//".csv")      ! Open file with name filename

  !Outputs choice variables: k',c,l,y
  do i = 1,4*N
     write (1, '(F14.7," ")', advance = 'no') Results(i)
     write (1,"()")                                                
  end do

  print*,""
  print*,""
  print*,""
  print*,"Results were written to file -> ", filename, ".csv", " <-"
  print*,""
  print*,""
  print*,""
  
end subroutine Output

