"""
#;+ 
#; NAME:
#; lls_literature
#;   Ordered by publication date
#;    Version 1.0
#;
#; PURPOSE:
#;    Module for loading up literature data on Lyman Limit Systems
#;   29-Jun-2015 by JXP
#;-
#;------------------------------------------------------------------------------
"""

from __future__ import print_function, absolute_import, division, unicode_literals

import os, copy, sys, imp, glob
import numpy as np
import urllib2

from astropy import units as u
from astropy.io import ascii 

from linetools.lists.linelist import LineList
from linetools.spectralline import AbsLine

from xastropy.atomic import ionization as xai
from xastropy.igm.abs_sys.lls_utils import LLSSystem
from xastropy.igm.abs_sys.ionclms import IonClms
from xastropy.igm.abs_sys import ionclms as xiai
from xastropy.obs import radec as xor 
from xastropy.xutils import xdebug as xdb

xa_path = imp.find_module('xastropy')[1]

#class LLSSystem(AbslineSystem):
#class LLS_Survey(Absline_Survey):

def zonak2004():
    '''Zoank, S. et al. 2004, ApJ, 2004, 606, 196
    PG1634+706
    HST+Keck spectra
    MgII, SiIV, SiIII from Table 2.  Summing Subsystems A (Model 2) and B
       Errors estimated by JXP (not reported)
       SiIII in A may be a model
       SiIV in B may be a model
    Total NHI from LL. Taken from Fig 3 caption.  
       Error estimated by JXP 
    Not all EWs in Table 1 included
    Adopting their M/H
    '''
    # Setup
    radec = xor.stod1('J163428.9897+703132.422') # SIMBAD
    lls = LLSSystem(name='PG1634+706_z1.041', RA=radec[0], Dec=radec[1], zem=1.337,
        zabs=1.0414, vlim=[-200., 30.]*u.km/u.s, NHI=17.23, MH=-1.4,
        sigNHI=np.array([0.15,0.15])) 
    # SubSystems
    lls.mk_subsys(2) 
    # Abundances
    adict = dict(MgII={'clm': log_sum([11.45,11.90,12.02,11.68]), 'sig_clm': 0.05, 'flg_clm': 1},
        SiIII={'clm': log_sum([12.5,12.5,12.8,12.7]), 'sig_clm': 0.25, 'flg_clm': 1},
        SiIV={'clm': log_sum([10.9,10.8,11.2,11.1]), 'sig_clm': 0.15, 'flg_clm': 1} )
    lls.subsys['A']._ionclms = IonClms(idict=adict)
    bdict = dict(SiIII={'clm': log_sum([11.8,12.8,12.4]), 'sig_clm': 0.15, 'flg_clm': 1},
        SiIV={'clm': log_sum([11.2,12.2,11.8]), 'sig_clm': 0.15, 'flg_clm': 1} )
    lls.subsys['B']._ionclms = IonClms(idict=bdict)
    # Total
    lls._ionclms = lls.subsys['A']._ionclms.sum(lls.subsys['B']._ionclms)
    lls.Refs.append('Zon04')
    # Return
    return lls

