gt:         Obj o = squares.get(p);
context: /*
   * Copyright (C) 2015 Matthew Seal
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version 2
   * of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   */
  package org.mseal.chess;
  
  import com.jme3.asset.AssetManager;
  import com.jme3.material.Material;
  import com.jme3.math.ColorRGBA;
  import com.jme3.math.FastMath;
  import com.jme3.math.Vector3f;
  import com.jme3.renderer.queue.RenderQueue;
  import com.jme3.scene.Geometry;
  import com.jme3.scene.Node;
  import com.jme3.scene.Spatial;
  import java.util.HashMap;
  import java.util.Map;
  import jme3tools.optimize.GeometryBatchFactory;
  import org.mseal.chess.logic.Point;
  import org.mseal.jme3.states.SmoothMoveAppState;
  import org.mseal.jme3.tools.VectorTools;
  
  /**
   *
   * @author Matthew Seal
   */
  public final class SquareGrid {
  
      private static final class Obj {
  
          Spatial obj = null;
          Vector3f position;
          boolean selected = false;
          Spatial indicator = null;
          Spatial move;
          boolean changed = true;
      }
      private final Map<Point, Obj> squares = new HashMap<Point, Obj>();
      private Spatial sp_indicator;
      protected Spatial sp_pointer;
      private Spatial sp_indicator_gr, sp_indicator_red;
      protected Node pointNode;
      protected final Point currentPointer = new Point(0, 0);
      private Node rootNode;
      private ChessApplication app;
  
      public SquareGrid() {
      }
  
      public void load(AssetManager assetManager, Node rootNode) {
          this.rootNode = rootNode;
  
          sp_indicator = assetManager.loadModel("Models/indicator.j3o");
          sp_pointer = assetManager.loadModel("Models/pointer.j3o");
  
          pointNode = new Node("pointer node");
          pointNode.attachChild(sp_pointer);
  
          sp_indicator_gr = assetManager.loadModel("Models/indicator-green.j3o");
          sp_indicator_gr.setUserData("color", "green");
          sp_indicator_red = assetManager.loadModel("Models/indicator-red.j3o");
          sp_indicator_red.setUserData("color", "red");
  
          this.rootNode.attachChild(pointNode);
  
          Node sqNode = new Node("Squares node");
          createSquares(assetManager, sqNode);
  
          Spatial sq = GeometryBatchFactory.optimize(sqNode);
          rootNode.attachChild(sq);
      }
  
      private void createSquares(AssetManager assetManager, Node node) {
          Spatial sp = assetManager.loadModel("Models/square.j3o");
          Spatial sp_off = assetManager.loadModel("Models/square-off.j3o");
  
          sp.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
          sp_off.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
  
          for (int x = 0; x < 14; x++) {
              for (int y = 0; y < 14; y++) {
                  boolean off = (x < 3 || x >= 11) && (y < 3 || y >= 11);
  
                  Spatial sq = off ? sp_off.clone() : sp.clone();
  
                  if (!off) {
                      setSquareType(sq, (x + y) % 2 == 0);
                  } else {
                      offSquare(sq);
                  }
  
                  float fx = x * ModelSizes.square.x;
                  float fz = y * ModelSizes.square.z;
                  float fy = 0f;
  
                  sq.setLocalTranslation(fx, fy, fz);
                  node.attachChild(sq);
  
                  Point p = new Point(x, y);
  
                  Obj o = new Obj();
                  o.obj = sq;
                  o.position = new Vector3f(fx, fy, fz);
                  //o.indicator = sp_indicator.clone();
                  squares.put(p, o);
              }
          }
      }
  
      void setSquareType(Spatial square, boolean dark) {
          Node n = (Node) square;
          Geometry geom = (Geometry) ((Node) n.getChild("Plane")).getChild("Plane1");
          Material mat = geom.getMaterial();
          if (dark) {
              mat.setColor("Diffuse", ColorRGBA.DarkGray);
          } else {
              mat.setColor("Diffuse", ColorRGBA.White);
          }
          geom.setMaterial(mat);
      }
  
      void offSquare(Spatial square) {
          Node n = (Node) square;
          Geometry geom = (Geometry) ((Node) n.getChild("Cube")).getChild("Cube.0011");
          Material mat = geom.getMaterial();
          mat.setColor("Diffuse", ColorRGBA.LightGray);
          geom.setMaterial(mat);
      }
  
      public Spatial getSquareAt(int x, int y) {
          if (x >= 14 || x < 0 || y >= 14 || y < 0) {
              throw new ArrayIndexOutOfBoundsException("x/y out of range!");
          }
          Point p = new Point(x, y);
          return squares.get(p).obj;
      }
  
      public Vector3f getSquarePos(int x, int y) {
          if (x == -1 && y == -1) {
              return new Vector3f(0, 0, 0);
          }
          if (x >= 14 || x < 0 || y >= 14 || y < 0) {
              throw new ArrayIndexOutOfBoundsException("x/y out of range! " + x + " " + y);
          }
          Point p = new Point(x, y);
          return squares.get(p).position.clone();
      }
  
      public Vector3f getSquarePos(Point p) {
          if (p.x == -1 && p.y == -1) {
              return new Vector3f(0, 0, 0);
          }
          if (p.x >= 14 || p.x < 0 || p.y >= 14 || p.y < 0) {
              throw new ArrayIndexOutOfBoundsException("x/y out of range! "
                      + p.x + " " + p.y);
          }
          return squares.get(p).position.clone();
      }
  
      public Point getSquarePos(Vector3f vector, float range) {
          Point store = new Point(0, 0);
          for (int x = 0; x < 14; x++) {
              for (int y = 0; y < 14; y++) {
                  store.set(x, y);
                  if (VectorTools.isInRange(getSquarePos(store), vector,
                          range)) {
                      return new Point(x, y);
                  }
              }
          }
          return null;
      }
  
      public void setSquareSelected(int x, int y, boolean selected) {
          Point p = new Point(x, y);
          Obj o = squares.get(p);
          if (o == null && selected) {
              o = new Obj();
              o.indicator = sp_indicator.clone();
              squares.put(p, o);
              o.selected = selected;
          }
          if (o != null) {
              o.selected = selected;
              o.changed = true;
          }
      }
  
      public void setPointerLocation(int x, int y) {
          setSquareSelected(currentPointer.x, currentPointer.y, false);
  
          currentPointer.x = x;
          currentPointer.y = y;
          setSquareSelected(currentPointer.x, currentPointer.y, true);
          pointNodeChanged = true;
      }
  
      public Point getPointerLocation() {
          return currentPointer;
      }
  
      public Vector3f getPointerTranslation() {
          return getSquarePos(currentPointer.x, currentPointer.x);
      }
  
      public boolean squareIsSelected(int x, int y) {
          Point p = new Point(x, y);
          return squareSelected(p);
      }
  
      public boolean squareSelected(Point p) {
  