#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

#from fw.common.Result import * ##[inamura 140204]
import os, datetime
from xml.dom.minidom import parse
import Manyo.Utsusemi as mu

# 原子情報ファイル名
DEF_ATOM_DB_FILE_NAME = 'atomDBTaikan.xml'

# 辞書のキー名
DEF_ATOM_DB_KEY_DICTIONARY = 'dictionary'

# タグ名
DEF_ATOM_DB_ATOMDBTAIKAN_TAG = 'AtomDBTaikan'					# AtomDBTaikan
DEF_ATOM_DB_NO_TAG = 'No'										# No
DEF_ATOM_DB_INCB_TAG = 'Incb'									# Incb
DEF_ATOM_DB_COHB_TAG = 'Cohb'									# Cohb
DEF_ATOM_DB_COHXS_TAG = 'Cohxs'									# Cohxs
DEF_ATOM_DB_INCXS_TAG = 'Incxs'									# Incxs
DEF_ATOM_DB_SCATTXS_TAG = 'Scattxs'								# Scattxs
DEF_ATOM_DB_ABSXS_TAG = 'Absxs'									# Absxs
DEF_ATOM_DB_ISOTOPE_TAG = 'Isotope'								# Isotope

# ViewRed, ViewGreen, ViewBlueを全て取得したいときに指定するタグ名
DEF_ATOM_DB_VIEWCOLORS_TAG = 'Viewcolors'

# 属性名
DEF_ATOM_DB_ID_TAG = 'Id'										# Id
DEF_ATOM_DB_ATOMNAME_TAG = 'AtomName'							# AtomName
DEF_ATOM_DB_MOLWEIGHT_TAG = 'MolWeight'							# MolWeight
DEF_ATOM_DB_VIEWRED_TAG = 'ViewRed'								# ViewRed
DEF_ATOM_DB_VIEWGREEN_TAG = 'ViewGreen'							# ViewGreen
DEF_ATOM_DB_VIEWBLUE_TAG = 'ViewBlue'							# ViewBlue
DEF_ATOM_DB_VIEWSIZE_TAG = 'ViewSize'							# ViewSize
DEF_ATOM_DB_NAME_TAG = 'Name'									# Name
DEF_ATOM_DB_MASS_TAG = 'Mass'									# Mass
DEF_ATOM_DB_CONC_TAG = 'Conc'									# Conc
DEF_ATOM_DB_HALFLIFE_TAG = 'HalfLife'							# HalfLife
DEF_ATOM_DB_UNC_TAG = 'Unc'										# Unc

# 戻り値
DEF_ATOM_DB_GET_VALUE = 0										# 値取得
DEF_ATOM_DB_GET_PARENT_VALUE = 1								# 親の値を返す
DEF_ATOM_DB_GET_ISOTOPE_VALUE = 2								# 同位体の値を返す
DEF_ATOM_DB_ARG_ERROR = 3										# 引数間違い
DEF_ATOM_DB_NOVAL = 4											# 値なし

##[inamura 140204]-->
RSLT_OK = 'OK'
RSLT_NG = 'NG'
class Result(object):
	def __init__(self, status):
		self.status = status
##<--[inamura 140204]

###############################################################################
# 定数値定義
###############################################################################