def jenkins2005():
    '''Jenkins, E. et al. 2005, ApJ, 2005, 623, 767
    PHL 1811
    HST/STIS, FUSE
    Metals parsed from Table 1
      OI taken from text
      Had to input error on columns by hand (JXP)
    Total NHI from Lyman series. see Fig 3
    M/H from O/H
    '''
    # Grab ASCII file from ApJ
    tab_fil = xa_path+"/data/LLS/jenkins2005.tb1.ascii"
    chk_fil = glob.glob(tab_fil)
    if len(chk_fil) > 0:
        tab_fil = chk_fil[0]
    else:
        url = 'http://iopscience.iop.org/0004-637X/623/2/767/fulltext/61520.tb1.txt'
        print('LLSSurvey: Grabbing table file from {:s}'.format(url))
        f = urllib2.urlopen(url)
        with open(tab_fil, "wb") as code:
            code.write(f.read())
    # Setup
    radec = xor.stod1('J215501.5152-092224.688') # SIMBAD
    lls = LLSSystem(name='PHL1811_z0.081', RA=radec[0], Dec=radec[1], zem=0.192,
        zabs=0.080923, vlim=[-100., 100.]*u.km/u.s, NHI=17.98, MH=-0.19,
        sigNHI=np.array([0.05,0.05])) 

    # AbsLines
    ism = LineList('ISM')
    Nsig = {'C IV': 0.4, 'N II': 0.4, 'Si II': 0.05, 'Si IV': 0.25, 
        'S II': 0.2, 'Fe II': 0.12, 'H I': 0.05, 'S III': 0.06}

    # Parse Table
    with open(tab_fil,'r') as f:
        flines = f.readlines()
    ion_dict = {}
    for iline in flines:
        iline = iline.strip()
        if (len(iline) == 0): 
            continue
        # Split on tabs
        isplit = iline.split('\t')
        # Offset?
        ioff = 0
        if isplit[0][0] in ['1','2']:
            ioff = -1
        # Catch bad lines
        if (isplit[1+ioff][0:6] in ['1442.0','1443.7','1120.9']): # Skip goofy CII line and CII*
            continue
        if len(isplit[2+ioff]) == 0: 
            continue
        # Ion
        if (len(isplit[0].strip()) > 0) & (isplit[0][0] not in ['1','2']):
            ionc = isplit[0].strip()
            try:
                Zion = xai.name_ion(ionc)
            except KeyError:
                xdb.set_trace()
        # Generate the Line
        try:
            newline = AbsLine(float(isplit[2+ioff])*u.AA,linelist=ism, closest=True)
        except ValueError:
            xdb.set_trace()
        newline.attrib['z'] = lls.zabs
        # Spectrum
        newline.analy['datafile'] = 'STIS' if 'S' in isplit[1] else 'FUSE'
        # EW
        try:
            EWvals = isplit[4+ioff].split(' ')
        except IndexError:
            xdb.set_trace()
        newline.attrib['EW'] = float(EWvals[0])*u.AA/1e3
        newline.attrib['EWsig'] = float(EWvals[2])*u.AA/1e3
        newline.attrib['flgEW'] = 1
        if len(isplit) < (5+ioff+1):
            continue
        # Colm?
        #xdb.set_trace()
        if (len(isplit[5+ioff].strip()) > 0) & (isplit[5+ioff].strip() != '\\ldots'):
            if isplit[5+ioff][0] == '\\':
                ipos = isplit[5+ioff].find(' ')
                newline.attrib['N'] = float(isplit[5+ioff][ipos+1:])
                newline.attrib['flagN'] = 2
            elif isplit[5+ioff][0] == '<':
                ipos = 0
                newline.attrib['N'] = float(isplit[5+ioff][ipos+1:])
                newline.attrib['flagN'] = 3
            elif isplit[5+ioff][0] == '1':
                try:
                    newline.attrib['N'] = float(isplit[5+ioff][0:5])
                except ValueError:
                    xdb.set_trace()
                newline.attrib['flagN'] = 1
                try:
                    newline.attrib['Nsig'] = Nsig[ionc]
                except KeyError:
                    print('No error for {:s}'.format(ionc))
            else:
                raise ValueError('Bad character')
            # ion_dict
            ion_dict[ionc] = dict(clm=newline.attrib['N'], sig_clm=newline.attrib['Nsig'],
                flg_clm=newline.attrib['flagN'], Z=Zion[0], ion=Zion[1])  
        # Append
        lls.lines.append(newline)
    # Fix NI, OI
    ion_dict['O I']['clm'] = 14.47
    ion_dict['O I']['sig_clm'] = 0.05
    ion_dict['N I']['flg_clm'] = 3