************************************************************************
* MASTER MECHANISM - ROUTINE NAME : ratings                            *
*                                                                      *
*  22 april 2008                                                       *
*                                                                      *
* PURPOSE:  Rates groups in molecule based on node connections and     *
*           group types.  Small rating gives higher priority.          *
*           Default rating = '99999....' so is LOW priority.           *
*           Rating scale adapted from original prioty subroutine       *
*                                                                      *
* INPUT:                                                               *
* - nca       : number of nodes in molecule                            *
* - nring     : number of rings in molecule                            *
* - group(i)  : character string for each node and attached functional *
*               groups                                                 *
* - bond(i,j) : node-node bond matrix  ('node' = 'C','c','-O-')        *
*                                                                      *
* OUTPUT:                                                              *
* - rank(i)   : integer ranks for groups                               *
*                                                                      *
************************************************************************
      SUBROUTINE ratings(nca,group,bond,nring,rank)

      IMPLICIT NONE
      INCLUDE 'general.h'
      INCLUDE 'organic.h'

!input:
      INTEGER          nca,nring
      CHARACTER(LEN=lgr)  group(mca)
      INTEGER          bond(mca,mca)

!internal:
      INTEGER          i,j,nrat,cntr
      INTEGER          ncx(mca)    ! n_connections on node
      INTEGER          rjg(mri,2)  ! ring-join group pairs
      PARAMETER(nrat=24)
      CHARACTER(nrat) nines, maxm
      CHARACTER(nrat) rating(mca)
      CHARACTER(nrat) tmprat(mca)

! output:
      INTEGER          rank(mca)
!-----------------------------------------------------------------!
      !print*,'*ratings*'

! initialize
      rank(:)=0
      do i = 1,nrat
        DO j=1,nrat
          tmprat(i)(j:j)='9'
        ENDDO
      enddo

! find # of adjacent nodes, convert to character
      DO i=1,nca
        ncx(i)=0
        rating(i)(1:1) = '0'
        DO j=1,nca
          IF(bond(i,j).GT.0) THEN
            ncx(i)=ncx(i)+1
            rating(i)(1:1) =  digit(ncx(i))
          ENDIF
        ENDDO
      ENDDO

! remove ring-joining characters from groups if rings exist
      IF(nring.GT.0) CALL rjgrm(nring,group,rjg)

      nines = '999999999999999999999999'
      DO i=1,nca
        rating(i)(2:nrat) = nines
