/*******************************************************************************
* Copyright (c) 2012-present Jakub Kováč, Jozef Brandýs, Katarína Kotrlová,
* Pavol Lukča, Ladislav Pápay, Viktor Tomkovič, Tatiana Tóthová
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package algvis.ds.intervaltree;
import java.awt.Color;
import java.util.Hashtable;
import algvis.core.DataStructure;
import algvis.core.Node;
import algvis.core.NodeColor;
import algvis.core.history.HashtableStoreSupport;
import algvis.ds.dictionaries.bst.BST;
import algvis.ds.dictionaries.bst.BSTNode;
import algvis.ds.intervaltree.IntervalTrees.mimasuType;
import algvis.ui.Fonts;
import algvis.ui.view.View;
public class IntervalNode extends BSTNode {
// boolean leaf = true;
int b = 1, e = 1; // zaciatok a koniec intervalu, ktory reprezentuje
public enum focusType {
FALSE, // ziadny obdlznik
TIN, // zeleny obdlznik
TOUT, // cerveny obdlznik
TWAIT // iba obvod obdlznika
}
focusType focused;
private boolean markedColor = false;
public IntervalNode(DataStructure D, int key, int zDepth) {
super(D, key, zDepth);
focused = focusType.FALSE;
}
private IntervalNode(DataStructure D, int key, int x, int y) {
super(D, key, x, y);
bgKeyColor();
}
public IntervalNode(IntervalNode v) {
this(v.D, v.getKey(), v.x, v.y);
}
@Override
public void drawKey(View v) {
v.setColor(getFgColor());
if (getKey() != NOKEY) {
v.drawString(toString(), x, y, Fonts.NORMAL);
}
if (!isLeaf()) {
v.drawStringLeft(Integer.toString(b), x - Node.RADIUS, y
- Node.RADIUS, Fonts.SMALL);
v.drawStringRight(Integer.toString(e), x + Node.RADIUS, y
- Node.RADIUS, Fonts.SMALL);
} else {
v.drawString(Integer.toString(e), x, y + Node.RADIUS + 5,
Fonts.SMALL);
}
}
private static final NodeColor TREE = new NodeColor(Color.BLACK, new Color(
0xFDFF9A));// 0xFEFFC3));
private static final NodeColor EMPTY = new NodeColor(Color.BLACK,
new Color(0xF0F0F0));
@Override
protected void drawBg(View v) {
if (getKey() != NOKEY) {
if (!isLeaf()) {
this.setColor(TREE);
}
} else {
this.setColor(EMPTY);
}
if (!isLeaf()) {
v.setColor(this.getBgColor());
v.fillCircle(x, y, Node.RADIUS);
v.setColor(this.getFgColor());
v.drawCircle(x, y, Node.RADIUS);
if (marked) {
v.drawCircle(x, y, Node.RADIUS + 2);
}
} else {
if (getKey() != NOKEY) {
if (this.markedColor) {
this.setColor(IN);
} else {
this.setColor(NodeColor.NORMAL);
}
} else {
this.setColor(EMPTY);
}
v.setColor(getBgColor());
v.fillSqr(x, y, Node.RADIUS + 1);// + IntervalTree.minsepx);
v.setColor(Color.BLACK); // fgcolor);
v.drawSqr(x, y, Node.RADIUS + 1);// + IntervalTree.minsepx);
// DOROBIT!!!
if (marked) {
v.drawSqr(x, y, Node.RADIUS - 1);
}
}
}
private int i;
@Override
public void drawTree(View v) {
i = 0;
drawTree2(v);
}
private static final NodeColor IN = new NodeColor(Color.BLACK, new Color(
0xAAFF95));
private static final NodeColor OUT = new NodeColor(Color.BLACK, new Color(
0xFC9A79));
private static final NodeColor WAIT = new NodeColor(Color.BLACK, new Color(
0xFFFFFF));
private void drawTree2(View v) {
switch (focused) {
case TIN:
this.setColor(IN);
break;
case TOUT:
this.setColor(OUT);
break;
case TWAIT:
this.setColor(WAIT);
break;
case FALSE:
break;
}
switch (focused) {
case TIN:
case TOUT:
case TWAIT:
v.setColor(this.getFgColor());
final int c = (e - b + 1);
final int d = (int) (Math.log10(c) / Math.log10(2));
// System.out.println(d + " =vyska-1, minsepy= "
// + IntervalTree.minsepy);
final int width = (c) * IntervalTree.minsepx;
final int height = (d) * DataStructure.minsepy + 4 + 2
* Node.RADIUS;
v.drawRoundRectangle(x, y + height / 2 - Node.RADIUS - 3,
width / 2, height / 2, 8, 8);
v.setColor(this.getBgColor());
v.fillRoundRectangle(x, y + height / 2 - Node.RADIUS - 3,
width / 2, height / 2, 8, 8);
default:
break;
}
if (state != INVISIBLE && getParent() != null) {
v.setColor(Color.black);
v.drawLine(x, y, getParent().x, getParent().y);
}
if (getLeft() != null) {
// System.out.println("kreslim lavy " + getLeft().key + " " +
// this.key);
getLeft().drawTree2(v);
}
if (D instanceof BST && ((BST) D).order) { // && D.panel.S.layout ==
// Layout.SIMPLE
v.setColor(Color.LIGHT_GRAY);
++i;
if (i % 10 == 0) {
v.drawLine(x, y, x, -22);
} else {
v.drawLine(x, y, x, -20);
}
if (i % 10 == 0) {
v.drawString("" + i, x, -29, Fonts.NORMAL);
} else if (i % 10 == 5) {
v.drawString("5", x, -27, Fonts.NORMAL);
} else {
v.drawString("" + i % 10, x, -27, Fonts.SMALL);
}
}
if (getRight() != null) {
getRight().drawTree2(v);
}
draw(v);
}
@Override
public void rebox() {
/*
* if there is a left child, leftw = width of the box enclosing the
* whole left subtree, i.e., leftw+rightw; otherwise the width is the
* node RADIUS plus some additional space called xspan
*/
leftw = (getLeft() == null) ? ((IntervalTree) D).getMinsepx() / 2
: getLeft().leftw + getLeft().rightw;
// rightw is computed analogically
rightw = (getRight() == null) ? ((IntervalTree) D).getMinsepx() / 2
: getRight().leftw + getRight().rightw;
}
public boolean prec(IntervalNode v) {
if (((IntervalTree) D).minTree == mimasuType.MIN) {
return getKey() < v.getKey();
} else {
return getKey() > v.getKey();
}
}
/**
* Precedes or equals (see prec).
*/
public boolean preceq(IntervalNode v) {
if (((IntervalTree) D).minTree == mimasuType.MIN) {
return getKey() <= v.getKey();
} else {
return getKey() >= v.getKey();
}
}
@Override
public IntervalNode getRight() {
return (IntervalNode) super.getRight();
}
public void setRight(IntervalNode v) {
super.setRight(v);
}
@Override
public IntervalNode getLeft() {
return (IntervalNode) super.getLeft();
}
public void setLeft(IntervalNode v) {
super.setLeft(v);
}
@Override
public IntervalNode getParent() {
return (IntervalNode) super.getParent();
}
public void setParent(IntervalNode v) {
super.setParent(v);
}
public void setInterval(int i, int j) {
b = i;
e = j;
}
public void markColor() {
markedColor = true;
}
public void unmarkColor() {
markedColor = false;
}
@Override
public IntervalNode find(int x, int y) {
if (inside(x, y)) {
return this;
}
if (getLeft() != null) {
final IntervalNode tmp = getLeft().find(x, y);
if (tmp != null) {
return tmp;
}
}
if (getRight() != null) {
return getRight().find(x, y);
}
return null;
}
@Override
public void storeState(Hashtable<Object, Object> state) {
super.storeState(state);
HashtableStoreSupport.store(state, hash + "b", b);
HashtableStoreSupport.store(state, hash + "e", e);
HashtableStoreSupport.store(state, hash + "focused", focused);
HashtableStoreSupport.store(state, hash + "markedColor", markedColor);
}
@Override
public void restoreState(Hashtable<?, ?> state) {
super.restoreState(state);
final Object b = state.get(hash + "b");
if (b != null) {
this.b = (Integer) HashtableStoreSupport.restore(b);
}
final Object e = state.get(hash + "e");
if (e != null) {
this.e = (Integer) HashtableStoreSupport.restore(e);
}
final Object focused = state.get(hash + "focused");
if (focused != null) {
this.focused = (focusType) HashtableStoreSupport.restore(focused);
}
final Object markedColor = state.get(hash + "markedColor");
if (markedColor != null) {
this.markedColor = (Boolean) HashtableStoreSupport
.restore(markedColor);
}
}
}