package util.input; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.ResourceBundle; /** * ResourceContainer makes it easy to work with resource files. * @author Aaron Krolik, Gavin Ovsak * */ public class ResourceMappingObject { private final String myName; private String myPath; private ResourceBundle myPersistentResources; private Map<String, String> resourceMapping; private ArrayList<WebButton> interpretedButtons = new ArrayList<WebButton>(); /** * Constructs an object which manages a dynamic behavior mapping. * @param name */ public ResourceMappingObject(String name){ myName = name; } /** * Overflow constructor for immediately supplying the mapping resource path * @param name * @param path */ public ResourceMappingObject(String name, String path){ this(name); setResourcePath(path); } /** * Called when behavior mapping has been modified, goes through the resource * mapping and creates a button for each game behavior except for behaviors * which are called by Ups and Downs of the same device button. Used for * intuitively generating web buttons. */ public void interpretButtons() { interpretedButtons.clear(); WebButton newButtonBehaviors = new WebButton(); boolean stillNeedsToBeSet = true; for(String inputBehavior : resourceMapping.keySet()) { newButtonBehaviors = new WebButton(); stillNeedsToBeSet = true; boolean isUp = inputBehavior.substring(inputBehavior.length()-2, inputBehavior.length()).equals("Up"); boolean isDown = inputBehavior.substring(inputBehavior.length()-4, inputBehavior.length()).equals("Down"); if(isUp || isDown){ String conjugateCommand = isUp?inputBehavior.substring(0, inputBehavior.length()-2)+"Down" :inputBehavior.substring(0, inputBehavior.length()-4)+"Up"; for(WebButton button : interpretedButtons) { if(button.getDownBehavior().length() == 0 && isDown && button.getUpInputBehaviors().contains(conjugateCommand)) { button.setDownBehavior(resourceMapping.get(inputBehavior)); button.setDownInputBehaviors(inputBehavior); stillNeedsToBeSet = false; } if(button.getUpBehavior().length() == 0 && isUp && button.getDownInputBehaviors().contains(conjugateCommand)) { button.setUpBehavior(resourceMapping.get(inputBehavior)); button.setUpInputBehaviors(inputBehavior); stillNeedsToBeSet = false; } } if(stillNeedsToBeSet && isUp) { newButtonBehaviors.setUpBehavior(resourceMapping.get(inputBehavior)); newButtonBehaviors.setUpInputBehaviors(newButtonBehaviors.getUpInputBehaviors()+inputBehavior); interpretedButtons.add(newButtonBehaviors); } } else{ newButtonBehaviors.setDownBehavior(resourceMapping.get(inputBehavior)); newButtonBehaviors.setDownInputBehaviors(newButtonBehaviors.getDownInputBehaviors()+inputBehavior); interpretedButtons.add(newButtonBehaviors); } } } /** * returns a list of interpretted buttons for use on a web UI * @return */ @SuppressWarnings("unchecked") public ArrayList<WebButton> getWebButtons() { return (ArrayList<WebButton>) interpretedButtons.clone(); } /** * * @param path */ public void setResourcePath(String path){ myPath = path; resourceMapping = convertResourceBundleToMap( (myPersistentResources = ResourceBundle.getBundle(path)) ); interpretButtons(); //DEBUGprintMap(resourceMapping); } /** * Returns the name of this MappingObject * @return */ public String getName(){ return myName; } /** * Returns the String of last current resource path given. * @return */ public String getCurrentPath(){ return myPath; } /** * get corresponding value from our resource map given a key * @param key * @return value * * TODO handle invalid keys. maybe throw exception */ public String getGameBehavior(String inputBehavior) { return resourceMapping.get(inputBehavior); } /** * Returns a true value if the given inputBehavior is currently mapped to a game behavior, false if not. * @param inputBehavior * @return */ public boolean containsInputBehavior(String inputBehavior){ return resourceMapping.containsKey(inputBehavior); } /** * Sets mappings to those found in the current resource file. */ public void restoreDefault(){ resourceMapping.clear(); resourceMapping = convertResourceBundleToMap(myPersistentResources); interpretButtons(); } /** * Override the mappings in your current resource file. **watch out! will remove your current mappings** * @param gameBehavior * @param inputBehavior */ public void overrideMapping(String gameBehavior, String inputBehaviors) { Iterator<Map.Entry<String, String>> iter = resourceMapping.entrySet().iterator(); while (iter.hasNext()) { Map.Entry<String, String> KV = iter.next(); if ( KV.getValue().equals(gameBehavior) || KV.getKey().equals(gameBehavior)){ iter.remove(); } } for (String inputBehavior : parseStr(inputBehaviors)) resourceMapping.put(inputBehavior, gameBehavior); interpretButtons(); } /** * writes your current mappings to a file specified by path. if it does not exist, we'll make it. * @param path to file you want. doesn't need to exist * TODO figure out exception handling */ public void saveMappingsToFile(String path){ Map<String, String> temp = new HashMap<String, String>(); Iterator<Map.Entry<String, String>> iter = resourceMapping.entrySet().iterator(); Map.Entry<String, String> entry; while (iter.hasNext()){ entry = iter.next(); if (temp.containsKey(entry.getValue())){ temp.put( entry.getValue(), temp.get(entry.getValue()).concat("|" + entry.getKey() ) ); } else { temp.put(entry.getValue(), entry.getKey()); } } try { PrintWriter out = new PrintWriter(new File(path)); for (Map.Entry<String,String> ent : temp.entrySet()) { out.println(ent.getKey() + "\t=\t" + ent.getValue()); } out.close(); } catch (FileNotFoundException e) { } } /** * Parse string as coming in form resource file. Supports legacy formatting. * @param resource * @return */ protected Map<String, String> convertResourceBundleToMap(ResourceBundle resource) { Map<String, String> map = new HashMap<String, String>(); Enumeration<String> keys = resource.getKeys(); while (keys.hasMoreElements()) { String gameBehavior = keys.nextElement(); if (resource.getString(gameBehavior).contains("_")) { for (String inputBehavior : parseStr(resource.getString(gameBehavior))) { map.put(inputBehavior, gameBehavior); } } else { String oldInputBehavior = gameBehavior; String oldGameBehavior = resource.getString(oldInputBehavior); map.put(oldInputBehavior, oldGameBehavior);//Legacy support for flipped resource files } } return map; } /** * Breaks up a list of inputBehaviors separated by "or" pipes * @param in * @return parsed string */ protected String[] parseStr(String in){ return in.split("\\|"); } private void DEBUGprintMap(Map<String, String> map){ Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); String value = map.get(key); System.out.println(key + " = " + value); } System.out.println("---"); } }