!*********************************************************************
!
!    Subroutine:  Output
!
!    Purpose:    Produces Output File
!                Writes output to a .csv file.
!
!    Author:   Ben Malin
!
!    Date:   7/6/07
!    Revised: 7/31/07
!*********************************************************************

subroutine Output(filename)

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

  implicit none
  
  ! Variable Declaration
  character(len=4), intent(IN) :: filename 
 
  character(len=9), dimension(1,17) :: ParamNames
  real(prec), dimension(1,17) :: ParamOut
  character(len=9), dimension(1,27) :: VarNames
  character(len=9), dimension(1,7) :: Acc1Names
  character(len=9), dimension(1,15) :: Acc2Names
  character(len=9), dimension(1,3) :: Acc3Names
  integer :: i
  
  !Matrix that holds parameter names & run times
  ParamNames(1,1) = "rho"
  ParamNames(1,2) = "sigma"
  ParamNames(1,3) = "phi"
  ParamNames(1,4) = "gamma_m"
  ParamNames(1,5) = "gamma_M"
  ParamNames(1,6) = "N"
  ParamNames(1,7) = "kss"
  ParamNames(1,8) = "kmin(1)"
  ParamNames(1,9) = "kmax(1)"
  ParamNames(1,10) = "kmin(N)"
  ParamNames(1,11) = "kmax(N)"
  ParamNames(1,12) = "lss"
  ParamNames(1,13) = "Sol Time"
  ParamNames(1,14) = "Acc1 Time"
  ParamNames(1,15) = "Acc2 Time"
  ParamNames(1,16) = "Acc3 Time"
  ParamNames(1,17) = "Accel"

  !Matrix that holds parameter values
  ParamOut(1,1) = rho
  ParamOut(1,2) = sigma
  ParamOut(1,3) = kappa
  ParamOut(1,4) = gamma_min
  ParamOut(1,5) = gamma_max
  ParamOut(1,6) = real(N,prec)
  ParamOut(1,7) = kss
  ParamOut(1,8) = kmin(1)
  ParamOut(1,9) = kmax(1)
  ParamOut(1,10) = kmin(N)
  ParamOut(1,11) = kmax(N)
  ParamOut(1,12) = lss
  ParamOut(1,13) = policy_runtime
  ParamOut(1,14) = Acc1_runtime
  ParamOut(1,15) = Acc2_runtime
  ParamOut(1,16) = Acc3_runtime
  ParamOut(1,17) = acc

  !Matrix that holds variable names
  VarNames(1,1) = "K(ownK)1"
  VarNames(1,2) = "K(othK)1"
  VarNames(1,3) = "K(ownZ)1"
  VarNames(1,4) = "K(othZ)1"
  VarNames(1,5) = "C(ownK)1"
  VarNames(1,6) = "C(othK)1"
  VarNames(1,7) = "C(ownZ)1"
  VarNames(1,8) = "C(othZ)1"
  VarNames(1,9) = "L(ownK)1"
  VarNames(1,10) = "L(othK)1"
  VarNames(1,11) = "L(ownZ)1"
  VarNames(1,12) = "L(othZ)1"
  VarNames(1,13) = "Knorm1"
  VarNames(1,14) = "Znorm"
  VarNames(1,15) = "K(ownK)N"
  VarNames(1,16) = "K(othK)N"
  VarNames(1,17) = "K(ownZ)N"
  VarNames(1,18) = "K(othZ)N"
  VarNames(1,19) = "C(ownK)N"
  VarNames(1,20) = "C(othK)N"
  VarNames(1,21) = "C(ownZ)N"
  VarNames(1,22) = "C(othZ)N"
  VarNames(1,23) = "L(ownK)N"
  VarNames(1,24) = "L(othK)N"
  VarNames(1,25) = "L(ownZ)N"
  VarNames(1,26) = "L(othZ)N"
  VarNames(1,27) = "KnormN"

  !Matrix that holds names for output from Accuracy Check 1
  Acc1Names(1,1) = "r=.01"
  Acc1Names(1,2) = "r=.02"
  Acc1Names(1,3) = "r=.05"
  Acc1Names(1,4) = "r=.10"
  Acc1Names(1,5) = "r=.15"
  Acc1Names(1,6) = "r=.20"
  Acc1Names(1,7) = "r=.30"

  !Matrix that holds names of variables from Accuracy Check 2
  Acc2Names(1,1) = "MaxEEerr"
  Acc2Names(1,2) = "MaxCerr"
  Acc2Names(1,3) = "MaxBCerr"
  Acc2Names(1,4) = "MaxLerr"
  Acc2Names(1,5) = "AvgEEerr"
  Acc2Names(1,6) = "AvgCerr"
  Acc2Names(1,7) = "AvgBCerr"
  Acc2Names(1,8) = "AvgLerr"
  Acc2Names(1,9) = "mincap"
  Acc2Names(1,10) = "maxcap"
  Acc2Names(1,11) = "mincons"
  Acc2Names(1,12) = "minlab"
  Acc2Names(1,13) = "maxlab"
  Acc2Names(1,14) = "minz"
  Acc2Names(1,15) = "maxz"

  !Matrix that holds names for output from Accuracy Check 3
  Acc3Names(1,1) = "P_05"
  Acc3Names(1,2) = "P_50"
  Acc3Names(1,3) = "P_95"

  ! Write output to file
  print*,""
  print*,""
  print*,""
  print*,"Make sure the output file -> ", filename, ".csv <- is closed!"
  print*,""
  print*,""
  print*,""
!  pause
  
  open (1, file = filename//".csv")      ! Open file with name filename

  !Outputs the parameters of the model
  call WriteRowT(ParamNames, 1, 17, 1)
  write (1,"()") 
  call WriteRowM(ParamOut, 1, 17, 1)
  write (1,"()") 
  write (1,"()") 

  !Outputs the state variable grids and decision rules
  call WriteRowT(VarNames, 1, 27, 1)
  write (1,"()") 

  do i = 1, nk
     call WriteRowM(VarOut, nk, 27, i)
     write (1,"()")                                                
  end do

  !Outputs errors from Accuracy Check 1
  write (1,"()") 
  call WriteRowT(Acc1Names, 1, 7, 1)
  write (1,"()") 

  call WriteRowM(Acc1Out, 1, 7, 1)
  write (1,"()")                                                

  !Outputs errors and other variables Accuracy Check 2
  write (1,"()") 
  call WriteRowT(Acc2Names, 1, 15, 1)
  write (1,"()") 

  do i = 1, N
     call WriteRowM(Acc2Out, N, 15, i)
     write (1,"()")                                                
  end do

  !Outputs errors from Accuracy Check 3
  write (1,"()") 
  call WriteRowT(Acc3Names, 1, 3, 1)
  write (1,"()") 

  call WriteRowM(Acc3Out, 1, 3, 1)
  write (1,"()")                                                

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