<commit_before>package org.mwc.debrief.timebar.painter;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.nebula.widgets.ganttchart.AbstractPaintManager;
import org.eclipse.nebula.widgets.ganttchart.AdvancedTooltip;
import org.eclipse.nebula.widgets.ganttchart.DefaultSettings;
import org.eclipse.nebula.widgets.ganttchart.GanttChart;
import org.eclipse.nebula.widgets.ganttchart.GanttComposite;
import org.eclipse.nebula.widgets.ganttchart.GanttEvent;
import org.eclipse.nebula.widgets.ganttchart.GanttEventListenerAdapter;
import org.eclipse.nebula.widgets.ganttchart.GanttGroup;
import org.eclipse.nebula.widgets.ganttchart.GanttImage;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.nebula.widgets.ganttchart.ISettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.mwc.debrief.timebar.Activator;
import org.mwc.debrief.timebar.model.IEventEntry;
import org.mwc.debrief.timebar.model.TimeSpot;

import MWC.GUI.Editable;



public class NebulaGanttPainter implements ITimeBarsPainter, PropertyChangeListener
{
	GanttChart _chart;
	Map<IEventEntry, GanttEvent> _eventEntries = new HashMap<IEventEntry, GanttEvent>();	
	List<ITimeBarsPainterListener> _listeners = new ArrayList<ITimeBarsPainterListener>();
	GanttEvent _earliestEvent = null;
	GanttEvent _latestEvent = null;
	
	public NebulaGanttPainter(final Composite parent)
	{
		_chart = new GanttChart(parent, SWT.MULTI, new GanttChartSettings(),
				null /* color manager */, 
				new GanttPaintManager(), null /* language manager */);		
		
		_chart.getGanttComposite().addMouseListener(new MouseListener() {
			
			@Override
			public void mouseUp(final MouseEvent e) {}
			
			@Override
			public void mouseDown(final MouseEvent e) {}
			
			@Override
			public void mouseDoubleClick(final MouseEvent e) 
			{
				//TODO: do not do anything if an event was double-clicked
				final Date clickedAt = _chart.getGanttComposite().getDateAt(e.x).getTime();
				if (_earliestEvent.getStartDate().getTime().compareTo(clickedAt) > 0)
				{
					// it is too early
					return;
				}
				if (_latestEvent.getEndDate().getTime().compareTo(clickedAt) < 0)
				{
					//it is too late
					return;
				}
					
				chartDoubleClicked(clickedAt);				
			}
		});
		
		_chart.addGanttEventListener(new GanttEventListenerAdapter()
    	{
    		@Override
    		@SuppressWarnings("rawtypes")
    		public void eventSelected(final GanttEvent event, final List allSelectedEvents,
    				final MouseEvent me) 
    		{
    			super.eventSelected(event, allSelectedEvents, me);
    			final IEventEntry eventEntry = findEventEntry(event);
    			if (eventEntry != null)
    				eventIsSelected(eventEntry.getSource());
    		}  
    		
    		@Override
    		public void eventDoubleClicked(final GanttEvent event, final MouseEvent me) 
    		{    		
    			super.eventDoubleClicked(event, me);
    			final IEventEntry eventEntry = findEventEntry(event);
    			if (eventEntry != null)
    				eventIsDoubleClicked(eventEntry.getSource());	
    		}
    	});
	
	}
	
	@Override
	public void drawBar(final IEventEntry modelEntry) 
	{
		if (!modelEntry.isVisible())
			return;
			
		final GanttEvent evt = new GanttEvent(_chart, modelEntry.getName(), 
				modelEntry.getStart(), modelEntry.getEnd(), 0);
		if (modelEntry.getColor() !=null)
			evt.setStatusColor(modelEntry.getColor());
		
		if (modelEntry.getChildren().size() > 0)
		{
			evt.setScope(true);
			evt.setTextFont(new Font(null, "Arial", 12, SWT.BOLD ));
			evt.setStatusColor(modelEntry.getColor());
			final GanttGroup group = new GanttGroup(_chart);
			for (final IEventEntry entry: modelEntry.getChildren())
			{
				if (entry instanceof TimeSpot)
				{
					drawSpot(entry);					
					group.addEvent(_eventEntries.get(entry));
				}
				else
				{
					drawBar(entry);
				}
				evt.addScopeEvent(_eventEntries.get(entry));
			}
		}
		addEvent(evt, modelEntry);		
	}

