#!/usr/bin/python3
import os,sys,math
import numpy as np
import copy

def ams_whitespacesplit(ln):
    splitline = []

    I1 = -1
    I2 = -1
    mode = 0
    for I in range(0,len(ln)):
        c = ln[I]
        if(not c.isspace() and mode==0):
            mode = 1
            I1 = I
        if(c.isspace() and mode==1):
            I2 = I
            s = ln[I1:I2]
            splitline.append(s)
            mode = 0
    if(mode==1):
        I2 = len(ln)
        s = ln[I1:I2]
        splitline.append(s)
        mode = 0

    return splitline

def convert_stringlist_to_numeric(stringlist):

    nlist = np.zeros(len(stringlist),dtype=np.float64)

    for I in range(0,len(stringlist)):
        try:
            q = float(stringlist[I])
        except:
            q = 0.0
        nlist[I] = q
    return nlist


def load_igrfdata():
    datastruct = dict()
    lns = []
    sdir = os.path.split(__file__)[0]
    fname = "{}/igrf13_data.txt".format(sdir)
    fp = open(fname,"r")

    ln = " "
    mode = 0
    N = 0
    gharray = []
    narray = []
    marray = []
    amplitudetable = []

    while(ln!=""):
        ln = fp.readline()
        if(ln.find("g/h n m")>=0 and mode==0):
            mode = 1
            #read date line
            dateline = ams_whitespacesplit(ln)
            dateline = dateline[3:len(dateline)]
            dateline = convert_stringlist_to_numeric(dateline)

            datastruct["year"] = dateline
        elif(mode==1):
            lns = ams_whitespacesplit(ln)
            if(len(lns)>5):
                if(lns[0]=='g'):
                    gh = 0
                else:
                    gh = 1
                gharray.append(gh)
                lnsn = convert_stringlist_to_numeric(lns)
                narray.append(lnsn[1])
                marray.append(lnsn[2])
                amplitudetable.append(lnsn[3:len(lnsn)])
                N = N + 1
    
    gharray = np.int32(gharray)
    narray = np.int32(narray)
    marray = np.int32(marray)
    
    atable = np.zeros([len(amplitudetable),len(amplitudetable[0])],dtype=np.float64)
    for I in range(0,atable.shape[0]):
        atable[I,:] = amplitudetable[I][:]
    
    datastruct["gh"] = gharray
    datastruct["n"] = narray
    datastruct["m"] = marray
    datastruct["a"] = atable
                
    fp.close()


    return datastruct

def igrf_getcomponents(year,igrfdatastruct):

    acomp = None
    a = igrfdatastruct["a"]

    if(year<1900):
        acomp = a[:,0]
    elif(year>=2020):
        ac0 = a[:,a.shape[1]-2]
        ac1 = a[:,a.shape[1]-1]
        acomp = ac0 + ac1*(year-2020)
    else:
        I0 = int(np.floor((year-1900)/5.0))
        I1 = I0 + 1
        ac0 = a[:,I0]
        ac1 = a[:,I1]
        acomp = (ac1-ac0)/5.0*(year-(1900+5*I0)) + ac0

    return acomp

def igrf_getcompstruct(year, igrfdatastruct):

    acomp = igrf_getcomponents(year, igrfdatastruct);
    compstruct = copy.deepcopy(igrfdatastruct)
    compstruct["a"] = acomp

    return compstruct