content: /*
  * Copyright (c) 1997 - 2016
  * Actelion Pharmaceuticals Ltd.
  * Gewerbestrasse 16
  * CH-4123 Allschwil, Switzerland
  *
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice, this
  *    list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of the the copyright holder nor the
  *    names of its contributors may be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
  
  package com.actelion.research.chem;
  
  import java.util.Hashtable;
  
  public class PeriodicTable {
  
  	public static final int ConnectionPoint = 0;
  
  	public static final int Hydrogen = 1;
  
  	public static final int Carbon = 6;
  	
  	public static final int Nitrogen = 7;
  	
  	public static final int Oxygen = 8;
  	
  	public static final int Fluorine = 9;
  	
  	public static final int Silicon = 14;
  	
  	public static final int Phosphorus = 15;
  	
  	public static final int Sulfur = 16;
  	
  	public static final int Chlorine = 17;
  	
  	public static final int Bromine = 35;
  	
  	public static final int Iodine = 53;
  	public static final int Uranium = 92;
  
  	
  	
  	private static Element[] arrData;
  
  	private boolean [] arrAlkaline;
  
  	private Hashtable<Integer, Element> htblDataAtNo;
  
  	private Hashtable<String, Element> htblDataName;
  
  	private Hashtable<String, Element> htblDataSymbol;
  
  	private static PeriodicTable tbl;
  
  
  	private PeriodicTable() {
  
  		htblDataAtNo = new Hashtable<>();
  
  		htblDataName = new Hashtable<>();
  
  		htblDataSymbol = new Hashtable<>();
  
  // Order Number, Element Symbol, Atomic Weight, Covalent Radius, VdW radius
      arrData = new Element [] {
  			new Element(1,"Hydrogen","H",1.008,0.435,1.185,2.200),
  			new Element(2,"Helium","He",4.003,0.930,1.785,0.000),
  			new Element(3,"Lithium","Li",6.940,1.520,0.000,0.980),
  			new Element(4,"Beryllium","Be",9.013,1.143,0.000,1.570),
  			new Element(5,"Boron","B",10.820,0.975,1.700,2.040),
  			new Element(6,"Carbon","C",12.011,0.655,1.750,2.550),
  			new Element(7,"Nitrogen","N",14.008,0.750,1.525,3.040),
  			new Element(8,"Oxygen","O",16.000,0.730,1.400,3.440),
  			new Element(9,"Fluorine","F",19.000,0.720,1.350,3.980),
  			new Element(10,"Neon","Ne",20.183,0.710,1.600,0.000),
  			new Element(11,"Sodium","Na",22.991,1.858,0.000,0.930),
  			new Element(12,"Magnesium","Mg",24.320,1.605,0.000,1.310),
  			new Element(13,"Aluminum","Al",26.980,1.432,0.000,1.610),
  			new Element(14,"Silicon","Si",28.090,1.176,2.000,1.900),
  			new Element(15,"Phosphorus","P",30.975,1.060,1.900,2.190),
  			new Element(16,"Sulfur","S",32.066,1.020,1.850,2.580),
  			new Element(17,"Chlorine","Cl",35.457,0.990,1.780,3.160),
  			new Element(18,"Argon","Ar",39.944,0.980,1.900,0.000),
  			new Element(19,"Potassium","K",39.100,2.262,0.000,1.000),
  			new Element(20,"Calcium","Ca",40.080,1.976,0.000,1.360),
  			new Element(21,"Scandium","Sc",44.960,1.655,0.000,1.540),
  			new Element(22,"Titanium","Ti",47.900,1.476,0.000,1.630),
  			new Element(23,"Vanadium","V",50.950,1.309,0.000,1.660),
  			new Element(24,"Chromium","Cr",52.010,1.249,0.000,1.550),
  			new Element(25,"Manganese","Mn",54.940,1.350,0.000,1.830),
  			new Element(26,"Iron","Fe",55.850,1.241,0.000,1.880),
  			new Element(27,"Cobalt","Co",58.940,1.254,0.000,1.910),
  			new Element(28,"Nickel","Ni",58.690,1.246,0.000,1.900),
  			new Element(29,"Copper","Cu",63.540,1.278,0.000,1.650),
  			new Element(30,"Zinc","Zn",65.380,1.333,0.000,1.810),
  			new Element(31,"Gallium","Ga",69.720,1.350,0.000,2.010),
  			new Element(32,"Germanium","Ge",72.600,1.225,0.000,0.000),
  			new Element(33,"Arsenic","As",74.910,1.200,2.100,2.180),
  			new Element(34,"Selenium","Se",78.960,1.160,2.000,2.550),
  			new Element(35,"Bromine","Br",79.916,1.140,1.970,0.000),
  			new Element(36,"Krypton","Kr",83.800,1.120,2.000,2.960),
  			new Element(37,"Rubidium","Rb",85.480,2.470,0.000,0.000),
  			new Element(38,"Strontium","Sr",87.630,2.151,0.000,0.820),
  			new Element(39,"Yttrium","Y",88.920,1.824,0.000,0.950),
  			new Element(40,"Zirconium","Zr",91.220,1.616,0.000,1.220),
  			new Element(41,"Niobium","Nb",92.910,1.432,0.000,1.330),
  			new Element(42,"Molybdenum","Mo",95.950,1.363,0.000,1.600),
  			new Element(43,"Technetium","Tc",99.000,1.367,0.000,2.160),
  			new Element(44,"Ruthenium","Ru",101.100,1.353,0.000,1.900),
  			new Element(45,"Rhodium","Rh",102.910,1.345,0.000,2.200),
  			new Element(46,"Palladium","Pd",106.700,1.375,0.000,2.280),
  			new Element(47,"Silver","Ag",107.880,1.445,0.000,2.200),
  			new Element(48,"Cadmium","Cd",112.410,1.489,0.000,1.930),
  			new Element(49,"Indium","In",114.760,1.666,0.000,1.690),
  			new Element(50,"Tin","Sn",118.700,1.538,0.000,1.780),
  			new Element(51,"Antimony","Sb",121.760,1.400,2.200,1.960),
  			new Element(52,"Tellurium","Te",127.610,1.360,2.200,0.000),
  			new Element(53,"Iodine","I",126.910,1.330,2.200,2.050),
  			new Element(54,"Xenon","Xe",131.300,1.310,2.200,2.100),
  			new Element(55,"Cesium","Cs",132.910,2.632,0.000,2.660),
  			new Element(56,"Barium","Ba",137.360,2.171,0.000,2.600),
  			new Element(57,"Lanthanum","La",138.920,1.873,0.000,0.790),
  			new Element(58,"Cerium","Ce",140.130,1.824,0.000,0.890),
  			new Element(59,"Praesodymium","Pr",140.920,1.836,0.000,1.100),
  			new Element(60,"Neodymium","Nd",144.270,1.829,0.000,1.120),
  			new Element(61,"Promethium","Pm",145.000,1.809,0.000,1.130),
  			new Element(62,"Samarium","Sm",150.430,1.804,0.000,1.140),
  			new Element(63,"Europium","Eu",152.000,1.984,0.000,0.000),
  			new Element(64,"Gadolinium","Gd",156.900,1.818,0.000,1.170),
  			new Element(65,"Terbium","Tb",158.930,1.800,0.000,0.000),
  			new Element(66,"Dyprosium","Dy",162.460,1.795,0.000,1.200),
  			new Element(67,"Holmium","Ho",164.940,1.789,0.000,0.000),
  			new Element(68,"Erbium","Er",167.200,1.779,0.000,1.220),
  			new Element(69,"Thulium","Tm",168.940,1.769,0.000,1.230),
  			new Element(70,"Ytterbium","Yb",173.040,1.940,0.000,1.240),
  			new Element(71,"Lutetium","Lu",174.990,1.752,0.000,1.250),
  			new Element(72,"Hafnium","Hf",178.600,1.597,0.000,0.000),
  			new Element(73,"Tantalium","Ta",180.950,1.428,0.000,1.270),
  			new Element(74,"Wolfram","W",183.920,1.371,0.000,1.300),
  			new Element(75,"Rhenium","Re",186.310,1.380,0.000,1.500),
  			new Element(76,"Osmium","Os",190.200,1.368,0.000,2.360),
  			new Element(77,"Iridium","Ir",192.200,1.357,0.000,1.900),
  			new Element(78,"Platinum","Pt",195.230,1.387,0.000,2.200),
  			new Element(79,"Gold","Au",197.000,1.442,0.000,2.200),
  			new Element(80,"Mercury","Hg",200.610,1.502,0.000,2.280),
  			new Element(81,"Thallium","Tl",204.390,1.728,0.000,2.540),
  			new Element(82,"Lead","Pb",207.210,1.750,0.000,2.000),
  			new Element(83,"Bismuth","Bi",209.000,1.460,0.000,1.620),
  			new Element(84,"Polonium","Po",210.000,1.460,0.000,2.330),
  			new Element(85,"Astatine","At",210.000,1.450,0.000,2.020),
  			new Element(86,"Radon","Rn",222.000,1.430,0.000,2.000),
  			new Element(87,"Francium","Fr",223.000,2.500,0.000,2.200),
  			new Element(88,"Radium","Ra",226.050,2.140,0.000,0.000),
  			new Element(89,"Actinium","Ac",227.000,1.877,0.000,0.700),
  			new Element(90,"Thorium","Th",232.050,1.798,0.000,0.890),
  			new Element(91,"Protactinium","Pa",231.000,1.609,0.000,1.100),
  			new Element(92,"Uranium","U",238.070,1.568,0.000,1.300),
  			new Element(93,"Neptunium","Np",237.000,0.000,0.000,1.500),
  			new Element(94,"Plutonium","Pu",242.000,0.000,0.000,1.380),
  			new Element(95,"Americium","Am",243.000,0.000,0.000,1.360),
  			new Element(96,"Curium","Cm",243.000,0.000,0.000,1.280),
  			new Element(97,"Berkelium","Bk",245.000,0.000,0.000,1.300),
  			new Element(98,"Californium","Cf",246.000,0.000,0.000,1.300),
  			new Element(99,"Einsteinium","E",-999.000,0.000,0.000,1.300),
  			new Element(100,"Fermium","Fm",-999.000,0.000,0.000,1.300),
  			new Element(101,"Mendelevium","Mv",-999.000,0.000,0.000,1.300)
  
      	};
  
  		for (Element arrDatum : arrData) {
  			htblDataAtNo.put(arrDatum.getOrderNumber(), arrDatum);
  			htblDataName.put(arrDatum.getName(), arrDatum);
  			htblDataSymbol.put(arrDatum.getSymbol().toLowerCase(), arrDatum);
  		}
  
  		arrAlkaline = new boolean[arrData.length];
  
      	arrAlkaline[3]=true;
      	arrAlkaline[11]=true;
      	arrAlkaline[19]=true;
      	arrAlkaline[37]=true;
      	arrAlkaline[55]=true;
      	arrAlkaline[87]=true;
  
  	}
  
  	private static PeriodicTable getInstance() {
  		if (tbl == null) {
  			tbl = new PeriodicTable();
  		}
  		return tbl;
  	}
  
  	public static boolean isAlkaline(int atomicNo) {
  		return getInstance().arrAlkaline[atomicNo];
  	}
  
  	/**
  	 * 
  	 * @param sNameOrSymbol
  	 * @return atomic order number or 0 if the input can not be resolved to an element.
  	 */
  	public static int number(String sNameOrSymbol) {
  
  		int iOrderNumber = 0;
  
  		Element el = getInstance().htblDataName.get(sNameOrSymbol);
  		if (el == null)
  			el = getInstance().htblDataSymbol.get(sNameOrSymbol.toLowerCase());
  
  		if (el != null)
  			iOrderNumber = el.getOrderNumber();
  
  		return iOrderNumber;
  	}
  
  	public static String symbol(int iOrderNumber) {
  
  		String sSymbol = "";
  
  		Element el = getInstance().htblDataAtNo.get(iOrderNumber);
  
  		if (el != null)
  			sSymbol = el.getSymbol();
  
  		return sSymbol;
  	}
  
  	public static int size(){
  		return getInstance().htblDataAtNo.size();
  	}
  	
  	/**
  	 * 
  	 * @param iOrderNumber
  	 * @return element weight
  	 */
  	public static double getWeight(int iOrderNumber) {
  
  		Element el = getInstance().htblDataAtNo.get(iOrderNumber);
  
  		return el.getWeight();
  	}
  
  	public static String name(int iOrderNumber) {
  
  		String sName = "";
  
  		Element el = getInstance().htblDataAtNo.get(iOrderNumber);
  
  		if (el != null)
  			sName = el.getName();
  
  		return sName;
  	}
  
  	public static Element getElement(int orderNumber) {
  		return getInstance().htblDataAtNo.get(orderNumber);
  	}
  	
  	public String toString() {
  		String sPeriodicTable = "";
  		return sPeriodicTable;
  	}
  }