package de.lighti.components.map;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.jfree.data.xy.XYSeries;
import de.lighti.io.ChartCreator;
import de.lighti.model.AppState;
import de.lighti.model.Statics;
import de.lighti.model.game.Ability;
import de.lighti.model.game.Dota2Item;
import de.lighti.model.game.Hero;
import de.lighti.model.game.Player;
public class MapComponent extends JSplitPane {
/**
*
*/
private static final long serialVersionUID = 1045770296903996356L;
private final AppState appState;
private JTree attributeTree;
public final static String CAT_MOVEMENT = Statics.MOVEMENT;
public final static String CAT_DEATHS = Statics.DEATHS;
public final static String CAT_ZONES = Statics.ZONES;
public final static String CAT_ABILITIES = Statics.ABILITIES;
public final static String CAT_ITEMS = Statics.ITEMS;
private MapCanvasComponent mapCanvas;
private OptionContainer optionContainer;
private JPanel mapCanvasContainer;
private final static Logger LOGGER = Logger.getLogger( MapCanvasComponent.class.getName() );
public MapComponent( AppState state ) {
appState = state;
setOrientation( JSplitPane.HORIZONTAL_SPLIT );
setRightComponent( getMapCanvansContainer() );
setLeftComponent( new JScrollPane( getAttributeTree() ) );
setResizeWeight( 1.0 );
setOneTouchExpandable( false );
setDividerSize( 0 );
setDividerLocation( 250 );
setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
}
public void buildTreeNodes( Iterable<Player> players ) {
//Movement
final DefaultMutableTreeNode movement = new DefaultMutableTreeNode( CAT_MOVEMENT );
for (final Player p : players) {
movement.add( new DefaultMutableTreeNode( p.getName() ) );
}
//Deaths
final DefaultMutableTreeNode deaths = new DefaultMutableTreeNode( CAT_DEATHS );
for (final Player p : players) {
deaths.add( new DefaultMutableTreeNode( p.getName() ) );
}
//Abilities
final DefaultMutableTreeNode abilities = new DefaultMutableTreeNode( CAT_ABILITIES );
for (final Player p : players) {
final DefaultMutableTreeNode playerNode = new DefaultMutableTreeNode( p.getName() );
final Hero h = p.getHero();
for (final Ability a : h.getAbilities()) {
if (!a.getKey().equals( "attribute_bonus" )) {
playerNode.add( new DefaultMutableTreeNode( a ) );
}
}
abilities.add( playerNode );
}
//Items
final DefaultMutableTreeNode items = new DefaultMutableTreeNode( CAT_ITEMS );
for (final Player p : players) {
final DefaultMutableTreeNode playerNode = new DefaultMutableTreeNode( p.getName() );
final Hero h = p.getHero();
//The hero internally stores an object for every item entity it seen. We have
//to flatten this down to only unique item names. We'll ask the Hero later for only
//specific items of a certain type when we build the data set in the ChartCreator
final Set<String> itemNames = new HashSet<String>();
for (final Dota2Item i : h.getAllItems()) {
//Just take items that can be and were actively used
if (!i.getUsage().isEmpty()) {
itemNames.add( i.getKey() );
}
}
for (final String s : itemNames) {
playerNode.add( new DefaultMutableTreeNode( s ) );
}
items.add( playerNode );
}
//Root
final DefaultTreeModel model = (DefaultTreeModel) attributeTree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
if (root != null) {
root.removeAllChildren();
}
else {
root = new DefaultMutableTreeNode();
model.setRoot( root );
}
root.add( movement );
root.add( deaths );
root.add( abilities );
root.add( items );
model.reload( root );
}
public JTree getAttributeTree() {
if (attributeTree == null) {
final TreeModel model = new DefaultTreeModel( null );
attributeTree = new JTree( model );
final TreeSelectionModel selectionModel = attributeTree.getSelectionModel();
selectionModel.setSelectionMode( TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION );
attributeTree.addTreeSelectionListener( new TreeSelectionListener() {
@Override
public void valueChanged( TreeSelectionEvent e ) {
final TreePath[] paths = e.getPaths();
for (int i = 0; i < paths.length; i++) {
final TreePath p = paths[i];
final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) p.getLastPathComponent();
if (selectedNode.isLeaf()) {
final Object selection = selectedNode.getUserObject();
String catName = null;
DefaultMutableTreeNode category = selectedNode;
while (catName == null) {
category = (DefaultMutableTreeNode) category.getParent();
final String value = (String) category.getUserObject();
switch (value) {
case CAT_MOVEMENT:
case CAT_DEATHS:
case CAT_ABILITIES:
case CAT_ITEMS:
catName = value;
break;
}
}
if (e.isAddedPath( i )) {
switch (catName) {
case CAT_MOVEMENT: {
final Player player = appState.getPlayerByName( (String) selection );
final XYSeries s = ChartCreator.createMoveMap( player.getName(), appState );
s.setKey( player.getName() + catName );
getMapCanvas().addSeries( s, player.getId() );
}
break;
case CAT_DEATHS: {
final Player player = appState.getPlayerByName( (String) selection );
final XYSeries s = ChartCreator.createDeathMap( player.getName(), appState );
s.setKey( player.getName() + catName );
getMapCanvas().addSeries( s, player.getId() );
}
break;
case CAT_ABILITIES: {
final String playerName = (String) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject();
final Player player = appState.getPlayerByName( playerName );
final XYSeries s = ChartCreator.createAbilityMap( player.getHero(), ((Ability) selection).getKey() );
getMapCanvas().addSeries( s, player.getId() );
}
break;
case CAT_ITEMS: {
final String playerName = (String) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject();
final Player player = appState.getPlayerByName( playerName );
final XYSeries s = ChartCreator.createItemMap( player.getHero(), (String) selection );
getMapCanvas().addSeries( s, player.getId() );
}
break;
default:
LOGGER.warning( "Unknown category in tree" );
break;
}
getOptionContainer().setEnabled( true );
getOptionContainer().getStepSlider().setMaximum( getMapCanvas().getItemCount() );
}
else {
switch (catName) {
case CAT_ABILITIES:
getMapCanvas().removeSeries( ((Ability) selection).getKey() + catName );
break;
case CAT_ITEMS:
final String playerName = (String) ((DefaultMutableTreeNode) selectedNode.getParent()).getUserObject();
final Player player = appState.getPlayerByName( playerName );
getMapCanvas().removeSeries( player.getHero().getName() + selection + MapComponent.CAT_ABILITIES );
break;
default:
getMapCanvas().removeSeries( selection + catName );
break;
}
}
}
}
getMapCanvas().repaint();
}
} );
}
return attributeTree;
}
private JComponent getMapCanvansContainer() {
if (mapCanvasContainer == null) {
mapCanvasContainer = new JPanel();
mapCanvasContainer.add( getMapCanvas() );
mapCanvasContainer.add( getOptionContainer() );
}
return mapCanvasContainer;
}
public MapCanvasComponent getMapCanvas() {
if (mapCanvas == null) {
mapCanvas = new MapCanvasComponent();
}
return mapCanvas;
}
private OptionContainer getOptionContainer() {
if (optionContainer == null) {
optionContainer = new OptionContainer( this, appState );
}
return optionContainer;
}
}