<commit_before>// PathVisio,
// a tool for data visualization and analysis using Biological Pathways
// Copyright 2006-2007 BiGCaT Bioinformatics
//
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0 
//  
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
//
package org.pathvisio.view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import org.pathvisio.preferences.GlobalPreference;

public abstract class VPathwayElement implements Comparable<VPathwayElement>
{	
	protected BasicStroke defaultStroke = new BasicStroke();
	
	protected VPathway canvas;
	
	VPathwayElement(VPathway canvas)
	{
		this.canvas = canvas;
		canvas.addObject(this);
	}
	
	public static Color selectColor = GlobalPreference.getValueColor(GlobalPreference.COLOR_SELECTED);
	public static final float HIGHLIGHT_STROKE_WIDTH = 5.0f;

	private Rectangle2D oldrect = null;
	
	private boolean isSelected;
	
	/**
	 * Will be called by VPathway whenever the zoom factor
	 * is changed. Default implementation refreshes the cache
	 * of VBounds and VOutline.
	 */
	void zoomChanged() { 
		resetShapeCache();
	}
	
	private Shape vOutlineCache;
	private Rectangle2D vBoundsCache;
	
	/**
	 * Resets cache for VOutline and VBounds so that
	 * they will be recalculated on the next call to
	 * getVOutline or getVBounds.
	 */
	protected void resetShapeCache() {
		vOutlineCache = null;
		vBoundsCache = null;
	}
	
	public final void draw(Graphics2D g2d)
	{
		//Create a copy to ensure that the state of this Graphics2D will be intact
		//see: http://java.sun.com/docs/books/tutorial/uiswing/painting/concepts2.html
		
		Graphics2D g = (Graphics2D)g2d.create();
				
		//Prevent element from drawing outside its bounds
		g.clip(getVBounds());
		g.setStroke(defaultStroke);
		//Perform the drawing
		doDraw(g);
		
		//Free resources from the copied Graphics2D
		g.dispose();
	}
		
	protected abstract void doDraw(Graphics2D g2d);
	
	/** 
	 * mark both the area currently and previously occupied by this object for redraw 
	 */
	protected void markDirty()
	{
		if (oldrect != null)
		{
			canvas.addDirtyRect(oldrect);
		}
		resetShapeCache();
		Rectangle2D newrect = getVBounds();
		canvas.addDirtyRect(newrect);
		oldrect = newrect;
	}

	/**
	 * Get the drawing this object belongs to
	 */
	public VPathway getDrawing()
	{
		return canvas;
	}
	
	/**
	 * Besides resetting isHighlighted, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in unhighlighted state
	 */
	public void unhighlight()
	{
		if(isHighlighted)
		{
			isHighlighted = false;
			highlightColor = null;
			markDirty();
		}
	}

	private Color highlightColor;
	public Color getHighlightColor()
	{
		return highlightColor;
	}
	
	private boolean isHighlighted;

	/**
	 Besides setting isHighlighted, this accomplishes this:
	 - marking the area dirty, so the object has a chance to redraw itself in highlighted state

	 @param c this will highlight in a particular color. See
	 highlight() without parameter if you just want to highlight with
	 the default color
	 */
	public void highlight(Color c)
	{
		if(!(isHighlighted && highlightColor == c))
		{
			isHighlighted = true;
			highlightColor = c;
			markDirty();
		}
	}

	/**
	   highlight this element with the default highlight color
	 */
	public void highlight()
	{
		highlight (GlobalPreference.getValueColor(GlobalPreference.COLOR_HIGHLIGHTED));
	}
	
	/**
	 * Returns true if this object is highlighted, false otherwise
	 */
	public boolean isHighlighted()
	{
		return isHighlighted;
	}

	/**
	 * Determines whether a Graphics object intersects 
	 * the rectangle specified
	 * @param r - the rectangle to check
	 * @return True if the object intersects the rectangle, false otherwise
	 */
	protected boolean vIntersects(Rectangle2D r)
	{
		return getVOutline().intersects(r);
	}
	
	/**
	 * Determines whether a Graphics object contains
	 * the point specified
	 * @param point - the point to check
	 * @return True if the object contains the point, false otherwise
	 */
	protected boolean vContains(Point2D point)
	{
		return getVOutline().contains(point);
	}	
	
	public boolean isSelected()
	{
		return isSelected;
	}
	
	/**
	 * Besides resetting isSelected, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in unselected state
	 */
	public void deselect()
	{
		if (isSelected)
		{
			isSelected = false;
			markDirty();			
		}
	}

