Package ch.sahits.game.graphic.image.impl

Source Code of ch.sahits.game.graphic.image.impl.LanguageImageLoader

package ch.sahits.game.graphic.image.impl;

import java.awt.Polygon;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

import ch.sahits.game.graphic.image.ILanguageAwareImageLoader;
import ch.sahits.game.graphic.image.NamedBufferedImage;

/**
* This imageLoader augments the {@link ImagesLoader} by the
* ability to load images based on a language.
*  * <br/>
* ImagesFile Formats:<br/>
*
* <pre>
*     o &lt;fnm&gt;                     // a single image file
*    
*     l &lt;fnm*.ext&gt; {&lt;coords&gt;}        // a single language specific file
*
*     n &lt;fnm*.ext&gt; &lt;number&gt;       // a series of numbered image files, whose
*                                 // filenames use the numbers 0 - &lt;number&gt;-1
*
*     s &lt;fnm&gt; &lt;number&gt;            // a strip file (fnm) containing a single row
*                                 // of &lt;number&gt; images
*
*     g &lt;name&gt; &lt;fnm&gt; [ &lt;fnm&gt; ]*   // a group of files with different names;
*                                 // they are accessible via 
*                                 // &lt;name&gt; and position _or_ &lt;fnm&gt; prefix
*      
*     L &lt;fnm*.ext&gt;         // load all matching files for a language
* </pre>
*
* and blank lines and comment lines.<br/>
* <br/>
* The language specific files are looked up by replacing the the wildcard with the local string and
* then loading the image. If the image cannot be found the default image (without local extension) will
* be loaded.<br/>
* If the local is 'de_CH' and the filename specified is 'screenshot*.png' then the following files are
* tried to load:
* <ul>
* <li>screenshot_de_CH.png</li>
* <li>screenshot_de.png</li>
* <li>screenshot.png</li>
* </ul>
* The first file that can be loaded will be returned.<br/>
* The file name is followed by an optional list of points defining a polygon that can be used as a
* map for the image. The coordinates are entered in the form x-y. Multiple coordinates are separated
* by a space.
* <br/>
* The numbered image files (n) can be accessed by the &lt;fnm&gt; prefix and
* &lt;number&gt;. <br/>
* <br/>
* The strip file images can be accessed by the <fnm> prefix and their position
* inside the file (which is assumed to hold a single row of images).<br/>
* <br/>
* The images in group files can be accessed by the 'g' &lt;name&gt; and the
* &lt;fnm&gt; prefix of the particular file, or its position in the group.<br/>
* <br/>
* <br/>
* The images are stored as BufferedImage objects, so they will be manipulated
* as 'managed' images by the JVM (when possible).
* @author Andi Hotz, (c) Sahits GmbH, 2011
* Created on Feb 26, 2011
*
*/
public class LanguageImageLoader extends ImagesLoader implements ILanguageAwareImageLoader{
  private final static Logger logger = Logger.getLogger(LanguageImageLoader.class);
  private static final String EMPTY = "";
 
  private  final Locale locale;
 
  // TODO the polygon coordinate should be defined in a separate file since they are language specific ImageData
  private HashMap<String,Polygon> polyMap = new HashMap<String,Polygon>();
  private HashMap<String,List<NamedBufferedImage>> localImageMap = new HashMap<String, List<NamedBufferedImage>>();
 
 
  public LanguageImageLoader(String fnm, Locale locale) {
    initLoader();
    this.locale=locale;
    loadImagesFile(fnm);
  }


  /**
   * Parse the definition file and load the corresponding images
   * @param br
   * @throws IOException
   */
  protected void parseImageDefinitionsAndLoad(BufferedReader br)
      throws IOException {
    String line;
    char ch;
    while ((line = br.readLine()) != null) {
      if (line.length() == 0) // blank line
        continue;
      if (line.startsWith("//")) // comment
        continue;
      ch = line.charAt(0);
      if (ch == 'o') // a single image
        getFileNameImage(line);
      else if (ch == 'l') // a local image
        getLocalFileNameImage(line);
      else if (ch == 'n') // a numbered sequence of images
        getNumberedImages(line);
      else if (ch == 's') // an images strip
        getStripImages(line);
      else if (ch == 'g') // a group of images
        getGroupImages(line);
      else if (ch == 'L') // Lanuguage group
        getLanguageGroupImages(line);
      else
        logger.warn("Do not recognize line: " + line);
    }
  }

