module Eulim::Chemistry
	class Compound

		VALID_COMPOUND_REGEXP = /[A-Z][a-z]{0,2}\d*|\((?:[^()]*(?:\(.*\))?[^()]*)+\)\d*/

		attr_accessor :molecular_mass, :constituents, :formula
		
		def initialize(arg)
			@formula = arg
			@constituents = get_constituents
			@molecular_mass = get_molecular_mass
		end

		private
			def get_molecular_mass
				mass = 0
				@constituents.each do |constituent|
					mass += constituent[:element].atomic_mass * constituent[:atom_count]
				end
				mass
			end

			def get_constituents
				constituents = []
				get_constituent_atoms.each do |symbol, count|
					constituents << {element: Element.get_by_symbol(symbol), atom_count: count}
				end
				constituents
			end

			def get_constituent_atoms formula=@formula, result={}
				constituents = formula.scan VALID_COMPOUND_REGEXP
				constituents.each do |constituent|
					multipler = get_multipler constituent
					if constituent[0] != '(' && multipler == 0
						result[constituent] = result[constituent] ? result[constituent] + 1 : 1
					else
						(multipler == 0 ? 1 : multipler).times do
							sub_constituents = constituent.match(/^\(?(.*?)\)?($|\d*$)/).to_a
							idx = constituent == sub_constituents.first ? 1 : 0
							get_constituent_atoms sub_constituents[idx], result
						end
					end	
				end
				result
			end

			def get_multipler constituent
				multipler = constituent.match(/\d*$/).to_a.first.to_i
			end

	end
end