program piste
!copy of program in Chapman Fig 15-14 Fortran 95/2003

implicit none

!Derived data type to store real values in
type :: snow_layer
  real :: value
  type (snow_layer), pointer :: p => null()
end type

!Data dictionary: declare variable types and definitions
type (snow_layer), pointer :: top => null()	!pointer to top of snow_column
type (snow_layer), pointer :: ptr => null()		!temporary pointer
type (snow_layer), pointer :: bottom => null()	!pointer to bottom of snow_column
character(len=30) :: filename				!name of input data file
integer :: nvals = 0						!number of data read
integer :: istat							!i/o status: 0 for success
real :: tmp									!temporary variable

integer :: findnode							!node count to find
integer :: nodeindex						!index of any node
real :: findvalue							!node value to find

!Get the name of the file containing the input data
write (*,"(a)", advance= "no") "Enter the input filename: "
read (*,"(a30)") filename

!Open the input data file.
open (1, file=filename, status="old", action="read", iostat=istat)

!Was the OPEN successful?
fileopen: if (istat == 0) then
  
  input: do									!read each line of input file
    read (1, *, iostat=istat) tmp			!get value
    if (istat .ne. 0) exit					!exit do loop on end of data
    nvals = nvals + 1						!bump count
    
    if (.not. associated(top)) then		!CREATE THE FIRST TOP LAYER OF SNOW ==================
      allocate(top,stat=istat)				!allocate this first new value to the top
      nullify(top%p)						!if top is the only node in snow_column, then set next to null
      bottom => top							!bottom points to the top (for first value only)
      nullify (bottom%p)						!pointer in bottom doesn't point
      bottom%value = tmp						!store the number
      nvals = nvals + 1						!bump count of nodes
      
    else									!ADD A NEW SNOW LAYER AT END OF snow_column ======================
      allocate(bottom%p,stat=istat)			!allocate new value for the bottom, and point the old bottom to it
      bottom => bottom%p						!bottom points to the new value
      nullify (bottom%p)						!pointer in bottom doesn't point
      bottom%value = tmp						!store the number
      nvals = nvals + 1						!bump count of nodes
    endif
    
  end do input								!finished reading input file
  
  !TRAVERSE THE WHOLE COLUMN OF LAYERS FROM TOP TO BOTTOM ===================
  !Now, access the linked snow_column, and write them to the screen
  ptr => top								!start at the first item in the snow_column
  do								!for each item in the linked snow_column
    if (.not. associated(ptr) ) exit		!reached end of snow_column
    write (*,"(1X,F10.4)") ptr%value		!print value 
    ptr => ptr%p							!point to the next item in the snow_column
  end do
  
else fileopen
	write (*,*) "Sorry.  Couldn't open file: '", trim(filename), "'.  IOSTAT = ",istat
  
end if fileopen
	
	
!Add a value to the beginning of the snow_column, as a new TOP LAYER ==================
write(*,*) "New top value = 0.01"			!passify user

ptr => top									!remember pointer to old top
allocate(top, stat=istat)					!create new memory space for new top, and make top point to it
top%p => ptr								!new top points to old top
top%value = 0.01							!value stored in new top
nvals = nvals + 1							!bump count of nodes
	
  !TRAVERSE THE WHOLE SNOW COLUMN FROM top TO bottom ===================
  !Now, access the linked snow_column, and write them to the screen
  ptr => top								!start at the first item in the snow_column
  do								!for each item in the linked snow_column
    if (.not. associated(ptr) ) exit		!reached end of snow_column
    write (*,"(1X,F10.4)") ptr%value		!print value 
    ptr => ptr%p							!point to the next item in the snow_column
  end do
  
!Find the ith LAYER in the SNOW COLUMN =================

  findnode = 4								!For example, find the 4th node
  nodeindex = 0								!initialize the node count
  write(*,*) "Find node index ", findnode, " and print its value."
  
  ptr => top								!start at the first item in the snow_column
  do								!for each item in the linked snow_column
    if (.not. associated(ptr) ) exit		!reached end of snow_column
    nodeindex = nodeindex + 1				!the index of the current node
    if (nodeindex == findnode) exit			!found it.  Stop traversing the snow_column
    ptr => ptr%p							!point to the next item in the snow_column
  end do
  
  write (*,"(1X,F10.4)") ptr%value		!print value 
  
  
!Find the SNOW LAYER with the desired data value ===================
nodeindex = 0								!initialize the node count
findvalue = 5.0							!example of value to find in the snow_column
write(*,*) "Find node having value =", findvalue

  ptr => top								!start at the first item in the snow_column
  do										!for each item in the linked snow_column
    if (.not. associated(ptr) ) then
      write(*,*) "Value NOT found in the snow_column."
      exit		!reached end of snow_column
    endif
    nodeindex = nodeindex + 1				!the index of the current node
    if (ptr%value == findvalue) then
      write (*,*) "Node index =", nodeindex		!print value 
      exit			!found it.  Stop traversing the snow_column
    endif
    ptr => ptr%p							!point to the next item in the snow_column
  end do
  

!Delete the ith SNOW LAYER in the snow_column, as found with the previous ptr ===========




endprogram piste
