"""This module provides a way to grab and store raw data for atomic weights."""
import os
import re
import pkgutil

import numpy as np
import tables as tb

from .. import nucname
from .api import BASIC_FILTERS
from .isotopic_abundance import get_isotopic_abundances

# Note that since ground state and meta-stable isotopes are of the same atomic weight, 
# the meta-stables have been discluded from the following data sets.

MASS_FILE = 'mass.mas12'


def copy_atomic_mass_adjustment(build_dir=""):
    """Copies the atomic mass evaluation originally from the Atomic Mass Data
    Center.  These are courtesy of Georges Audi and Wang Meng via a private
    communication, November 2012."""

    if os.path.exists(os.path.join(build_dir, MASS_FILE)):
        return 

    mass = pkgutil.get_data('pyne.dbgen', MASS_FILE)
    with open(os.path.join(build_dir, MASS_FILE), 'w') as f:
        f.write(mass)


# Note, this regex specifically leaves our free neutrons
#amdc_regex = re.compile('[ \d-]*? (\d{1,3})[ ]{1,4}(\d{1,3}) [A-Z][a-z]? .*? (\d{1,3}) ([ #.\d]{10,11}) ([ #.\d]{1,10})[ ]*?$')
amdc_regex = re.compile('[ \d-]*? (\d{1,3})[ ]{1,4}(\d{1,3}) [A-Z][a-z]? .*? (\d{1,3}) ([ #.\d]{5,12}) ([ #.\d]+)[ ]*?$')

def parse_atomic_mass_adjustment(build_dir=""):
    """Parses the atomic mass adjustment data into a list of tuples of 
    the nuclide, atomic mass, and error."""
    f = open(os.path.join(build_dir, MASS_FILE), 'r')

    atomic_masses = []

    for line in f:
        m = amdc_regex.search(line)
        if m is None:
            continue

        nuc = (10000000 * int(m.group(1))) + (10000 * int(m.group(2)))
        mass = float(m.group(3)) + 1E-6 * float(m.group(4).strip().replace('#', ''))
        error = 1E-6 * float(m.group(5).strip().replace('#', ''))

        atomic_masses.append((nuc, mass, error))
        
    f.close()

    return atomic_masses    




atomic_weight_desc = {
    'nuc':   tb.IntCol(pos=1),
    'mass':  tb.FloatCol(pos=2),
    'error': tb.FloatCol(pos=3),
    'abund': tb.FloatCol(pos=4),
    }

atomic_weight_dtype = np.dtype([
    ('nuc',   int),
    ('mass',  float),
    ('error', float), 
    ('abund', float), 
    ])

def make_atomic_weight_table(nuc_data, build_dir=""):
    """Makes an atomic weight table in the nuc_data library.

    Parameters
    ----------
    nuc_data : str
        Path to nuclide data file.
    build_dir : str
        Directory to place html files in.
    """
    # Grab raw data
    atomic_abund  = get_isotopic_abundances()
    atomic_masses = parse_atomic_mass_adjustment(build_dir)

    A = {}

    # Add normal isotopes to A
    for nuc, mass, error in atomic_masses:
        if nuc in atomic_abund:
            A[nuc] = nuc, mass, error, atomic_abund[nuc]
        else:
            A[nuc] = nuc, mass, error, 0.0

    # Add naturally occuring elements
    for element in nucname.name_zz:
        nuc = nucname.id(element)
        A[nuc] = nuc, 0.0, 0.0, 0.0
        
    for nuc, abund in atomic_abund.items():
        zz = nucname.znum(nuc)
        element_zz = nucname.id(zz)
        element = nucname.zz_name[zz]

        _nuc, nuc_mass, _error, _abund = A[nuc]
        elem_zz, elem_mass, _error, _abund = A[element_zz]

        new_elem_mass = elem_mass + (nuc_mass * abund)
        A[element_zz] = element_zz, new_elem_mass, 0.0, float(0.0 < new_elem_mass)


    A = sorted(A.values(), key=lambda x: x[0])

    # Open the HDF5 File
    kdb = tb.openFile(nuc_data, 'a', filters=BASIC_FILTERS)

    # Make a new the table
    Atable = kdb.createTable("/", "atomic_weight", atomic_weight_desc, 
                             "Atomic Weight Data [amu]", expectedrows=len(A))
    Atable.append(A)

    # Ensure that data was written to table
    Atable.flush()

    # Close the hdf5 file
    kdb.close()




def make_atomic_weight(args):
    """Controller function for adding atomic_weights."""
    nuc_data, build_dir = args.nuc_data, args.build_dir

    if os.path.exists(nuc_data):
        with tb.openFile(nuc_data, 'r') as f:
            if hasattr(f.root, 'atomic_weight'):
                print "skipping atomic weights data table creation; already exists."
                return 

    # Then grab mass data
    print "Copying AME 2012 atomic mass data."
    copy_atomic_mass_adjustment(build_dir)

    # Make atomic weight table once we have the array
    print "Making atomic weight data table."
    make_atomic_weight_table(nuc_data, build_dir)


@@ -73,16 +73,54 @@
 hts.%22%22%22%0A
+from __future__ import print_function%0A
 import o
@@ -4122,17 +4122,17 @@
    print
- 
+(
 %22skippin
@@ -4185,16 +4185,17 @@
 exists.%22
+)
 %0A       
@@ -4205,25 +4205,24 @@
       return
- 
 %0A%0A    # Then
@@ -4246,17 +4246,17 @@
    print
- 
+(
 %22Copying
@@ -4283,16 +4283,17 @@
 s data.%22
+)
 %0A    cop
@@ -4392,17 +4392,17 @@
    print
- 
+(
 %22Making 
@@ -4427,16 +4427,17 @@
  table.%22
+)
 %0A    mak

Use print function in atomic_weight.py