  /**
   * Loading the image group with the language specification
   * @param line
   */
  private void getLanguageGroupImages(String line) {
    String[] locales = getLocals();
    StringTokenizer tokens = new StringTokenizer(line);
    if (tokens.countTokens()==2){
      tokens.nextToken(); // skip command label
      System.out.print("L Line: ");
      String filePrototype = tokens.nextToken();
      String head = filePrototype.substring(0, filePrototype.indexOf('*'));
      String tail = filePrototype.substring(filePrototype.indexOf('*')+1);
      for (int i = 0; i < locales.length; i++) {
        String fname = head+"*"+locales[i]+tail;
        String[] fnames = getAvailableFilenames(fname);
        Arrays.sort(fnames);
        if (fnames.length>0){
          ArrayList<NamedBufferedImage> images = new ArrayList<NamedBufferedImage>();
          for (int j = 0; j < fnames.length; j++) {
            String name = head+j;
            BufferedImage img = loadImage(fnames[j]);
            logger.debug("  Stored " + name + "/" + fnames[j]);

            images.add(new NamedBufferedImage(img, name));
          }
          localImageMap.put(head, images);
          break;
        }
      }
    }
  }
  /* (non-Javadoc)
   * @see ch.sahits.game.graphic.image.impl.ILanguageAwareImageLoader#getLocalImageGroup(java.lang.String, int)
   */
  @Override
  public BufferedImage getLocalImageGroup(String groupName,int index){
    List<NamedBufferedImage> img =localImageMap.get(groupName);
    if (img!=null && img.size()>=index){
      return img.get(index).getImage();
    } else {
      return null;
    }
  }
  @Override
  public int getLocalImageGroupeSize(String groupName){
    List<NamedBufferedImage> img =localImageMap.get(groupName);
    if (img!=null){
      return img.size();
    } else {
      return 0;
    }
   
  }

  /**
   * Retrieve the list of locales filename parts that are to be checked. The parts are ordered.
   * @return
   */
  private String[] getLocals() {
    String lang_country = locale.toString();
    String localReplacement;
    if (lang_country.startsWith("_")) {// no language defined
      localReplacement=EMPTY;
    }else if (lang_country.indexOf("__")>0) {// no country
        localReplacement=lang_country.substring(0,lang_country.indexOf("__"));
    } else if (lang_country.indexOf('_')!=lang_country.lastIndexOf('_')){ // with variant
      localReplacement=lang_country.substring(0,lang_country.lastIndexOf('_'));
    } else if (lang_country.indexOf('_')==lang_country.lastIndexOf('_') && lang_country.indexOf('_')!=-1){
      String[] parts = lang_country.split("_");
     
      localReplacement=parts[0]+"_"+parts[1].toUpperCase();
    } else if (lang_country.length()>0&& lang_country.indexOf('_')==-1){ // only country
      localReplacement=lang_country;
    }else {
      localReplacement=EMPTY;
    }
    if (localReplacement.equals(EMPTY)){
      return new String[]{EMPTY};
    } else if (localReplacement.indexOf('_')>0){
      return new String[]{localReplacement,localReplacement.substring(0,localReplacement.indexOf('_')),EMPTY};
    } else {
      return new String[]{localReplacement,EMPTY};
    }
  }


