/*******************************************************************************
* Copyright 2016 Observational Health Data Sciences and Informatics
*
* This file is part of WhiteRabbit
*
* 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.ohdsi.rabbitInAHat;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.ChangeListener;
import org.ohdsi.rabbitInAHat.dataModel.MappableItem;
public class LabeledRectangle implements MappingComponent {
public static int FONT_SIZE = 18;
private static Stroke stroke = new BasicStroke(2);
private static BasicStroke dashed = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 10.f }, 0.0f);
private List<ChangeListener> changeListeners = new ArrayList<ChangeListener>();
private int x;
private int y;
private int width;
private int height;
private MappableItem item;
private Color baseColor;
private Color transparentColor;
private boolean isVisible = true;
private boolean isSelected = false;
public void addChangeListener(ChangeListener x) {
changeListeners.add(x);
}
public void removeChangeListener(ChangeListener x) {
changeListeners.remove(x);
}
public LabeledRectangle(int x, int y, int width, int height, MappableItem item, Color baseColor) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.item = item;
this.baseColor = baseColor;
this.transparentColor = new Color(baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), 128);
}
public boolean isVisible(){
return isVisible == true;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
public void filter(String searchTerm){
if (this.getItem().getName().matches(".*(" + searchTerm + ").*") || searchTerm.equals("") ){
this.setVisible(true);
}else{
this.setVisible(false);
this.setSelected(false);
}
}
public void paint(Graphics g) {
if (!isVisible)
return;
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(transparentColor);
g2d.fillRect(x, y, width, height);
if (isSelected) {
g2d.setColor(Color.BLACK);
g2d.setStroke(dashed);
} else {
g2d.setColor(baseColor);
g2d.setStroke(stroke);
}
g2d.drawRect(x, y, width, height);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("default", Font.PLAIN, FONT_SIZE));
FontMetrics fm = g2d.getFontMetrics();
Rectangle2D r = fm.getStringBounds(item.outputName(), g2d);
if (r.getWidth() >= width) {
int breakPoint = 0;
int index = nextBreakPoint(item.outputName(), 0);
double midPoint = item.outputName().length() / 2d;
while (index != -1) {
if (Math.abs(index - midPoint) < Math.abs(breakPoint - midPoint))
breakPoint = index;
index = nextBreakPoint(item.outputName(), index + 1);
}
if (breakPoint == 0) {
int textX = (this.getWidth() - (int) r.getWidth()) / 2;
int textY = (this.getHeight() - (int) r.getHeight()) / 2 + fm.getAscent();
g2d.drawString(item.outputName(), x + textX, y + textY);
}
breakPoint++;
String line1 = item.outputName().substring(0, breakPoint);
String line2 = item.outputName().substring(breakPoint);
r = fm.getStringBounds(line1, g2d);
int textX = (this.getWidth() - (int) r.getWidth()) / 2;
int textY = (this.getHeight() / 2 - (int) r.getHeight()) / 2 + fm.getAscent();
g2d.drawString(line1, x + textX, y + textY);
r = fm.getStringBounds(line2, g2d);
textX = (this.getWidth() - (int) r.getWidth()) / 2;
textY = (int) Math.round(this.getHeight() * 1.5 - (int) r.getHeight()) / 2 + fm.getAscent();
g2d.drawString(line2, x + textX, y + textY);
} else {
int textX = (this.getWidth() - (int) r.getWidth()) / 2;
int textY = (this.getHeight() - (int) r.getHeight()) / 2 + fm.getAscent();
g2d.drawString(item.outputName(), x + textX, y + textY);
}
}
private int nextBreakPoint(String string, int start) {
int index1 = string.indexOf(' ', start);
int index2 = string.indexOf('_', start);
if (index1 == -1)
return index2;
else if (index2 == -1)
return index1;
else
return Math.min(index1, index2);
}
public boolean contains(Point point) {
return (point.x >= x && point.x <= x + width && point.y >= y && point.y <= y + height);
}
public boolean contains(Point point, int xOffset, int yOffset) {
Point p = new Point(point.x + xOffset, point.y + yOffset);
return contains(p);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public MappableItem getItem() {
return item;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
public boolean toggleSelected(){
this.isSelected = !this.isSelected;
return isSelected;
}
public void setVisible(boolean value) {
isVisible = value;
}
}