	@Override
	public void drawSpot(final IEventEntry modelEntry) 
	{		
		if (!modelEntry.isVisible())
			return;
		final GanttImage evt = new GanttImage(_chart, "", modelEntry.getStart(),
				Activator.getImageDescriptor("icons/sample.gif").createImage());
		evt.setAdvancedTooltip(new AdvancedTooltip("", modelEntry.getToolTipText()));
		if (modelEntry.getColor() !=null)
			evt.setStatusColor(modelEntry.getColor());
		addEvent(evt, modelEntry);
	}
	
	private void addEvent(final GanttEvent evt, final IEventEntry modelEntry)
	{
		_eventEntries.put(modelEntry, evt);
		if (_earliestEvent == null)
		{
			_earliestEvent = evt;
		}
		else
		{
			if (evt.getStartDate().compareTo(_earliestEvent.getStartDate()) < 0)
			{
				_earliestEvent = evt;
			}
		}
		if(_latestEvent == null)
		{
			_latestEvent = evt;
		}
		else
		{
			if (evt.getEndDate().compareTo(_latestEvent.getEndDate()) > 0)
			{
				_latestEvent = evt;
			}
		}<commit_msg>Fixed NullPointerException when draw a bar event<commit_after>package org.mwc.debrief.timebar.painter;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.nebula.widgets.ganttchart.AbstractPaintManager;
import org.eclipse.nebula.widgets.ganttchart.AdvancedTooltip;
import org.eclipse.nebula.widgets.ganttchart.DefaultSettings;
import org.eclipse.nebula.widgets.ganttchart.GanttChart;
import org.eclipse.nebula.widgets.ganttchart.GanttComposite;
import org.eclipse.nebula.widgets.ganttchart.GanttEvent;
import org.eclipse.nebula.widgets.ganttchart.GanttEventListenerAdapter;
import org.eclipse.nebula.widgets.ganttchart.GanttGroup;
import org.eclipse.nebula.widgets.ganttchart.GanttImage;
import org.eclipse.nebula.widgets.ganttchart.IColorManager;
import org.eclipse.nebula.widgets.ganttchart.ISettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.mwc.debrief.timebar.Activator;
import org.mwc.debrief.timebar.model.IEventEntry;
import org.mwc.debrief.timebar.model.TimeSpot;

import MWC.GUI.Editable;



public class NebulaGanttPainter implements ITimeBarsPainter, PropertyChangeListener
{
	GanttChart _chart;
	Map<IEventEntry, GanttEvent> _eventEntries = new HashMap<IEventEntry, GanttEvent>();	
	List<ITimeBarsPainterListener> _listeners = new ArrayList<ITimeBarsPainterListener>();
	GanttEvent _earliestEvent = null;
	GanttEvent _latestEvent = null;
	
	public NebulaGanttPainter(final Composite parent)
	{
		_chart = new GanttChart(parent, SWT.MULTI, new GanttChartSettings(),
				null /* color manager */, 
				new GanttPaintManager(), null /* language manager */);		
		
		_chart.getGanttComposite().addMouseListener(new MouseListener() {
			
			@Override
			public void mouseUp(final MouseEvent e) {}
			
			@Override
			public void mouseDown(final MouseEvent e) {}
			
			@Override
			public void mouseDoubleClick(final MouseEvent e) 
			{
				//TODO: do not do anything if an event was double-clicked
				final Date clickedAt = _chart.getGanttComposite().getDateAt(e.x).getTime();
				if (_earliestEvent.getStartDate().getTime().compareTo(clickedAt) > 0)
				{
					// it is too early
					return;
				}
				if (_latestEvent.getEndDate().getTime().compareTo(clickedAt) < 0)
				{
					//it is too late
					return;
				}
					
				chartDoubleClicked(clickedAt);				
			}
		});
		
		_chart.addGanttEventListener(new GanttEventListenerAdapter()
    	{
    		@Override
    		@SuppressWarnings("rawtypes")
    		public void eventSelected(final GanttEvent event, final List allSelectedEvents,
    				final MouseEvent me) 
    		{
    			super.eventSelected(event, allSelectedEvents, me);
    			final IEventEntry eventEntry = findEventEntry(event);
    			if (eventEntry != null)
    				eventIsSelected(eventEntry.getSource());
    		}  
    		
    		@Override
    		public void eventDoubleClicked(final GanttEvent event, final MouseEvent me) 
    		{    		
    			super.eventDoubleClicked(event, me);
    			final IEventEntry eventEntry = findEventEntry(event);
    			if (eventEntry != null)
    				eventIsDoubleClicked(eventEntry.getSource());	
    		}
    	});
	
	}
	
	@Override
	public void drawBar(final IEventEntry modelEntry) 
	{
		if (!modelEntry.isVisible())
			return;
			
		GanttEvent evt = _eventEntries.get(modelEntry);
		if (evt == null)
		{
			evt = new GanttEvent(_chart, modelEntry.getName(), 
				modelEntry.getStart(), modelEntry.getEnd(), 0);
			addEvent(evt, modelEntry);		
		}
		if (modelEntry.getColor() !=null)
			evt.setStatusColor(modelEntry.getColor());
		
		if (modelEntry.getChildren().size() > 0)
		{
			evt.setScope(true);
			evt.setTextFont(new Font(null, "Arial", 12, SWT.BOLD ));
			evt.setStatusColor(modelEntry.getColor());
			final GanttGroup group = new GanttGroup(_chart);
			for (final IEventEntry entry: modelEntry.getChildren())
			{
				GanttEvent ganttEvt = _eventEntries.get(entry);
				if (ganttEvt == null)
				{
					ganttEvt = new GanttEvent(_chart, entry.getName(), 
							entry.getStart(), entry.getEnd(), 0);
					addEvent(ganttEvt, entry);
				}
				if (entry instanceof TimeSpot)
				{
					drawSpot(entry);					
					group.addEvent(ganttEvt);
				}
				else
				{
					drawBar(entry);
				}				
				evt.addScopeEvent(ganttEvt);
			}
		}
	}

	@Override
	public void drawSpot(final IEventEntry modelEntry) 
	{		
		if (!modelEntry.isVisible())
			return;
		final GanttImage evt = new GanttImage(_chart, "", modelEntry.getStart(),
				Activator.getImageDescriptor("icons/sample.gif").createImage());
		evt.setAdvancedTooltip(new AdvancedTooltip("", modelEntry.getToolTipText()));
		if (modelEntry.getColor() !=null)
			evt.setStatusColor(modelEntry.getColor());
		addEvent(evt, modelEntry);
	}
	
	private void addEvent(final GanttEvent evt, final IEventEntry modelEntry)
	{
		if (_eventEntries.containsKey(modelEntry))
			return;
		
		_eventEntries.put(modelEntry, evt);
		if (_earliestEvent == null)
		{
			_earliestEvent = evt;
		}
		else
		{
			if (evt.getStartDate().compareTo(_earliestEvent.getStartDate()) < 0)
			{
				_earliestEvent = evt;
			}
		}
		if(_latestEvent == null)
		{
			_latestEvent = evt;
		}
		else
		{
			if (evt.getEndDate().compareTo(_latestEvent.getEndDate()) > 0)
			{
				_latestEvent = evt;
			}
		}
{'fraction_non_alphanumeric': 0.11263250883392226, 'fraction_numerical': 0.0015017667844522968, 'mean_word_length': 3.9609991235758106, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2502217', 'n_tokens_mistral': 4385, 'n_tokens_neox': 3819, 'n_words': 666}