
      SUBROUTINE globalInit(numChunk)
          IMPLICIT NONE
          INTEGER numChunk
          numChunk = 5
      END SUBROUTINE

      SUBROUTINE processorInit()
      END SUBROUTINE

      SUBROUTINE chunkInit(obj, width,height, chunkStruct, thisIndex)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          INTEGER width, height, thisIndex
          INTEGER (KIND=8) obj
          INTEGER i,j

          ALLOCATE (chunk)
          chunkStruct%chunk_ptr => chunk

          chunk%height = height
          chunk%width = width + 2
          chunk%objPtr = obj
          chunk%index = thisIndex
          chunk%iterations = 0

          DO i = 1, width
            DO j = 0, height-1
              chunk%temperature(j+1, i+1) = 100*(i-1) + j
            ENDDO 
          ENDDO
        END SUBROUTINE        

        SUBROUTINE nextIteration(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          INTEGER i,j

          chunk => chunkStruct%chunk_ptr

          DO i = 2, 11
           DO j = 2, 99
             chunk%temperature(j,i) = ( chunk%temperature(j, i) + chunk%&
     &temperature(j, i+1) + chunk%temperature(j, i-1) + chunk%temperatur&
     &e(j+1, i) + chunk%temperature(j-1, i))/5.0
	   END DO
	  ENDDO
        END SUBROUTINE

        RECURSIVE SUBROUTINE sendToNeighbors(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk
          REAL(KIND=8) buf(1:200)
          INTEGER toIndex, fromIndex

          EXTERNAL callfunc
          EXTERNAL nextStep

          chunk => chunkStruct%chunk_ptr

          buf(1:chunk%height) = chunk%temperature(1:chunk%height, 2);
          toIndex = mod(chunk%index-1+5,5)
          call f_send(toIndex, buf, 200*8, 1, chunk%index, chunk%iterations)

          buf(1:chunk%height) = chunk%temperature(1:chunk%height, chunk%width-1);
          toIndex = mod(chunk%index+1,5)
          call f_send(toIndex, buf, 200*8, 0, chunk%index, chunk%iterations)
 
          fromIndex = mod(chunk%index+1,5)
          call f_irecv(chunk%objPtr, chunk%buf1, 200*8, 1, fromIndex, chunk%iterations)

          fromIndex = mod(chunk%index-1+5,5)
          call f_irecv(chunk%objPtr, chunk%buf2, 200*8, 0, fromIndex, chunk%iterations)

          call f_iwaitall(chunk%objPtr, nextStep, chunkStruct, chunk%iterations)

        END SUBROUTINE


        RECURSIVE SUBROUTINE nextStep(chunkStruct)
          USE chunkModule
	  IMPLICIT NONE

          TYPE(chunk_struct) :: chunkStruct
          TYPE(chunk_type), POINTER :: chunk

          chunk => chunkStruct%chunk_ptr

          chunk%temperature(1:chunk%height,chunk%width) = chunk%buf1(1:chunk%height)
          chunk%temperature(1:chunk%height,1) = chunk%buf2(1:chunk%height)

          chunk%iterations = chunk%iterations + 1

          IF ( chunk%iterations .lt. 3) THEN
             call nextIteration(chunkStruct);
             call sendToNeighbors(chunkStruct);
          ENDIF

        END SUBROUTINE



