"""
This module is designed to perceive bond types of kappa.Molecule instances.
Design from: http://www.sciencedirect.com/science/article/pii/S1093326305001737

@author: Alex Kerr
"""

import csv

import numpy as np

from ... import package_dir

def main(mol):
    """Return the perceived bond types list for `mol`,
    indexed like `mol.bondList`."""
    
    max_valence_state = 2000
    state_num = 0
    
    tps = 0
    
    #first we need to numerate the possible valences and respective penalty scores for each atom
    av = find_atomic_valences(mol)
    
    print(av)
    return av
    
#    vstates = np.array([])
#    
#    while state_num < max_valence_state:
#        
#        #find states of given tps
#        newstates = bondtype(tps, mol)
#        
#        #increment tps and state number
#        tps += 1
#        state_num += len(newstates)
#        
#    for vstate in vstates:
#        
#        match, b_order = boaf(vstate)
#        
#        if match:
#            break
#        
#    #develop bond types from bond order
#    b_types = b_order
#        
#    return b_types
    
def bondtype(tps, mol):
    """Return all the combinations of valence states for the given tps."""
    
    vstates = np.array([])
    def dfs(index, vstate):
        """A recursive function to fill `vstates` will all valence states
        of total penalty score `tps`"""
        atomicnum, con = mol.zList[index], len(mol.nList[index])
        
    
    return vstates
    
def boaf(vstate):
    """Return True if bond order assignment of the valence state is successful,
    otherwise return False."""
    
    return False, None
    
def find_atomic_valences(mol):
    
    file_ = "APS_kerr_edit.DAT"
    
    reader = csv.reader(open("%s/antechamber/bondtype/%s" % (package_dir, file_)), delimiter=" ", skipinitialspace=True)
    lines = []
    for line in reader:
        #populate lineList
        #this is because reader object cycles only once; was a surprising bug!
        #there must be a better way to do this
        lines.append(line)
    
    print(lines)
    av = []
    
    #for each atom in the molecule search through the APS file and add all possible valence values
    for z, nList in zip(mol.zList, mol.nList):
        for line in [line for line in lines if line[0]=="APS"]:
            if int(line[2]) == z:
                #check to see if con is specified
                if line[3] == "*":
                    #then we have a match
                    av.append(parse_line(line))
                    break
                elif int(line[3]) == len(nList):
                    #then we have a match
                    av.append(parse_line(line))
                    break
            else:
                #go to next line
                continue
        else:
            #no aps values were found for this atom
            raise ValueError("Atom type could not be assigned for bond type perception")
            
    return av
    
def parse_line(line,):
    """Return a list of 2-tuples of the possible atomic valences for a given line from
    the APS defining sheet."""
    
    possap = []
    
    for valence, entry in enumerate(line[4:]):
        if entry != "*":
            possap.append((valence, int(entry)))
            
    return possap
@@ -560,42 +560,8 @@
    %0A
-    print(av)%0A    return av%0A    %0A#
     
@@ -587,15 +587,13 @@
 %5B%5D)%0A
-#
     %0A
-#
     
@@ -629,17 +629,16 @@
 _state:%0A
-#
         
@@ -630,33 +630,32 @@
 state:%0A        %0A
-#
         #find st
@@ -672,17 +672,16 @@
 ven tps%0A
-#
         
@@ -710,14 +710,83 @@
 ps, 
-mol
+av)%0A        %0A        vstates = np.concatenate((vstates, newstates),axis=0
 )%0A
-#
     
@@ -782,33 +782,32 @@
 xis=0)%0A        %0A
-#
         #increme
@@ -830,17 +830,16 @@
  number%0A
-#
         
@@ -847,17 +847,16 @@
 ps += 1%0A
-#
         
@@ -883,17 +883,16 @@
 states)%0A
-#
         
@@ -888,25 +888,24 @@
 s)%0A        %0A
-#
     for vsta
@@ -919,17 +919,16 @@
 states:%0A
-#
         
@@ -920,33 +920,32 @@
 tates:%0A        %0A
-#
         match, b
@@ -966,17 +966,16 @@
 vstate)%0A
-#
         
@@ -971,25 +971,24 @@
 e)%0A        %0A
-#
         if m
@@ -993,17 +993,16 @@
  match:%0A
-#
         
@@ -1011,17 +1011,16 @@
   break%0A
-#
         
@@ -1016,25 +1016,24 @@
 ak%0A        %0A
-#
     #develop
@@ -1056,25 +1056,24 @@
  bond order%0A
-#
     b_types 
@@ -1082,17 +1082,16 @@
 b_order%0A
-#
         
@@ -1091,17 +1091,16 @@
        %0A
-#
     retu
@@ -1133,19 +1133,18 @@
 pe(tps, 
-mol
+av
 ):%0A    %22
@@ -1228,36 +1228,31 @@
   vstates = 
-np.array(%5B%5D)
+%5B%5D%0A    
 %0A    def dfs
@@ -1261,24 +1261,32 @@
 ndex, vstate
+, runsum
 ):%0A        %22
@@ -1402,73 +1402,238 @@
     
-atomicnum, con = mol.zList%5Bindex%5D, len(mol.nList%5Bindex%5D)%0A        
+newstate = vstate%5B:%5D%0A        try:%0A            for valence, ps in av%5Bindex%5D:%0A                if ps+runsum %3C= tps:%0A                    dfs(index+1, newstate, runsum+ps)%0A        except IndexError:%0A            vstates.append(newstate)
 %0A   
@@ -1645,23 +1645,33 @@
  return 
+np.array(
 vstates
+)
 %0A    %0Ade

Add recursive function to find all valence states of a given total penalty score