code: package core.vgdl;
  
  import java.util.Map;
  import java.util.Set;
  import java.util.TreeMap;
  
  /**
   * Created with IntelliJ IDEA.
   * User: Diego
   * Date: 27/10/13
   * Time: 12:22
   * This is a Java port from Tom Schaul's VGDL - https://github.com/schaul/py-vgdl
   */
  public class VGDLRegistry
  {
      /**
       * Singleton instance of this class.
       */
      private static VGDLRegistry registry;
  
      /**
       * Maps strings to int. Strings are VGDL identifiers for SPRITE TYPES,
       * while integers are their unique int identifier counterparts.
       */
      private TreeMap<String, Integer> sprite_mapping;
  
      /**
       * Private constructor.
       */
      private VGDLRegistry(){}
  
      /**
       * Initializes the registry of sprites for games.
       */
      public void init()
      {
          sprite_mapping = new TreeMap<String, Integer>();
      }
  
      /**
       * Returns the unique instance of this class.
       * @return the unique instance of this class.
       */
      public static VGDLRegistry GetInstance()
      {
          if(registry == null)
          {
              registry = new VGDLRegistry();
              registry.init();
          }
          return registry;
      }
  
      /**
       * Register a new sprite string.
       * @param key key in the hashmap.
       * @return Returns its new index, or a new one if it was already registered.
       */
      public int registerSprite(String key)
      {
          int index = getRegisteredSpriteValue(key);
          if(index != -1)
              return index;
  
          //otherwise, insert.
          int numElements = sprite_mapping.size();
          sprite_mapping.put(key, numElements);
          return numElements;
      }
  
      /**
       * Returns the index (value in map) of a given key, for sprites.
       * @param key key to check
       * @return the value in map, -1 if it does not exist.
       */
      public int getRegisteredSpriteValue(String key)
      {
          if(sprite_mapping.containsKey(key))
              return sprite_mapping.get(key);
          return -1;
      }
  
  
      /**
       * Returns an array of indexes (value in map) of a set of keys, for sprites.
       * @param keys list of keys, separated by commas.
       * @return array with values in the map, -1 if it does not exist.
       */
      public int[] explode(String keys)
      {
          if(keys == null)
              return new int[]{-1};
  
          String[] keysArray = keys.split(",");
          int[] intKeys = new int[keysArray.length];
          for(int i = 0; i < keysArray.length; ++i)
              intKeys[i] = getRegisteredSpriteValue(keysArray[i]);
  
          return intKeys;
      }
  
      /**
       * Returns the String associated with the first (and in theory, unique) sprite value passed.
       * This method is for <b>debug purposes only</b>, should not be used for game execution.
       * @param value value whose key is returned.
       * @return the String associated with the value passed.
       */
      public String getRegisteredSpriteKey(int value)
      {
          //This method should not be used.
          //System.out.println("This method is deprecated, should not be used (other than debug).");
          if(sprite_mapping.containsValue(value))
          {
              Set<Map.Entry<String, Integer>> entries = sprite_mapping.entrySet();
              for(Map.Entry<String, Integer> entry : entries)
              {
                  if(entry.getValue() == value)
                      return entry.getKey();
              }
          }
          return null;
      }
  
      /**
       * Returns the -number of elements in the sprite_mapping array.
       * @return number of elements in the sprite_mapping array.
       */
      public int numSpriteTypes()
      {
          return sprite_mapping.size();
      }
  
  }
  