###############################################################################
# 大観用原子情報DBクラス
###############################################################################
class AtomDBTaikanClass(object):
	def __init__(self):
		"""
		コンストラクタ

		@param	self					自身のインスタンス
		@retVal	なし
		"""
		# AtomDBファイルから取得する原子情報を入れるテーブルの初期化
		self.atomIDNameList = []
		self.atomInfo = []
		self.isoTopeInfo = []

		# 共有データを特定する為のキー
		self.__key = ''

	###########################################################################
	def ReadDBFile(self, filepath = ""):
		"""
		原子情報DBデータ取得処理
		AtomDBTaikanからパラメータを取得し属性へ設定する。
   		@param	self									自身のインスタンス
		@param	params				(Element)			パラメータ
		"""
	#	## XML file読み込み
	#	if "" == filepath:
	#		# ファイルパスの指定がない場合は固定のパスを使用する。
	#		xmlpath = os.path.join(os.environ["MLF_USR_DIR"], "ana/xml", DEF_ATOM_DB_FILE_NAME)
	#	else:
	#		xmlpath = filepath

		## XML ファイルパス生成
		xmlpath = self.__MakeDBFilePath(filepath)

		## XML file読み込み
		if not os.path.exists(xmlpath):
			print("AtomDBTaikan.xml is not exist. Pass = ", xmlpath)
	#		raise Exception
			return Result(RSLT_NG)
		else:
			xmlfile = parse(xmlpath)

		# 共有データを特定する為のキーとして、AtomDBTaikan.xmlのフルパスを使用する
		self.__key = self.MakeKey(xmlpath)

		# AtomDBTaikanタグの取得
		atomDBTaikanInfo = xmlfile.getElementsByTagName(DEF_ATOM_DB_ATOMDBTAIKAN_TAG)[0]

		# No タグの取得
		noInfoList = atomDBTaikanInfo.getElementsByTagName(DEF_ATOM_DB_NO_TAG)

		for i, noInfoXml in enumerate(noInfoList):

			# 原子の辞書を作成し、リストに追加。
			atom_dic = self.MakeAtomDictionary(noInfoXml)
			if {} != atom_dic:
				self.atomInfo.append(atom_dic)

			# Isotope タグの取得
			isotopeInfoList = noInfoXml.getElementsByTagName(DEF_ATOM_DB_ISOTOPE_TAG)
			isotope_dic_list = []
			for j, isotopeInfoXml in enumerate(isotopeInfoList):
				# 同位体の辞書を作成し、リストに追加。
				isotope_dic_list.append(self.MakeIsotopeDictionary(isotopeInfoXml))

			# idとAtomNameが存在したら、同位体リストの辞書を作成し、リストに追加する。
			if DEF_ATOM_DB_ID_TAG in atom_dic and DEF_ATOM_DB_ATOMNAME_TAG in atom_dic:
				isotope_dic = {}
				isotope_dic[DEF_ATOM_DB_ID_TAG] = atom_dic[DEF_ATOM_DB_ID_TAG]
				isotope_dic[DEF_ATOM_DB_ATOMNAME_TAG] = atom_dic[DEF_ATOM_DB_ATOMNAME_TAG]
				isotope_dic[DEF_ATOM_DB_KEY_DICTIONARY] = isotope_dic_list
				self.isoTopeInfo.append(isotope_dic)

			#print 'self.atomIDNameList = ', self.atomIDNameList
			#print 'self.atomInfo = ', self.atomInfo
			#print 'self.isoTopeInfo = ', self.isoTopeInfo

	###########################################################################
	def MakeAtomDictionary(self, noInfoXml):
		"""
		Noのタグ下のXML情報から原子情報の辞書を作成する
		@param	self									自身のインスタンス
		@param	noInfoXml		(XML)					No下のXML情報
		@retval					(dictionary)			原子情報の辞書
		"""
		atr_dic = {}
		info_dic = {}
		id_name_list = []
		atom_dic = {}
		# No下の属性情報を取得する。
		# [id,AtomName,MolWeight,ViewRed,ViewGreen,ViewBlue,ViewSize]のリストになっている。
		atr_dic = self.GetNoAttribute(noInfoXml)

		# No下の原子情報を取得する。
		# [Cohb,Incb,Cohxs,Incxs,Scattxs,Absxs]のリストになっている。
		info_dic = self.GetAtomInfo(noInfoXml)
		# idとAtomNameを取得し、リスト化する。
		if DEF_ATOM_DB_ID_TAG in atr_dic and DEF_ATOM_DB_ATOMNAME_TAG in atr_dic:
			id_name_list.append(atr_dic[DEF_ATOM_DB_ID_TAG])
			id_name_list.append(atr_dic[DEF_ATOM_DB_ATOMNAME_TAG])
			self.atomIDNameList.append(id_name_list)

			# 原子の辞書を作成。
			atom_dic.update(atr_dic)
			atom_dic.update(info_dic)

		#print 'id_name_list = ', id_name_list
		#print 'atom_dic = ', atom_dic

		return atom_dic

	###########################################################################
	def MakeIsotopeDictionary(self, noInfoXml):
		"""
		Isotopeのタグ下のXML情報から同位体情報の辞書を作成する
		@param	self									自身のインスタンス
		@param	noInfoXml		(XML)					Isotope下のXML情報
		@retval					(dictionary)			同位体情報の辞書
		"""
		atr_dic = {}
		info_dic = {}
		isotope_dic = {}
		# Isotope下の属性情報を取得する。
		# [Name,Mass,Conc,ViewRed,ViewGreen,ViewBlue,ViewSize]の辞書になっている。
		atr_dic = self.GetIsotopeAttribute(noInfoXml)

		# Isotope下の原子情報を取得する。
		# [Cohb,Incb,Cohxs,Incxs,Scattxs,Absxs]の辞書になっている。
		info_dic = self.GetAtomInfo(noInfoXml)

		# 同位体の辞書を作成。
		isotope_dic.update(atr_dic)
		isotope_dic.update(info_dic)

		#print 'isotope_dic = ', isotope_dic

		return isotope_dic

	###########################################################################
	def MakeKey(self, filepath):
		"""
		データ情報の値に応じてユニークなキーを作成する

		キーのフォーマットは任意
		"""
		return self.__MakeDBFilePath(filepath).replace( '\\', '/' )

	###########################################################################
	def GetKey(self):
		"""
		ユニークなキーを取得する
		※キーのフォーマットは任意

		@param self クラスのインスタンス
		@retval     キー
		"""
		return self.__key

	###########################################################################
	def __MakeDBFilePath(self, filepath):
		"""
		AtomDBTaikan.xmlのフルパス生成

		@param self      クラスのインスタンス
		@param filepath  AtomDBTaikan.xmlのフルパス
		@retval          AtomDBTaikan.xmlのフルパス
		"""
		if "" == filepath:
			# ファイルパスの指定がない場合は固定のパスを使用する。
			#xmlpath = os.path.join(os.environ["UTSUSEMI_USR_DIR"], "ana","xml", DEF_ATOM_DB_FILE_NAME) ##[inamura 140204]
                        xmlpath = mu.FindParamFilePath( DEF_ATOM_DB_FILE_NAME )
                        if xmlpath=="":
                                raise UserWarning("DBfile not found."+DEF_ATOM_DB_FILE_NAME)
		else:
			xmlpath = filepath

		return xmlpath

	###########################################################################
	def GetNoAttribute(self, no_info_xml):
		"""
		Noの属性として持っている情報をXMLから取得する
		「id」、「AtomName」、「MolWeight」、「ViewRed」、「ViewGreen」、「ViewBlue」、
		「ViewSize」を取得し、辞書化して戻り値として返す。
		@param	self									自身のインスタンス
		@param	noinfoxml		(XML)					No下のXML情報
		@retval					(dictionary)			{id,AtomName,MolWeight,
											ViewRed,ViewGreen,ViewBlue,ViewSize}
		"""
		info_dic = {}
		# 属性から取得。
		no_id = no_info_xml.getAttribute(DEF_ATOM_DB_ID_TAG)
		atom_name = no_info_xml.getAttribute(DEF_ATOM_DB_ATOMNAME_TAG)
		molweight = no_info_xml.getAttribute(DEF_ATOM_DB_MOLWEIGHT_TAG)
		view_red = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWRED_TAG)
		view_green = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWGREEN_TAG)
		view_blue = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWBLUE_TAG)
		view_size = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWSIZE_TAG)

		# リストに追加。
		info_dic[DEF_ATOM_DB_ID_TAG] = no_id
		info_dic[DEF_ATOM_DB_ATOMNAME_TAG] = atom_name
		info_dic[DEF_ATOM_DB_MOLWEIGHT_TAG] = molweight
		info_dic[DEF_ATOM_DB_VIEWRED_TAG] = view_red
		info_dic[DEF_ATOM_DB_VIEWGREEN_TAG] = view_green
		info_dic[DEF_ATOM_DB_VIEWBLUE_TAG] = view_blue
		info_dic[DEF_ATOM_DB_VIEWSIZE_TAG] = view_size

		return info_dic

	###########################################################################
	def GetIsotopeAttribute(self, no_info_xml):
		"""
		Isotopeの属性として持っている情報をXMLから取得する
		「Name」、「Mass」、「Conc」、「ViewRed」、「ViewGreen」、「ViewBlue」、
		「ViewSize」を取得し、辞書化して戻り値として返す。
		@param	self									自身のインスタンス
		@param	noinfoxml		(XML)					No下のXML情報
		@retval					(dictionary)			{Name,Mass,Conc,ViewRed,
													ViewGreen,ViewBlue,ViewSize}
		"""
		info_dic = {}
		# 属性から取得。
		name = no_info_xml.getAttribute(DEF_ATOM_DB_NAME_TAG)
		mass = no_info_xml.getAttribute(DEF_ATOM_DB_MASS_TAG)
		conc = no_info_xml.getAttribute(DEF_ATOM_DB_CONC_TAG)
		halflife = no_info_xml.getAttribute(DEF_ATOM_DB_HALFLIFE_TAG)
		view_red = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWRED_TAG)
		view_green = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWGREEN_TAG)
		view_blue = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWBLUE_TAG)
		view_size = no_info_xml.getAttribute(DEF_ATOM_DB_VIEWSIZE_TAG)

		# リストに追加。
		info_dic[DEF_ATOM_DB_NAME_TAG] = name
		info_dic[DEF_ATOM_DB_MASS_TAG] = mass
		info_dic[DEF_ATOM_DB_CONC_TAG] = conc
		info_dic[DEF_ATOM_DB_HALFLIFE_TAG] = halflife
		info_dic[DEF_ATOM_DB_VIEWRED_TAG] = view_red
		info_dic[DEF_ATOM_DB_VIEWGREEN_TAG] = view_green
		info_dic[DEF_ATOM_DB_VIEWBLUE_TAG] = view_blue
		info_dic[DEF_ATOM_DB_VIEWSIZE_TAG] = view_size

		return info_dic

	###########################################################################
	def GetAtomInfo(self, no_info_xml):
		"""
		原子情報をXMLから取得する
		「Cohb」、「Incb」、「Cohxs」、「Incxs」、「Scattxs」、「Absxs」を
		取得し、辞書化して戻り値として返す。
		@param	self									自身のインスタンス
		@param	noinfoxml		(XML)					No下のXML情報
		@retval					(dictionary)			{Cohb,Incb,Cohxs,Incxs,
																Scattxs,Absxs}
		"""
		info_dic = {}

		# No下の直下のElementの子ノードを取得する。
		choices = [e for e in no_info_xml.childNodes if e.nodeType == e.ELEMENT_NODE]

		# No下のCohb、Incb、Cohxs、Incxs、Scattxs、Absxsをタグ指定で取得。
		for i, choice in enumerate(choices):
			#print 'i =', i
			#print 'choice =', choice
			tagname = choice.tagName
			val = choice.firstChild.data
			atr_val = choice.getAttribute(DEF_ATOM_DB_UNC_TAG)

			if DEF_ATOM_DB_COHB_TAG == tagname or DEF_ATOM_DB_INCB_TAG == tagname \
				or DEF_ATOM_DB_COHXS_TAG == tagname or DEF_ATOM_DB_INCXS_TAG == tagname \
				or DEF_ATOM_DB_SCATTXS_TAG == tagname or DEF_ATOM_DB_ABSXS_TAG == tagname:
				list = []
				list.append(val)
				list.append(atr_val)
				info_dic[tagname] = list
		#print 'info_dic', info_dic

		return info_dic

	###########################################################################
	def PutIsotopeNameAndMassList_Name(self, atom_name):
		"""
		atom_nameで指定された原子名の同位体名と質量のリストを返す。
		@param	self									自身のインスタンス
		@param	atom_name		(string)				原子名
		@retval					(list)					同位体名と質量からなるリストの二重リスト
		@retval					(Result)				取得の成否
		"""
		name_mass_list = []
		rslt = Result(RSLT_OK)

		for isotope_dic in self.isoTopeInfo:
			dic_list = []
			if atom_name == isotope_dic[DEF_ATOM_DB_ATOMNAME_TAG]:
				dic_list = isotope_dic[DEF_ATOM_DB_KEY_DICTIONARY]
				for dic in dic_list:
					nm_list = []
					name = dic[DEF_ATOM_DB_NAME_TAG]
					mass = dic[DEF_ATOM_DB_MASS_TAG]
					nm_list.append(name)
					nm_list.append(mass)
					name_mass_list.append(nm_list)
				break
			else:
				continue
		if 0 == len(name_mass_list):
			# リストが存在しないならば、取得失敗
			rslt = Result(RSLT_NG)
			print('NG!')

		return name_mass_list, rslt

	###########################################################################
	def PutIsotopeNameAndMassList_No(self, atom_no):
		"""
		atom_noで指定された原子番号の同位体名と質量のリストを返す。
		@param	self									自身のインスタンス
		@param	atom_no			(string)				原子番号
		@retval					(list)					同位体名と質量からなるリストの二重リスト
		"""
		name_mass_list = []
		rslt = Result(RSLT_OK)

		for isotope_dic in self.isoTopeInfo:
			dic_list = []
			if atom_no == isotope_dic[DEF_ATOM_DB_ID_TAG]:
				dic_list = isotope_dic[DEF_ATOM_DB_KEY_DICTIONARY]
				for dic in dic_list:
					nm_list = []
					name = dic[DEF_ATOM_DB_NAME_TAG]
					mass = dic[DEF_ATOM_DB_MASS_TAG]
					nm_list.append(name)
					nm_list.append(mass)
					name_mass_list.append(nm_list)
				break
			else:
				continue
		if 0 == len(name_mass_list):
			# リストが存在しないならば、取得失敗
			rslt = Result(RSLT_NG)
			print('NG!')

		return name_mass_list, rslt

	###########################################################################
	def PutAtomInfoFromDictonary_No(self, atom_no, tag):
		"""
		atom_noで指定された原子番号に該当する原子の辞書からtagで指定された値を返す。
		@param	self									自身のインスタンス
		@param	atom_no			(string)				原子番号
		@param	tag				(string)				タグ名
		@retval					(string)				原子番号、タグで指定された情報
		@retval					(int)					処理結果
		"""
		dic = {}
		rslt = DEF_ATOM_DB_GET_VALUE
		val = ""
		rv = []

		for atom_dic in self.atomInfo:
			if atom_no == atom_dic[DEF_ATOM_DB_ID_TAG]:
				dic = atom_dic
				#print 'dic = ', dic
				break
			else:
				continue
		if 0 == len(dic):
			# 辞書が存在しないならば、取得失敗
			rslt = DEF_ATOM_DB_ARG_ERROR
			print('NG!')

		if tag in dic:
			val = dic[tag]
			if DEF_ATOM_DB_INCB_TAG == tag and "---" == val[0]:
				# Incbタグ指定時に値が'---'(なし)である場合は取得失敗
				rslt = DEF_ATOM_DB_NOVAL
		else:
			# tagが存在しないならば、取得失敗
			rslt = DEF_ATOM_DB_ARG_ERROR

		if type([]) != type(val):
			# 行列でないなら、戻り値の行列に要素追加
			rv.append(val)
		else:
			# 行列なら、戻り値の行列に連結
			rv.extend(val)
		return rv, rslt

	###########################################################################
	def PutAtomInfoFromDictonary_Name(self, atom_name, tag):
		"""
		atom_nameで指定された原子名に該当する原子の辞書からtagで指定された値を返す。
		@param	atom_no			(string)				原子名
		@param	tag				(string)				タグ名
		@retval					(string)				原子番号、タグで指定された情報
		@retval					(int)					処理結果
		"""
		dic = {}
		rslt = DEF_ATOM_DB_GET_VALUE
		val = ""
		rv = []
		for atom_dic in self.atomInfo:
			if atom_name == atom_dic[DEF_ATOM_DB_ATOMNAME_TAG]:
				dic = atom_dic
				#print 'dic = ', dic
				break
			else:
				continue
		if 0 == len(dic):
			# 辞書が存在しないならば、取得失敗
			rslt = DEF_ATOM_DB_ARG_ERROR
			print('NG!')

		if tag in dic:
			val = dic[tag]

			if DEF_ATOM_DB_INCB_TAG == tag and "---" == val[0]:
				# Incbタグ指定時に値が'---'(なし)である場合は取得失敗
				rslt = DEF_ATOM_DB_NOVAL
		else:
			# tagが存在しないならば、取得失敗
			rslt = DEF_ATOM_DB_ARG_ERROR

		if type([]) != type(val):
			# 行列でないなら、戻り値の行列に要素追加
			rv.append(val)
		else:
			# 行列なら、戻り値の行列に連結
			rv.extend(val)
		return rv, rslt

	###########################################################################
	def PutIsotopeInfoFromDictonary(self, isotope, tag):
		"""
		isotopeで指定された同位体名に該当する原子の辞書からtaで指定された値を返す。
		@param	atom_no			(string)				同位体名
		@param	tag				(string)				タグ名
		@retval					(string)				同位体名、タグで指定された情報
		@retval					(int)					処理結果
		"""
		dic = {}
		rslt = DEF_ATOM_DB_GET_VALUE
		val = ""
		rv = []

		for isotope_dics in self.isoTopeInfo:
			for isotope_dic in isotope_dics[DEF_ATOM_DB_KEY_DICTIONARY]:
				if isotope == isotope_dic[DEF_ATOM_DB_NAME_TAG]:
					dic = isotope_dic
					atom_name = isotope_dics[DEF_ATOM_DB_ATOMNAME_TAG]
					#print 'dic = ', dic
					#print 'atom_name = ', atom_name
					break
				else:
					continue
			if 0 != len(dic):
				# 辞書が見つかったら、ループ終了。
				break

		if 0 == len(dic):
			# 辞書が存在しないならば、取得失敗
			rslt = DEF_ATOM_DB_ARG_ERROR
			print('NG!')
		else:
			#print 'tag = ', tag
			if tag in dic:
				val = dic[tag]
				rslt = DEF_ATOM_DB_GET_VALUE
				if '' == dic[tag]:
					# 値が存在しないならば、原子から取得する。
					rslt = DEF_ATOM_DB_NOVAL
			else:
				# tagが存在しないならば、原子から取得する。
					rslt = DEF_ATOM_DB_NOVAL

			if DEF_ATOM_DB_NOVAL == rslt:
				# 原子から取得する。
				val, rslt = self.PutAtomInfoFromDictonary_Name(atom_name, tag)
				print('@@@rslt = ',rslt)
				if DEF_ATOM_DB_GET_VALUE == rslt:
					# 原子から値取得成功。
					rslt = DEF_ATOM_DB_GET_PARENT_VALUE


		if type([]) != type(val):
			# 行列でないなら、戻り値の行列に要素追加
			rv.append(val)
		else:
			# 行列なら、戻り値の行列に連結
			rv.extend(val)
		return rv, rslt

	###########################################################################
	def GetAtomNameList(self, id_name_list):
		"""
		原子名リストを取得する(GUI周期表用)
		「No id」の順に「AtomName」を配列に取得する。
		配列は2次元にしてNoも取得する。
		引数にはリストを渡さないと、エラーを返すことに注意すること。
		戻り値は成否。
		@param	self									自身のインスタンス
		@param	id_name_list	(list)					取得する番号と原子名のリストからなる二重リスト
		@retval					(Result)				処理結果
		"""
		rslt = Result(RSLT_OK)

		# id_name_listがリスト型でなければNG。
		if type([]) != type(id_name_list):
			rslt = Result(RSLT_NG)
		else:
			# id_name_listのリスト内をクリアする。
			for i, x in enumerate(id_name_list):
				id_name_list.pop(i)

		# self.atomIDNameListが空リストならNG。
		if len(self.atomIDNameList) == 0:
			rslt = Result(RSLT_NG)

		if RSLT_OK == rslt.status:
			for atomlist in self.atomIDNameList:
				id_name_list.append(atomlist)

		return Result(RSLT_OK)

	###########################################################################
	def GetValue(self, key, tag, return_val):
		"""
		原子名or同位体名or原子番号、getする値のタグで指定された値を文字列で取得する
		(アルファベットのみ→原子名、混合→IsoTope、数字→原子番号)
		ただし、
			(1)Isotopeのプロパティがない場合は、原子のタグから値を引いて戻す。(親の値を取得)
			(2)AtomのIncbを取得する場合、値がない場合は、同位体の存在比(conc)とIncbから計算して戻す。(同位体の値を取得)
		(1)(2)もできない場合は、否：値がない

		戻り値は成否。
			成:値を取得(0)、親の値を取得(1)、同位体の値(2)を取得の3種類
			否:引数の間違い(3)、値がない(4)の2種類

		@param	self									自身のインスタンス
		@param	key				(string)				原子名or同位体名or原子番号
		@param	tag				(string)				getする値のタグ
		@param	return_val								引数で指定されたタグの値のリスト(プロパティのUncがあれば、値用の変数を(値、Unc)で戻す)
		@retval					(Result)				処理結果
		"""
		rslt = DEF_ATOM_DB_GET_VALUE
		dic = {}

		# return_valがリストでなければ、引数の間違い。
		if type([]) != type(return_val):
			print('retval_err')
			rslt = DEF_ATOM_DB_ARG_ERROR
		else:
			# return_valのリスト内をクリアする。
			for i, x in enumerate(return_val):
				return_val.pop(i)

		print('key = ',key)
		# keyが文字列でなければ、引数の間違い。
		if type(str()) != type(key):
			print('key_err')
			rslt = DEF_ATOM_DB_ARG_ERROR
		elif 0 == len(key):
			# 空文字列であるなら、引数の間違い。
			print('key_err2')
			rslt = DEF_ATOM_DB_ARG_ERROR

		# tagが文字列でなければ、引数の間違い。
		if type(str()) != type(tag):
			print('tag_err')
			rslt = DEF_ATOM_DB_ARG_ERROR
		elif 0 == len(tag):
			# 空文字列であるなら、引数の間違い。
			print('tag_err2')
			rslt = DEF_ATOM_DB_ARG_ERROR

		val = []
		val_l = []
		taglist = []
		if DEF_ATOM_DB_VIEWCOLORS_TAG == tag:
			# Viewcolorsを指定されたら、赤、緑、青を一度に全て取得すること。
			taglist = [DEF_ATOM_DB_VIEWRED_TAG, DEF_ATOM_DB_VIEWGREEN_TAG, DEF_ATOM_DB_VIEWBLUE_TAG]
		else:
			taglist.append(tag)

		if DEF_ATOM_DB_ARG_ERROR != rslt:
			for i, tag_n in enumerate(taglist):
				#print 'tag_n = ', tag_n
				if True == key.isalpha():
					# アルファベットのみは原子名での指定
					#print'alpha'
					val, rslt = self.PutAtomInfoFromDictonary_Name(key, tag_n)
				elif True == key.isdigit():
					# 数字のみは原子番号での指定
					#print'number'
					val, rslt = self.PutAtomInfoFromDictonary_No(key, tag_n)
				elif True == key.isalnum():
					# 数字と原子番号の混合での指定は同位体
					#print'number+alpha'
					val, rslt = self.PutIsotopeInfoFromDictonary(key, tag_n)
				else:
					# 指定が数字のみ、アルファベットのみでない場合はNG
					rslt = DEF_ATOM_DB_ARG_ERROR
				val_l.extend(val)
			# 引数にリストを設定。
			return_val.extend(val_l)

		return val, rslt

	###########################################################################
	def GetIsotopeNameList(self, atom_info, isotope_name_list):
		"""
		同位体名リストを取得する(GUI周期表用)
		原子名or原子番号で、getする同位体を指定する。
		戻りはMass順にソートする。
		配列は2次元にして、Massも取得する。
		引数にはリストを渡さないと、エラーを返すことに注意すること。
		@param	self									自身のインスタンス
		@param	atom_info		(string)				原子名or原子番号
		@param	isotope_name_list	(list)					取得する同位体名とMassのリストからなる二重リスト
		@retval					(Result)				処理結果
		"""
		isotope_info_list = []
		rslt = Result(RSLT_OK)

		# isotope_name_listがリスト型でなければNG。
		if type([]) != type(isotope_name_list):
			rslt = Result(RSLT_NG)
		else:
			# リスト型なら、リストをクリアする。
			for i, x in enumerate(isotope_name_list):
				isotope_name_list.pop(i)

		# isotope_name_listが空リストでないならNG。
	#	if len(isotope_name_list) !=0:
	#		rslt = Result(RSLT_NG)

		if RSLT_OK == rslt.status:
			if True == atom_info.isalpha():
				# アルファベットのみは原子名での指定
				isotope_info_list, rslt = self.PutIsotopeNameAndMassList_Name(atom_info)
			elif True == atom_info.isdigit():
				# 数字のみは原子番号での指定
				isotope_info_list, rslt = self.PutIsotopeNameAndMassList_No(atom_info)
			else:
				# 指定が数字のみ、アルファベットのみでない場合はNG
				rslt = Result(RSLT_NG)

		if RSLT_OK == rslt.status:
			for list in sorted(isotope_info_list, key = lambda x:x[1], reverse = False):
				isotope_name_list.append(list)
		else:
			print('NG!')

		return rslt