	/**
	 * Besides setting isSelected, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in selected state<commit_msg>Use vBounds as a first approximation in vIntersects and vContains, only use vOutline when necessary.  This leads to a decent efficiency gain.<commit_after>// PathVisio,
// a tool for data visualization and analysis using Biological Pathways
// Copyright 2006-2007 BiGCaT Bioinformatics
//
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0 
//  
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
//
package org.pathvisio.view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import org.pathvisio.preferences.GlobalPreference;

public abstract class VPathwayElement implements Comparable<VPathwayElement>
{	
	protected BasicStroke defaultStroke = new BasicStroke();
	
	protected VPathway canvas;
	
	VPathwayElement(VPathway canvas)
	{
		this.canvas = canvas;
		canvas.addObject(this);
	}
	
	public static Color selectColor = GlobalPreference.getValueColor(GlobalPreference.COLOR_SELECTED);
	public static final float HIGHLIGHT_STROKE_WIDTH = 5.0f;

	private Rectangle2D oldrect = null;
	
	private boolean isSelected;
	
	/**
	 * Will be called by VPathway whenever the zoom factor
	 * is changed. Default implementation refreshes the cache
	 * of VBounds and VOutline.
	 */
	void zoomChanged() { 
		resetShapeCache();
	}
	
	private Shape vOutlineCache;
	private Rectangle2D vBoundsCache;
	
	/**
	 * Resets cache for VOutline and VBounds so that
	 * they will be recalculated on the next call to
	 * getVOutline or getVBounds.
	 */
	protected void resetShapeCache() {
		vOutlineCache = null;
		vBoundsCache = null;
	}
	
	public final void draw(Graphics2D g2d)
	{
		//Create a copy to ensure that the state of this Graphics2D will be intact
		//see: http://java.sun.com/docs/books/tutorial/uiswing/painting/concepts2.html
		
		Graphics2D g = (Graphics2D)g2d.create();
				
		//Prevent element from drawing outside its bounds
		g.clip(getVBounds());
		g.setStroke(defaultStroke);
		//Perform the drawing
		doDraw(g);
		
		//Free resources from the copied Graphics2D
		g.dispose();
	}
		
	protected abstract void doDraw(Graphics2D g2d);
	
	/** 
	 * mark both the area currently and previously occupied by this object for redraw 
	 */
	protected void markDirty()
	{
		if (oldrect != null)
		{
			canvas.addDirtyRect(oldrect);
		}
		resetShapeCache();
		Rectangle2D newrect = getVBounds();
		canvas.addDirtyRect(newrect);
		oldrect = newrect;
	}

	/**
	 * Get the drawing this object belongs to
	 */
	public VPathway getDrawing()
	{
		return canvas;
	}
	
	/**
	 * Besides resetting isHighlighted, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in unhighlighted state
	 */
	public void unhighlight()
	{
		if(isHighlighted)
		{
			isHighlighted = false;
			highlightColor = null;
			markDirty();
		}
	}

	private Color highlightColor;
	public Color getHighlightColor()
	{
		return highlightColor;
	}
	
	private boolean isHighlighted;

	/**
	 Besides setting isHighlighted, this accomplishes this:
	 - marking the area dirty, so the object has a chance to redraw itself in highlighted state

	 @param c this will highlight in a particular color. See
	 highlight() without parameter if you just want to highlight with
	 the default color
	 */
	public void highlight(Color c)
	{
		if(!(isHighlighted && highlightColor == c))
		{
			isHighlighted = true;
			highlightColor = c;
			markDirty();
		}
	}

	/**
	   highlight this element with the default highlight color
	 */
	public void highlight()
	{
		highlight (GlobalPreference.getValueColor(GlobalPreference.COLOR_HIGHLIGHTED));
	}
	
	/**
	 * Returns true if this object is highlighted, false otherwise
	 */
	public boolean isHighlighted()
	{
		return isHighlighted;
	}

	/**
	 * Determines whether a Graphics object intersects 
	 * the rectangle specified
	 * @param r - the rectangle to check
	 * @return True if the object intersects the rectangle, false otherwise
	 */
	protected boolean vIntersects(Rectangle2D r)
	{
		// first use getVBounds as a rough approximation
		if (getVBounds().intersects(r))
		{
			// Yes, the vbounds intersects, now try to be more precise
			return getVOutline().intersects(r);
		}
		else
		{
			return false;
		}
	}
	
	/**
	 * Determines whether a Graphics object contains
	 * the point specified
	 * @param point - the point to check
	 * @return True if the object contains the point, false otherwise
	 */
	protected boolean vContains(Point2D point)
	{
		// first use getVBounds as a rough approximation
		if (getVBounds().contains(point))
		{
			// Yes, the vbounds contains, now try to be more precise
			return getVOutline().contains(point);
		}
		else 
		{
			return false;
		}
	}	
	
	public boolean isSelected()
	{
		return isSelected;
	}
	
	/**
	 * Besides resetting isSelected, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in unselected state
	 */
	public void deselect()
	{
		if (isSelected)
		{
			isSelected = false;
			markDirty();			
		}
	}

	/**
	 * Besides setting isSelected, this accomplishes this:
	 * - marking the area dirty, so the object has a chance to redraw itself in selected state
{'fraction_non_alphanumeric': 0.08366460201534621, 'fraction_numerical': 0.005916612739206804, 'mean_word_length': 3.5645569620253164, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '4619813', 'n_tokens_mistral': 3555, 'n_tokens_neox': 3126, 'n_words': 1136}