#Physical constants

module constants

export M_sun, M_earth, AU, pc, G, kB, h, amu, c_ang, cc, c_kms, molnames, arcsec, deg, lam0s, nyquist_factor, mu_gas, m_H
export Molecule, mols
export DiskTracerException, ModelException, ImageException
export DISKTRACER_VERSION

DISKTRACER_VERSION = v"0.1.0"

# Conversion from astronomical units to CGS units
const M_sun = 1.99e33 # [g]
const M_earth = 5.97219e27 # [g]
const AU = 1.4959787066e13 # [cm]
const pc = 3.0856776e18 # [cm]
const G = 6.67259e-8 # [cm3 g-1 s-2]
const kB = 1.380658e-16 # [erg K^-1] Boltzmann constant
const h = 6.6260755e-27 #erg s Planck constant
const c_ang = 2.99792458e18 # [A s^-1]
const cc = 2.99792458e10 # [cm s^-1]
const c_kms = 2.99792458e5 # [km s^-1]

# Conversion from degrees to radians
const deg = pi/180. # [radians]

const mu_gas = 2.37 # mean molecular weight of circumstellar gas
const m_H = 1.6733e-24 # g mass of hydrogen atom

#Atomic
const amu = 1.6605402e-24 # [g]

# To hold molecular constants
struct Molecule
    X_mol::Float64 # number fraction of molecule
    B0::Float64 # rigid rotor constant of molecule (Hz)
    mu::Float64 # (e.s.u. cm) permanent dipole moment of the molecule
    mol_weight::Float64 # (g) molecular weight
    nu_0::Float64 # (Hz) central frequency of transition
    l::Int # lower level of transition
    T_L::Float64 # (K) temperature equivalent of energy at lower transition
end

# Using numbers from Charlie Qi
# Number ratios measured relative to all single H nuclei (not H2) [unitless]
f_12CO = 7.5e-5
X_12CO = 2 * f_12CO
X_13CO = 1/69. * X_12CO
X_C18O = 1/557. * X_12CO

# molecular hydrogen number ratio to gas [unitless]
# [n_H2/n_gas] = 0.8
X_H2 = 0.8

# To go from rho_gas to n_12CO
# n_12CO = rho_gas * X_H2 *

# Old number densities calculated as
# 12CO = 7.5e-5 / (mu_gas * amu)

# New number density calculated as
# 12CO = 0.8 * (2 * 7.5e-5)/ (mu_gas * amu)

# new/old = 1.6
# This means that the new total disk mass we use will be 1/1.6 times smaller than the old time.

# Number ratios relative to average molecule (chi_CO)
# Multiply this against rho to get number of molecules
chi_12CO = X_H2 * X_12CO/(mu_gas * amu)
chi_13CO = X_H2 * X_13CO/(mu_gas * amu)
chi_C18O = X_H2 * X_C18O/(mu_gas * amu)

#CO
m_CO = 28.01 * amu #molecular weight of CO in g
m_12CO = 27.9949 * amu # [g]
m_13CO = 28.9983 * amu # [g]
m_C18O = 29.9992 * amu # [g]


CO12_21 = Molecule(chi_12CO, 57635.96e6, 1.1011e-19, m_12CO, 230.53800000e6, 1, 5.5321)
CO12_32 = Molecule(chi_12CO, 57635.96e6, 1.1011e-19, m_12CO, 345.79598990e6, 2, 16.5962)
CO13_21 = Molecule(chi_13CO, 55101.01e6, 1.1046e-19, m_13CO, 220.39868420e6, 1, 5.2888)
CO13_32 = Molecule(chi_13CO, 55101.01e6, 1.1046e-19, m_13CO, 330.58796530e6, 2, 15.8662)
CO18_21 = Molecule(chi_C18O, 54891.42e6, 1.1079e-19, m_C18O, 219.56035410e6, 1, 5.2686)
CO18_32 = Molecule(chi_C18O, 54891.42e6, 1.1079e-19, m_C18O, 329.33055250e6, 2, 15.8059)

# Species can be "12CO", "13CO", etc.
# Transition can be "3-2", "2-1", etc.
# The key to this dictionary is then species * transition

mols = Dict{String, Molecule}([("12CO2-1", CO12_21),
            ("12CO3-2", CO12_32),
            ("13CO2-1", CO13_21),
            ("13CO3-2", CO13_32),
            ("C18O2-1", CO18_21),
            ("C18O3-2", CO18_32)])


atomic_massses = Dict([("12CO", m_12CO), ("13CO", m_13CO), ("C18O", m_C18O)])

molnames = Dict{String, String}([("12CO", "co"), ("13CO", "13co"), ("C18O", "c18o")])


# Rest frame wavelengths
lam0s = Dict{String, Float64}([("12CO2-1", cc/230.538e9 * 1e4 ),
            ("13CO2-1", cc/220.39868e9 * 1e4),
            ("13CO3-2", cc/330.58797e9 * 1e4),
            ("C18O2-1", cc/219.56036e9 * 1e4),
            ("12CO3-2", cc/345.79599e9 * 1e4)]) # microns


# Used when determining the necessary number of pixels in an image, given distance. Anything below
# 2 is not Nyquist sampled. This is currently set to 2.2 to provide a degree of oversampling.
nyquist_factor = 2.2


# Abstract exception that serves as a catch-all for any error generated by the DiskJockey package.
abstract type DiskTracerException <: Exception end

# Define the various types of Errors that we can Raise
type ModelException <: DiskTracerException
    msg::String
end

type ImageException <: DiskTracerException
    msg::String
end

end # Module