###############################################################################
# 原子名or同位体名or原子番号、getする値のタグで指定された値を文字列で取得する関数
###############################################################################
def GetValue(key, tag, xmlpath = ""):
	"""
	原子名or同位体名or原子番号、getする値のタグで指定された値を文字列で取得する
	(アルファベットのみ→原子名、混合→IsoTope、数字→原子番号)
	ただし、
		(1)Isotopeのプロパティがない場合は、原子のタグから値を引いて戻す。(親の値を取得)
		(2)AtomのIncbを取得する場合、値がない場合は、同位体の存在比(conc)とIncbから計算して戻す。(同位体の値を取得)
	(1)(2)もできない場合は、否：値がない

	戻り値は成否。
		成:値を取得(0)、親の値を取得(1)、同位体の値(2)を取得の3種類
		否:引数の間違い(3)、値がない(4)の2種類
	@param	key				(string)				原子名or同位体名or原子番号
	@param	tag				(string)				getする値のタグ
	@param	xmlpath			(string)				atomDBTaikan.xmlのフルパス
	@retval					(Result)				処理結果
	@retval					(list)					引数で指定されたタグの値のリスト(プロパティのUncがあれば、値用の変数を(値、Unc)で戻す)
	"""

	print('xmlpath:', xmlpath)
	return_val = []
	adt = AtomDBTaikanClass()
	adt.ReadDBFile(xmlpath)

	val, rs = adt.GetValue(key, tag, return_val)

	return rs, return_val