!rating(i)(1:1) reserved for # non-H bonds
        IF(INDEX(group(i),'.' ).NE.0)         rating(i)(2:2) = '1'
        IF(INDEX(group(i),'CdO' ).NE.0)       rating(i)(4:4) = '1'
        IF(INDEX(group(i),'Cd' ).NE.0)        rating(i)(5:5) = '3'
        IF(INDEX(group(i),'CdH' ).NE.0)        rating(i)(5:5) = '2'
        IF(INDEX(group(i),'CdH2' ).NE.0)        rating(i)(5:5) = '1'
        IF(INDEX(group(i),'-O-' ).NE.0)       rating(i)(6:6) = '1'
        IF(INDEX(group(i),'CHO' )  .NE.0)     rating(i)(7:7) = '1'
        IF(INDEX(group(i),'CO(OONO2)' ).NE.0) rating(i)(8:8) = '1'
        IF(INDEX(group(i),'CO(OOH)' ).NE.0)   rating(i)(9:9) = '1'
        IF(INDEX(group(i),'(OOH)' ).NE.0)     rating(i)(10:10) = '3'
        IF(INDEX(group(i),'(OOH)(OOH)' ).NE.0) rating(i)(10:10) = '2'
        IF(INDEX(group(i),'(OOH)(OOH)(OOH)').NE.0)rating(i)(10:10) = '1'
        IF(INDEX(group(i),'(ONO2)').NE.0)     rating(i)(11:11) = '3'
        IF(INDEX(group(i),'(ONO2)(ONO2)').NE.0)rating(i)(11:11) = '2'
        IF(INDEX(group(i),'(ONO2)(ONO2)(ONO2)').NE.0)
     &                                          rating(i)(11:11) = '1'
        IF(INDEX(group(i),'CO(OH)' ).NE.0)    rating(i)(12:12) = '1'
        IF(INDEX(group(i),'CO' ).NE.0)        rating(i)(13:13) = '1'
        IF(INDEX(group(i),'F' ).NE.0)         rating(i)(14:14) = '1'
        IF(INDEX(group(i),'Br' ).NE.0)        rating(i)(15:15) = '1'
        IF(INDEX(group(i),'Cl' ).NE.0)        rating(i)(16:16) = '1'
        IF(INDEX(group(i),'S' ).NE.0)         rating(i)(17:17) = '1'
        IF(INDEX(group(i),'NH' ).NE.0)        rating(i)(18:18) = '1'
        IF(INDEX(group(i),'(NO2)' ).NE.0)     rating(i)(19:19) = '3'
        IF(INDEX(group(i),'(NO2)(NO2)' ).NE.0) rating(i)(19:19) = '2'
        IF(INDEX(group(i),'(NO2)(NO2)(NO2)').NE.0)rating(i)(19:19) = '1'
        IF(INDEX(group(i),'NO' ).NE.0)        rating(i)(20:20) = '1'
        IF(INDEX(group(i),'(OH)' ).NE.0)      rating(i)(21:21) = '3'
        IF(INDEX(group(i),'(OH)(OH)' ).NE.0)   rating(i)(21:21) = '2'
        IF(INDEX(group(i),'(OH)(OH)(OH)' ).NE.0) rating(i)(21:21) = '1'
        IF(INDEX(group(i),'C' ).NE.0)         rating(i)(22:22) = '4'
        IF(INDEX(group(i),'CH' ).NE.0)         rating(i)(22:22) = '3'
        IF(INDEX(group(i),'CH2' ).NE.0)         rating(i)(22:22) = '2'
        IF(INDEX(group(i),'CH3' ).NE.0)          rating(i)(22:22) = '1'
        IF(INDEX(group(i),'c' ).NE.0)         rating(i)(23:23) = '2'
        IF(INDEX(group(i),'cH' ).NE.0)         rating(i)(23:23) = '1'
      ENDDO

!! NEW CODE WITH IMPROVED RANKINGS ASSIGNMENT !!
      tmprat(:)=rating(:)
!! DEBUG !!
      !DO i=1,nca
      !print*,i,group(i),rating(i)
      !ENDDO
!! END DEBUG !!

      CALL sortblen(nrat,nca,tmprat(1:nca))
! find index in rating corresponding to tmprat
      DO i=1,nca
        DO j = 1, nca
          IF(tmprat(j).EQ.rating(i))THEN
            rank(i)=j
!! DEBUG !!
            !print*,i,group(i),rating(i)," ",tmprat(i),rank(i)
!! END DEBUG !!
            EXIT
          ENDIF
        ENDDO
      ENDDO
!! END NEW CODE !!


!! BYPASS OLD CODE !!
      GOTO 19
!! OLD CODE !!
!! Not all groups are being assigned ranks by this code !
!! We seem to lose interest in the lowest-priority end of the chain !
!      cntr = 0
!      nines = '999999999999999999999999'
!      DO i = 1, nca !-1
!        maxm = nines
!        DO j = 1, nca
!          IF (rating(j).LT.maxm) maxm = rating(j)
!        ENDDO
!        IF (maxm.eq.nines) GOTO 20  ! EXIT
!        cntr = cntr + 1
!        DO j = 1, nca
!          IF (rating(j).LE.maxm) THEN
!             rating(j) = nines
!             rank(j) = cntr
!          ENDIF
!        ENDDO
!      ENDDO
!20    CONTINUE
!! END OLD CODE !!
19    CONTINUE
!! END BYPASS !!

! this catcher doesn't seem to be working!
      DO i = 1, nca
        IF(rank(i).EQ.0)THEN
          print*,'rank incorrectly assigned'
          STOP
        ENDIF
      ENDDO

! add ring-joining characters if rings exist
      IF (nring.GT.0) CALL rjgadd(nring,group,rjg)

! use product of adjacent primes to find unique ranks
!! DEBUG !!
        !print*,rank(1:nca)
!! END DEBUG !!
      CALL primes(nca,bond,rank)
!! DEBUG !!
        !print*,"*primes*"
        !print*,rank(1:nca)
!! END DEBUG !!

      !print*,'*end ratings*'
      RETURN
      END
