! CS101 Tutorial  \\
! TA : Srinivas Samala       \\
!      srinus@cse.iitb.ac.in  \\
! Example program  on Pointers
! 
!


program student_info
     implicit none
     Type :: student 
          integer :: rollno
          character(len=20) :: name
          integer :: marks
          Type(student),pointer :: next
     end type
     
     Type(student),pointer ::head
     Type(student),pointer ::tail
     Type(student),pointer :: ptr
     integer istat,num,i,opt,max
     
     allocate(head,stat=istat)
     tail =>head
     nullify(tail%next)

     print *,"Enter the information of first student"
     print *,"Enter rollno"
     read *,head%rollno
     print *, "Enter name"
     read  *,head%name
     print *,"enter marks"
     read *,head%marks


     do 
          print *,"Enter option"
          print *,"1. Enter student data"
          print *,"2. Display Students data"
          print *,"3. Find student with highest marks"
          print *,"4. Delete student entry"
          print *,"5. Exit "
          read *,opt
          select case(opt)
              case(1)
                   CALL insert()
              case(2)
                   print 10
                   10 FORMAT(T10,"ROLLNO",T20,"NAME",T40,"MARKS")
                   ptr => head
                   do
                       if(.not. associated(ptr)) exit
                       print 25,ptr%rollno,ptr%name,ptr%marks
                       25 FORMAT(T10,I5,T20,A,T40,I3)
                       ptr => ptr%next
                   end do
              case(3)
                   CALL find_max()
                   !print *,max
              case(4)
                   CALL delete()
              case(5)
                   stop
              case default
                   print *,"Enter correct code"
          end select
          
     end do


contains
subroutine insert()
  
      implicit none
!     Type(student),pointer :: tail

          allocate(tail%next,stat=istat)
          tail=>tail%next
          nullify(tail%next)

          print *,"Making new entry"
          print *,"Enter rollnumber"
          read  *,tail%rollno
          print *,"Enter student name"
          read  *,tail%name
          print *,"Enter marks"
          read  *,tail%marks     

end subroutine insert     

 
 
subroutine find_max()
   
     implicit none
!    Type(student),pointer :: head
     integer :: max
     Type(student),pointer :: ptr,max_ptr
   
     ptr=>head
     max = ptr%marks
     max_ptr =>ptr
   
     do 
       
       if(.not. associated(ptr)) exit
       if(max < ptr%marks) then
       max = ptr%marks
       max_ptr => ptr
       end if
       ptr =>ptr%next
     end do

     print *," "
     print *,"rollno:",max_ptr%rollno,"Name:",max_ptr%name,"Marks:",max_ptr%marks
     print *," "

end subroutine find_max


subroutine delete()

     implicit none
     Type(student),pointer :: prev_ptr

     print *,"enter the Roll Number of student"
     read *, num
     ptr =>head
     if(ptr%rollno==num) then
          head =>ptr%next
          nullify(ptr)
     else 
     
          prev_ptr =>ptr
          ptr=>ptr%next
          do 
               if(ptr%rollno==num) then
                    prev_ptr%next => ptr%next
                    print *,""
                    print *,"The entry with Rollno ",num," is  deleted"
                    print *,""
                    if(.not. associated(ptr%next)) then
                       tail =>prev_ptr
                    end if
                    nullify(ptr)
                    exit
               else 
                    if (.not. associated(ptr%next)) then
                        print *,"Given Roll number does not exist"
                       exit
                    end if
                    prev_ptr => ptr
                    ptr => ptr%next
               end if
          end do
     end if
end subroutine
end program


