gt: 						states.set(row * columns + columns - column - 1, state);
context: /*******************************************************************************
   * Copyright (c) 2013, 2014 UT-Battelle, LLC.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *   Initial API and implementation and/or initial documentation - Jay Jay Billings,
   *   Jordan H. Deyton, Dasha Gorin, Alexander J. McCaskey, Taylor Patterson,
   *   Claire Saunders, Matthew Wang, Anna Wojtowicz
   *******************************************************************************/
  package org.eclipse.ice.client.widgets.reactoreditor.lwr;
  
  import java.util.ArrayList;
  import java.util.BitSet;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import org.eclipse.gef.EditPart;
  import org.eclipse.gef.GraphicalViewer;
  import org.eclipse.ice.client.common.ActionTree;
  import org.eclipse.ice.client.widgets.reactoreditor.AnalysisView;
  import org.eclipse.ice.client.widgets.reactoreditor.DataSource;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.Cell;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.Cell.State;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.Grid;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.GridEditorInput;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.GridEditorTools;
  import org.eclipse.ice.client.widgets.reactoreditor.grid.IGridListener;
  import org.eclipse.ice.client.widgets.reactoreditor.lwr.properties.PropertySourceFactory;
  import org.eclipse.ice.reactor.AssemblyType;
  import org.eclipse.ice.reactor.GridLabelProvider;
  import org.eclipse.ice.reactor.LWRComponent;
  import org.eclipse.ice.reactor.pwr.PWRAssembly;
  import org.eclipse.ice.reactor.pwr.PressurizedWaterReactor;
  import org.eclipse.jface.action.Action;
  import org.eclipse.jface.viewers.StructuredSelection;
  import org.eclipse.swt.layout.FillLayout;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.ui.views.properties.IPropertySource;
  
  /**
   * This class provides an IAnalysisView geared toward an
   * {@link PressurizedWaterReactor} core. It displays a grid of hexagons, each of
   * which represents a location for a particular {@link AssemblyType type} of
   * {@link PWRAssembly}.<br>
   * <br>
   * When an assembly of the current type is selected, this View should update the
   * StateBroker with the current selection. It should also feed the properties of
   * the last clicked assembly or the core itself to the ICE Properties View via
   * {@link AnalysisView#selectionProvider}.
   * 
   * @author Jordan H. Deyton
   * 
   */
  public class CoreAnalysisView extends AnalysisView implements IGridListener {
  
  	/**
  	 * The name for this type of analysis view. This can be used for the display
  	 * text of SWT widgets that reference this view.
  	 */
  	protected static final String name = "Core";
  	/**
  	 * A brief description of this type of analysis view. This can be used for
  	 * ToolTips for SWT widgets referencing this view.
  	 */
  	protected static final String description = "A view of a light water reactor core.";
  
  	/* ----- GUI Components ----- */
  	/**
  	 * The grid model for the reactor core.
  	 */
  	private Grid grid;
  	/**
  	 * The GraphicalViewer used to display the grid for the reactor core.
  	 */
  	private GraphicalViewer viewer;
  	/**
  	 * The ActionTree that lets the user select the core to display its
  	 * properties.
  	 */
  	private final ActionTree coreProperties;
  	/* -------------------------- */
  
  	/* ---- Current State ---- */
  	/**
  	 * The current LWReactor displayed in the View.
  	 */
  	private PressurizedWaterReactor reactor;
  	/**
  	 * The current type of assemblies displayed in the Core View.
  	 */
  	private AssemblyType assemblyType;
  	/**
  	 * A Map of BitSets for each assembly type. The bits in the Sets correspond
  	 * to the indexes in the grid. A set bit means there is an assembly of that
  	 * type in that location.
  	 */
  	private final Map<AssemblyType, BitSet> assemblyLocations;
  	/**
  	 * A Map of currently-selected assemblies keyed on the assembly type.
  	 */
  	private final Map<AssemblyType, LWRComponentInfo> selectedAssemblies;
  
  	/* ----------------------- */
  
  	/**
  	 * The default constructor.
  	 * 
  	 * @param dataSource
  	 *            The data source associated with this view (input, reference,
  	 *            comparison).
  	 */
  	public CoreAnalysisView(DataSource dataSource) {
  		super(dataSource);
  
  		// Initialize any final variables here.
  		AssemblyType[] values = AssemblyType.values();
  		selectedAssemblies = new HashMap<AssemblyType, LWRComponentInfo>(
  				values.length);
  		assemblyLocations = new HashMap<AssemblyType, BitSet>(values.length);
  
  		// Default to show fuel assemblies.
  		assemblyType = AssemblyType.Fuel;
  
  		// Populate the list of actions (for ToolBar and context Menu).
  
  		// Add an ActionTree for the AssemblyTypes.
  		ActionTree assemblyTypes = new ActionTree("Assembly Type");
  		actions.add(assemblyTypes);
  		for (final AssemblyType assemblyType : values) {
  			Action action = new Action(assemblyType.toString()) {
  				@Override
  				public void run() {
  					setAssemblyType(assemblyType);
  				}
  			};
  			assemblyTypes.add(new ActionTree(action));
  		}
  
  		// Add an ActionTree (single button) for viewing the core's properties.
  		coreProperties = new ActionTree(new Action("Core Properties") {
  			@Override
  			public void run() {
  				// If the reactor is set, get is properties.
  				IPropertySource properties = new PropertySourceFactory()
  						.getPropertySource(reactor);
  
  				// If it has properties, set the properties in the ICE
  				// Properties View.
  				if (properties != null) {
  					selectionProvider.setSelection(new StructuredSelection(
  							properties));
  				}
  			}
  		});
  		actions.add(coreProperties);
  		// Disable the core properties button by default.
  		coreProperties.setEnabled(false);
  
  		// Add an ActionTree (single button) for saving the viewer image.
  		ActionTree saveImage = new ActionTree(new Action("Save Image") {
  			@Override
  			public void run() {
  				saveViewerImage(viewer);
  			}
  		});
  		actions.add(saveImage);
  
  		return;
  	}
  
  	/**
  	 * This method compares the passed in reactor with the currently-selected
  	 * reactor. If the two reactors are the same instance and share the same
  	 * assemblies among the currently-selected assemblies of each type, then
  	 * this method returns false. It also returns false if the new reactor is
  	 * null.
  	 * 
  	 * @param newReactor
  	 *            The new reactor to compare against the currently-selected one.
  	 * @return True if the current reactor should be changed to the new one,
  	 *         false otherwise.
  	 */
  	private boolean reactorChanged(PressurizedWaterReactor newReactor) {
  
  		boolean changed = false;
  
  		// We can't compare with a null reactor.
  		if (newReactor != null) {
  			if (newReactor == reactor) {
  
  				// If we have no selected assemblies, then assume the reactor is
  				// new.
  				if (selectedAssemblies.isEmpty()) {
  					changed = true;
  				}
  
  				// If we have selected assemblies, see if they are the same as
  				// the corresponding assemblies in the new reactor.
  				for (AssemblyType type : AssemblyType.values()) {
  					// Get the currently selected assembly of this type.
  					LWRComponentInfo info = selectedAssemblies.get(type);
  					if (info != null) {
  						// Get the corresponding assembly in the new reactor.
  						LWRComponent assembly = reactor.getAssemblyByLocation(
  								type, info.row, info.column);
  						// Compare the two assemblies and break if necessary.
  						if (assembly != info.lwrComponent) {
  							changed = true;
  							break;
  						}
  					}
  				}
  
  			} else {
  				// In some cases, the reactor actually is a different instance.
  				// This happens when a new type of reactor is loaded, since the
  				// new reactor cannot copy itself into the old one.
  				changed = true;
  			}
  		}
  
  		return changed;
  	}
  
  	/**
  	 * Sets the current reactor displayed in the CoreAnalysisView.
  	 * 
  	 * @param newReactor
  	 *            The new LWReactor to display.
  	 */
  	private void setReactor(PressurizedWaterReactor newReactor) {
  
  		// Don't try to reload anything unless the reactor is significantly
  		// enough different to warrant a change. We isolate this functionality
  		// because the typical procedure is to copy the data from a new
  		// IReactorComponent into the existing one known to this AnalysisView.
  		if (reactorChanged(newReactor)) {
  			// Reset the Map of selected assemblies here (because it is used to
  			// compare reactors).
  			selectedAssemblies.clear();
  
  			// Store the reference to the new reactor.
  			reactor = newReactor;
  
  			// Enable the core properties button.
  			coreProperties.setEnabled(true);
  
  			// Get the size of the reactor.
  			int size = reactor.getSize();
  			int rows = size;
  			int columns = size;
  			int totalSize = rows * columns;
  
  			/* ---- Build a new basic LWR core view. ---- */
  			// Re-initialize the List of states and set everything to be
  			// DISABLED.
  			List<Cell.State> states = new ArrayList<Cell.State>(totalSize);
  			for (int i = 0; i < totalSize; i++) {
  				states.add(Cell.State.DISABLED);
  			}
  
  			// If possible, set the corners of the reactor to be INVALID.
  			// Invalid states do not produce a Figure on the grid. This is
  			// specific to reactors of size 15.
  			if (rows == 15 && columns == 15) {
  				Cell.State state = Cell.State.INVALID;
  				int[] rowList = { 0, 1, 2, 3 };
  				int[] columnList = { 4, 2, 1, 1 };
  				for (int i = 0; i < rowList.length; i++) {
  					for (int column = 0; column < columnList[i]; column++) {
  						int row = rowList[i];
  						states.set(row * columns + column, state);
  