package factOrFiction.statistics.views;
import java.awt.Color;
import java.text.AttributedString;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.part.ViewPart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.PieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.PieDataset;
import org.jfree.util.Rotation;
import factOrFiction.model.Card;
import factOrFiction.model.CardGroup;
import factOrFiction.model.Deck;
import factOrFiction.model.IUpdateListener;
public class ManaDistributionView extends ViewPart implements IPartListener2, IUpdateListener {
private static String[] manas = {"R", "U", "B", "G", "W", "A"};
private static Color[] manaColors = { Color.red, Color.blue, Color.black, Color.green, Color.white, Color.lightGray };
CLabel colorDistribution;
CLabel manaCurve;
private JFreeChart chartColorDistribution;
private DefaultPieDataset colorDistributionDataSet;
private JFreeChart chartManaCurve;
private DefaultCategoryDataset manaCurveDataSet;
private Deck monitoredDeck;
public ManaDistributionView() {
}
public void createPartControl(Composite parent) {
parent.setLayout( new GridLayout(2, true) );
colorDistribution = new CLabel(parent, SWT.BORDER);
colorDistribution.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true) );
colorDistribution.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {}
public void controlResized(ControlEvent e) {
updateRequiredManaChart(null);
}
});
createColorDistributionChart();
manaCurve = new CLabel(parent, SWT.BORDER);
manaCurve.setLayoutData( new GridData(SWT.FILL, SWT.FILL, true, true) );
manaCurve.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {}
public void controlResized(ControlEvent e) {
updateManaCurveChart(null);
}
});
createManaCurveChart();
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IPartService service = window.getPartService();
service.addPartListener(this);
IWorkbenchPartReference aref = service.getActivePartReference();
if(aref != null) {
IWorkbenchPart apart = aref.getPart(false);
if (apart instanceof EditorPart) {
installUpdateListener(apart);
}
}
}
public void setFocus() {
}
private void createManaCurveChart() {
// Create the JFreeChart data
manaCurveDataSet = new DefaultCategoryDataset();
// Create the actuall JFreeChart chart
chartManaCurve = ChartFactory.createLineChart("Mana Curve", "Spells", "", manaCurveDataSet, PlotOrientation.VERTICAL, false, false, false );
Plot plot = chartManaCurve.getPlot();
plot.setNoDataMessage("No data available");
plot.setForegroundAlpha(0.5f);
// Color adjustment
chartColorDistribution.setBackgroundPaint(Color.white);
}
private void createColorDistributionChart() {
// Create the JFreeChart data
colorDistributionDataSet = new DefaultPieDataset();
// Create the actual JFreeChart chart
chartColorDistribution = ChartFactory.createPieChart3D("Color Distribution", colorDistributionDataSet, false, false, false);
PiePlot plot = (PiePlot) chartColorDistribution.getPlot();
plot.setNoDataMessage("No data available");
plot.setStartAngle(290);
plot.setDirection(Rotation.CLOCKWISE);
plot.setForegroundAlpha(0.5f);
plot.setCircular(false);
plot.setLabelGap(0.02);
for (int i = 0; i < manas.length; i++)
plot.setSectionPaint(new String(manas[i]), manaColors[i]);
plot.setLabelGenerator(new PieSectionLabelGenerator() {
@SuppressWarnings("unchecked")
public AttributedString generateAttributedSectionLabel(PieDataset arg0, Comparable arg1) {
return null;
}
@SuppressWarnings("unchecked")
public String generateSectionLabel(PieDataset dataset, Comparable key) {
String result = null;
if (dataset != null) {
int total = total(dataset);
int val = dataset.getValue(key).intValue();
if ( val > 0) {
result = key + ": "+String.valueOf((val * 100 + total/2 ) / total)+"%";
}
}
return result;
}
private int total(PieDataset data) {
int total = 0;
for (int i = 0; i < data.getItemCount(); i++) {
Number v = data.getValue(i);
if (v != null) {
total = total + v.intValue();
}
}
return total;
}
});
// Color adjustment
chartColorDistribution.setBackgroundPaint(Color.white);
}
public void dispose() {
if (monitoredDeck != null) {
uninstallUpdateListener();
}
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IPartService service = window.getPartService();
service.removePartListener(this);
super.dispose();
}
private void updateRequiredManaChart(Deck deck) {
if(deck != null) {
for (String mana : manas) {
int val = deck.countColoredCards( mana.toCharArray()[0] );
colorDistributionDataSet.setValue( mana, val);
}
int valArtifacts = deck.countArtifacts();
colorDistributionDataSet.setValue( manas[manas.length-1], valArtifacts);
}
// and generate image to display
Rectangle clientArea = colorDistribution.getClientArea();
if(clientArea.width > 0 && clientArea.height > 0 ) {
Image oldImage = colorDistribution.getImage();
if(oldImage != null)
oldImage.dispose();
Image image = ChartImageUtil.createChartImage(colorDistribution.getDisplay(), chartColorDistribution, clientArea.width, clientArea.height );
colorDistribution.setBackground(image);
}
}
private void updateManaCurveChart(Deck deck) {
String rowKey = "Series1";
if(deck != null) {
int[] costDistribution = new int[100];
for (CardGroup current : deck.getChildren()) {
if(current != deck.sideboard) {
for (Card currentCard : current.getAllCards()) {
if( !currentCard.isLand() ) {
int cost = currentCard.getConvertedManaCost();
costDistribution[cost]++;
}
}
}
}
int highest;
for(highest = 99;highest > 0; highest--)
if( costDistribution[highest] != 0)
break;
if(manaCurveDataSet.getRowIndex(rowKey) >= 0)
manaCurveDataSet.removeRow(rowKey);
for(int i=0;i<=highest;i++)
manaCurveDataSet.addValue( costDistribution[i], rowKey, Integer.toString(i) );
}
// and generate image to display
Rectangle clientArea = manaCurve.getClientArea();
if(clientArea.width > 0 && clientArea.height > 0 ) {
Image oldImage = manaCurve.getImage();
if(oldImage != null)
oldImage.dispose();
Image image = ChartImageUtil.createChartImage(manaCurve.getDisplay(), chartManaCurve, clientArea.width, clientArea.height );
manaCurve.setBackground(image);
}
}
public void update(Object o, boolean updateLabels, boolean needSave) {
if(o == monitoredDeck || o == null) {
updateRequiredManaChart(monitoredDeck);
updateManaCurveChart(monitoredDeck);
}
}
private void installUpdateListener(IWorkbenchPart part) {
EditorPart editorPart = (EditorPart)part;
monitoredDeck = (Deck)editorPart.getEditorInput().getAdapter(Deck.class);
monitoredDeck.addUpdateListener(this);
updateRequiredManaChart(monitoredDeck);
updateManaCurveChart(monitoredDeck);
}
private void uninstallUpdateListener() {
if(monitoredDeck != null)
monitoredDeck.removeUpdateListener(this);
monitoredDeck = null;
}
public void partActivated(IWorkbenchPartReference partRef) {
IWorkbenchPart part = partRef.getPart(false);
if(part != null && part != this && part instanceof EditorPart) {
installUpdateListener(part);
}
}
public void partDeactivated(IWorkbenchPartReference partRef) {
IWorkbenchPart part = partRef.getPart(false);
if(part != null && part != this && part instanceof EditorPart)
uninstallUpdateListener();
}
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
public void partClosed(IWorkbenchPartReference partRef) {
}
public void partOpened(IWorkbenchPartReference partRef) {
}
public void partHidden(IWorkbenchPartReference partRef) {
}
public void partVisible(IWorkbenchPartReference partRef) {
}
public void partInputChanged(IWorkbenchPartReference partRef) {
}
}