###############################################################################
# 原子名リストを取得する関数
###############################################################################
def GetAtomNameList(xmlpath = ""):
	"""
	原子名リストを取得する(GUI周期表用)
	「No id」の順に「AtomName」を配列に取得する。
	配列は2次元にしてNoも取得する。
	戻り値は成否。
	@param	xmlpath			(string)				atomDBTaikan.xmlのフルパス
	@retval					(Result)				処理結果
	@retval					(list)					番号と原子名のリストからなる二重リストリスト
	"""

	print('xmlpath:', xmlpath)
	list = []
	adt = AtomDBTaikanClass()
	adt.ReadDBFile(xmlpath)

	rs = adt.GetAtomNameList(list)

	return rs, list

###############################################################################
# 原子名リストを取得する関数
###############################################################################
def GetIsotopeNameList(atom_info, xmlpath = ""):
	"""
	同位体名リストを取得する(GUI周期表用)
	原子名or原子番号で、getする同位体を指定する。
	戻りはMass順にソートする。
	配列は2次元にして、Massも取得する。
	@param	atom_info		(string)				原子名or原子番号
	@param	xmlpath			(string)				atomDBTaikan.xmlのフルパス
	@retval					(Result)				処理結果
	@retval					(list)					同位体名とMassのリストからなる二重リスト
	"""

	print('xmlpath:', xmlpath)
	list = ['A']
	adt = AtomDBTaikanClass()
	adt.ReadDBFile(xmlpath)

	rs = adt.GetIsotopeNameList(atom_info, list)

	return rs, list

###############################################################################
# テスト用スクリプト
###############################################################################
if __name__=='__main__':
	#
	# 簡単なクラスのテスト
	#
#import fw.common.ParamUtil as PU
#from fw.common.Result import *
#import os, datetime
#from xml.dom.minidom import parse

	# 原子情報ファイル名
	DEF_ATOM_DB_FILE_NAME = '/home/kfukaya/atomDBTaikan.xml'
	list = []
	print('------  unit Test:Start --------')
	ret, list = GetValue('Al', 'Incb', DEF_ATOM_DB_FILE_NAME)
	print('------  unit Test:End --------')
	print('ret:', ret)
	print('list:', list)

	print('------  unit Test:Start --------')
	ret, list = GetAtomNameList(DEF_ATOM_DB_FILE_NAME)
	print('------  unit Test:End --------')
	print('ret:', ret)
	print('list:', list)

	print('------  unit Test:Start --------')
	#ret, list = GetIsotopeNameList('Al', DEF_ATOM_DB_FILE_NAME)
	ret, list = GetIsotopeNameList('Al')
	print('------  unit Test:End --------')
	print('ret:', ret)
	print('list:', list)

