c
c
c     ###################################################
c     ##  COPYRIGHT (C)  1990  by  Jay William Ponder  ##
c     ##              All Rights Reserved              ##
c     ###################################################
c
c     ############################################################
c     ##                                                        ##
c     ##  subroutine katom  --  atom type parameter assignment  ##
c     ##                                                        ##
c     ############################################################
c
c
c     "katom" assigns an atom type definitions to each atom in
c     the structure and processes any new or changed values
c
c
      subroutine katom
      implicit none
      include 'sizes.i'
      include 'atmtyp.i'
      include 'atoms.i'
      include 'couple.i'
      include 'inform.i'
      include 'iounit.i'
      include 'katoms.i'
      include 'keys.i'
      integer i,k,next
      integer cls,atn,lig
      real*8 wght
      character*3 symb
      character*20 keyword,notice
      character*80 record,string
      logical header
c
c
c     process keywords containing atom type parameters
c
      header = .true.
      do i = 1, nkey
         next = 1
         record = keyline(i)
         call gettext (record,keyword,next)
         call upcase (keyword)
         if (keyword(1:5) .eq. 'ATOM ') then
            k = 0
            cls = 0
            symb = ' '
            notice = ' '
            atn = 0
            wght = 0.0d0
            lig = 0
            string = record(next:80)
            read (string,*,err=10,end=10)  k,cls
   10       continue
            if (cls .eq. 0)  cls = k
            atmcls(k) = cls
            call getword (record,symb,next)
            call getstring (record,notice,next)
            string = record(next:80)
            read (string,*,err=50,end=50)  atn,wght,lig
            if (k.ge.1 .and. k.le.maxtyp) then
               if (header) then
                  header = .false.
                  write (iout,20)
   20             format (/,' Additional Atom Type Parameters :',
     &                    //,4x,'Type  Class  Symbol',4x,'Description',
     &                       12x,'Atomic #',4x,'Mass',3x,'Valence',/)
               end if
               symbol(k) = symb
               describe(k) = notice
               atmnum(k) = atn
               weight(k) = wght
               ligand(k) = lig
               write (iout,30)  k,cls,symb,notice,atn,wght,lig
   30          format (2i7,5x,a3,5x,a20,i8,f12.3,i6)
            else if (k .ge. maxtyp) then
               write (iout,40)
   40          format (/,' KATOM   --  Too many Atom Types;',
     &                    ' Increase MAXTYP')
               abort = .true.
            end if
   50       continue
         end if
      end do
c
c     transfer atom type values to individual atoms
c
      do i = 1, n
         k = type(i)
         if (k .eq. 0) then
            class(i) = 0
            atomic(i) = 0
            mass(i) = 0.0d0
            valence(i) = 0
            story(i) = 'Undefined Atom Type '
         else
            if (symbol(k) .ne. '   ')  name(i) = symbol(k)
            class(i) = atmcls(k)
            atomic(i) = atmnum(k)
            mass(i) = weight(k)
            valence(i) = ligand(k)
            story(i) = describe(k)
         end if
      end do
c
c     process keywords containing atom types for specific atoms
c
      header = .true.
      do i = 1, nkey
         next = 1
         record = keyline(i)
         call gettext (record,keyword,next)
         call upcase (keyword)
         if (keyword(1:5) .eq. 'ATOM ') then
            k = 0
            symb = ' '
            notice = ' '
            atn = 0
            wght = 0.0d0
            lig = 0
            string = record(next:80)
            read (string,*,err=60,end=60)  k,cls
   60       continue
            call getword (record,symb,next)
            call getstring (record,notice,next)
            string = record(next:80)
            read (string,*,err=90,end=90)  atn,wght,lig
            if (k.lt.0 .and. k.ge.-n) then
               if (header) then
                  header = .false.
                  write (iout,70)
   70             format (/,' Additional Atom Types for',
     &                       ' Specific Atoms :',
     &                    //,4x,'Type  Class  Symbol',4x,'Description',
     &                       12x,'Atomic #',4x,'Mass',3x,'Valence',/)
               end if
               k = -k
               if (cls .eq. 0)  cls = k
               class(k) = cls
               name(k) = symb
               story(k) = notice
               atomic(k) = atn
               mass(k) = wght
               valence(k) = lig
               write (iout,80)  k,cls,symb,notice,atn,wght,lig
   80          format (2i7,5x,a3,5x,a20,i8,f12.3,i6)
            end if
   90       continue
         end if
      end do
c
c     check for undefined atom types in the molecule
c
      header = .true.
      do i = 1, n
         k = type(i)
         if (k.lt.1 .or. k.gt.maxtyp) then
            abort = .true.
            if (header) then
               header = .false.
               write (iout,100)
  100          format (/,' Undefined or Illegal Atom Types :',
     &                 //,' Type',10x,'Atom Number',5x,'Atom Type',/)
            end if
            write (iout,110)  i,k
  110       format (' Atom',12x,i5,10x,i5)
         end if
      end do
c
c     check the number of atoms attached to each atom
c
      header = .true.
      do i = 1, n
         if (n12(i) .ne. valence(i)) then
            if (header) then
               header = .false.
               write (iout,120)
  120          format (/,' Atoms with an Unusual Number of Attached',
     &                    ' Atoms :',
     &                 //,' Type',11x,'Atom Name',6x,'Atom Type',7x,
     &                    'Expected',4x,'Found',/)
            end if
            write (iout,130)  i,name(i),type(i),valence(i),n12(i)
  130       format (' Valence',7x,i5,'-',a3,8x,i5,10x,i5,5x,i5)
         end if
      end do
      return
      end
