class Func
  Modname="sym_boundary"
  def header
    print "module ", Modname, "\n"
    print "  use datatype\n"
    print "  use model_info\n"
    print "  use mem_manager\n"
    print "  implicit none\n"
  end

  def contains
    print "contains\n"
  end

  def footer
    print "end module ", Modname, "\n"
  end
end

class Func1
  Modname = "sym_boundary"
  Modnamex = Modname + "_x"
  Modnamey = Modname + "_y"
  Modnamez = Modname + "_z"

  def header #name = "x", "y", "z"
    print "  interface ", Modnamex, " \n"

    print "    module procedure ", Modnamex, "_x, ", Modnamex, "_xy, ", Modnamex, "_xz, ", Modnamex, "_xyz \n "
    print "end interface\n\n"


    print "  interface ", Modnamey, " \n"
    print "    module procedure ", Modnamey, "_y, ", Modnamey, "_xy, ", Modnamey, "_yz, ", Modnamey, "_xyz \n "
    print "end interface\n\n"

    print "  interface ", Modnamez, " \n"
    print "    module procedure ", Modnamez, "_z, ", Modnamez, "_xz, ", Modnamez, "_yz, ", Modnamez, "_xyz\n "

    print "end interface\n\n"

  end

  def output(name, type)
    if type.index(name) != nil then
      print "  subroutine ", Modname, "_", name, "_", type, "(var) \n"
      print "    type(var_", type, "), intent(inout) :: var\n"
      print "    integer :: i\n\n"

      if name == "x" then 
	print "    if (var%grid(1) == 0) then \n"
	print "      do i = 1, margin_1\n"
	print "        work_", type, "(plb1-i,:,:,var%id) = work_", type, "(plb1+i,:,:,var%id) \n"
	print "        work_", type, "(pub1+i,:,:,var%id) = work_", type, "(pub1-i,:,:,var%id) \n"
	print "      end do\n\n"
	print "    else if (var%grid(1) == 1) then \n"
	print "      do i = 0, margin_1\n"
	print "        work_", type, "(plb1-i,:,:,var%id) = work_", type, "(plb1+i+1,:,:,var%id) \n"
	print "       end do\n"

	print "      do i = 1, margin_1\n"
	print "        work_", type, "(pub1+i,:,:,var%id) = work_", type, "(pub1-i+1,:,:,var%id) \n"
	print "       end do\n"
	print "     end if\n"

      elsif name == "y" then
	print "    if (var%grid(2) == 0) then \n"
	print "      do i = 1, margin_2\n"
	print "        work_", type, "(:,plb2-i,:,var%id) = work_", type, "(:,plb2+i,:,var%id) \n"
	print "        work_", type, "(:,pub2+i,:,var%id) = work_", type, "(:,pub2-i,:,var%id) \n"
	print "      end do\n\n"
	print "    else if (var%grid(2) == 1) then \n"
	print "      do i = 0, margin_2\n"
	print "        work_", type, "(:,plb2-i,:,var%id) = work_", type, "(:,plb2+i+1,:,var%id) \n"
	print "       end do\n"

	print "      do i = 1, margin_2\n"
	print "        work_", type, "(:,pub2+i,:,var%id) = work_", type, "(:,pub2-i+1,:,var%id) \n"
	print "       end do\n"
	print "     end if\n"

      elsif name == "z" then
	print "    if (var%grid(3) == 0) then \n"
	print "      do i = 1, margin_3\n"
	print "        work_", type, "(:,:,plb3-i,var%id) = work_", type, "(:,:,plb3+i,var%id) \n"
	print "        work_", type, "(:,:,pub3+i,var%id) = work_", type, "(:,:,pub3-i,var%id) \n"
	print "      end do\n\n"
	print "    else if (var%grid(3) == 1) then \n"
	print "      do i = 0, margin_3\n"
	print "        work_", type, "(:,:,plb3-i,var%id) = work_", type, "(:,:,plb3+i+1,var%id) \n"
	print "       end do\n"

	print "      do i = 1, margin_3\n"
	print "        work_", type, "(:,:,pub3+i,var%id) = work_", type, "(:,:,pub3-i+1,var%id) \n"
	print "       end do\n"
	print "     end if\n"

      end
      print "  end subroutine ", Modname, "_", name, "_", type, "\n\n"
    else return
#      print "  subroutine ", Modname, "_", name, "_", type, "(var) \n" 
#      print "    type(var_", type, "), intent(in) :: var\n"

#      print "    stop \"", Modname, "_", name, "_", type, "\"\n "
#      print "    var%grid = -1\n "
#      print "  end subroutine ", Modname, "_", name, "_", type, "\n\n"

    end
  end
end

#list1 = open("func_list1", "r")
#list2 = open("func_list2", "r")

func = Func.new
func1 = Func1.new
#func2 = Func2.new
#func4 = Func4.new

type=[6]
name=[2]

type[0] = "x"
type[1] = "y"
type[2] = "z"
type[3] = "xy"
type[4] = "xz"
type[5] = "yz"
type[6] = "xyz"

name[0] = "x"
name[1] = "y"
name[2] = "z"

func.header


  func1.header


func.contains

for i in 0..2 do
  for j in 0..6 do
    func1.output(name[i], type[j])
  end
end

func.footer