  protected final void getLocalFileNameImage(String line) {
    StringTokenizer tokens = new StringTokenizer(line);

    String storeName=null;
    if (tokens.countTokens() < 2)
      logger.warn("Wrong no. of arguments for " + line);
    else {
      tokens.nextToken(); // skip command label
      StringBuilder sb = new StringBuilder();
      sb.append("l Line: ");
      String filePrototype = tokens.nextToken();
      String fileName;
      if (filePrototype.indexOf('*')>0){
        fileName = filePrototype.substring(0, filePrototype.indexOf('*'));
      } else {
        fileName = filePrototype.substring(0, filePrototype.lastIndexOf('.'));
      }
      if (fileName.indexOf('.')>0){
        fileName=fileName.substring(0, fileName.indexOf('.'));
      }
      String ext = filePrototype.substring(filePrototype.indexOf('.'));
      String lang_country = locale.toString();
      String localReplacement;
      if (lang_country.startsWith("_")) {// no language defined
        localReplacement=EMPTY;
      }else if (lang_country.indexOf("__")>0) {// no country
          localReplacement=lang_country.substring(0,lang_country.indexOf("__"));
      } else if (lang_country.indexOf('_')!=lang_country.lastIndexOf('_')){ // with variant
        localReplacement=lang_country.substring(0,lang_country.lastIndexOf('_'));
      } else if (lang_country.indexOf('_')==lang_country.lastIndexOf('_') && lang_country.indexOf('_')!=-1){
        String[] parts = lang_country.split("_");
       
        localReplacement=parts[0]+"_"+parts[1].toUpperCase();
      } else if (lang_country.length()>0&& lang_country.indexOf('_')==-1){ // only country
        localReplacement=lang_country;
      }else {
        localReplacement=EMPTY;
      }
      if (localReplacement.indexOf("_")>0){ // try loading language_country
        String tmp = fileName+"_"+localReplacement+ext;
        if (isAvailable(tmp)){
          storeName=loadSingleLanguageImage(tmp,"_"+localReplacement,ext);
        } else {
          localReplacement=localReplacement.substring(0, localReplacement.indexOf('_'));
        }
      }
      if (!localReplacement.equals(EMPTY) && storeName==null){ // try load language
        String tmp = fileName+"_"+localReplacement+ext;
        if (isAvailable(tmp)){
          storeName=loadSingleLanguageImage(tmp,"_"+localReplacement,ext);
        } else {
          localReplacement=EMPTY;
        }
      }
      if (localReplacement.equals(EMPTY) && storeName==null){ // load default
        String tmp = fileName+ext;
        storeName=loadSingleLanguageImage(tmp,"",ext);
      }
      if (tokens.countTokens()==1){
        String definitionFile = tokens.nextToken();
        String polyfile = definitionFile.substring(0,definitionFile.indexOf("."))+"_"+localReplacement+definitionFile.substring(definitionFile.indexOf("."));
        loadPolygonData(storeName,polyfile);
      }
    }
//    if (tokens.countTokens()>2){
//      // There are coordinates of a polygon
//      Polygon poly = new Polygon();
//      while (tokens.hasMoreTokens()){
//        String coords = tokens.nextToken();
//        String[] parts = coords.split("-");
//        poly.addPoint(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
//      }
//      polyMap.put(storeName, poly);
//    }
  }
  private void loadPolygonData(String storeName, String polyfile) {
    String imsFNm = IMAGE_DIR + polyfile;
    logger.info("Reading file: " + imsFNm);
    try {
      InputStream in = this.getClass().getResourceAsStream(imsFNm);
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      // BufferedReader br = new BufferedReader( new FileReader(imsFNm));
      String line;
      while ((line = br.readLine()) != null) {
        if (line.length() == 0) // blank line
          continue;
        if (line.startsWith("//")) // comment
          continue;
        if (line.trim().startsWith(storeName)){
          StringTokenizer tokens = new StringTokenizer(line.trim());
          if (tokens.countTokens()<4){
            logger.warn("Wrong no. of arguments for " + line);
          } else {
            tokens.nextToken(); // skip name
            Polygon poly = new Polygon();
            while (tokens.hasMoreTokens()){
              String coords = tokens.nextToken();
              String[] parts = coords.split("-");
              poly.addPoint(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]));
            }
            polyMap.put(storeName, poly);
          }
        } else {
          continue;
        }

      }
      br.close();
    } catch (IOException e) {
      logger.fatal("Error reading file: " + imsFNm, e);
      System.exit(1);
    }
  }


  /**
   * Check if the image file has a polygon defined.
   * @param fnm filename under which the image is stored
   * @return
   */
  public boolean hasPolygonDefined(String fnm){
    return polyMap.containsKey(fnm);
  }
  /**
   * Retrieve the ploygon for the image file.
   * If no polygon is defined for the image null
   * is returned
   * @param fnm filename under which the image is stored
   * @return
   */
  public Polygon getPolygon(String fnm){
    return polyMap.get(fnm);
  }

/**
* Load a language file
* @param fnm complete filename
* @param loc Locale part
* @param ext file extension
* @return Base name of the file, if it can be loaded else null
*/
  private String loadSingleLanguageImage(String fnm,String loc,String ext) {
    String name = getPrefix(fnm,loc,ext);

    if (imagesMap.containsKey(name)) {
      logger.warn("Error: " + name + "already used");
      return null;
    }

    BufferedImage bi = loadImage(fnm);
    if (bi != null) {
      ArrayList<BufferedImage> imsList = new ArrayList<BufferedImage>();
      imsList.add(bi);
      imagesMap.put(name, imsList);
      logger.debug("  Stored " + name + "/" + fnm);
      return name;
    } else
      return null;
    }


  private String getPrefix(String fnm, String loc, String ext) {
    if (loc.equals(EMPTY)){
      return fnm.substring(0, fnm.indexOf(ext));
    } else {
      return fnm.substring(0, fnm.lastIndexOf(loc));
    }
  }
}
TOP

Related Classes of ch.sahits.game.graphic.image.impl.LanguageImageLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.