/*******************************************************************************
* 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.geom.Rectangle2D;
import java.util.Hashtable;
import algvis.core.Node;
import algvis.core.history.HashtableStoreSupport;
import algvis.core.visual.ZDepth;
import algvis.ds.intervaltree.IntervalNode.focusType;
import algvis.ui.VisPanel;
import algvis.ui.view.ClickListener;
import algvis.ui.view.View;
public class IntervalTree extends IntervalTrees implements ClickListener {
public static String dsName = "intervaltree";
IntervalNode root = null;
int numLeafs = 0; // pocet obsadenych listov
public static final int minsepx = 22;
public IntervalTree(VisPanel M) {
super(M);
M.screen.V.setDS(this);
}
@Override
public String getName() {
return "intervaltree";
}
@Override
public String stats() {
return "";
}
@Override
public void insert(int x) {
start(new IntervalInsert(this, x));
}
@Override
public void clear() {
root = null;
numLeafs = 0;
}
@Override
public void draw(View V) {
if (getRoot() != null) {
getRoot().drawTree(V);
}
}
@Override
protected void move() {
if (getRoot() != null) {
getRoot().moveTree();
}
}
@Override
protected Rectangle2D getBoundingBox() {
return root == null ? null : root.getBoundingBox();
}
@Override
protected void endAnimation() {
if (root != null) {
root.endAnimation();
}
}
@Override
protected boolean isAnimationDone() {
return root == null || root.isAnimationDone();
}
@Override
public void mouseClicked(int x, int y) {
// System.out.println("bolo kliknute");
if (root == null) {
return;
}
final IntervalNode v = root.find(x, y);
if (v != null && v.isLeaf()) {
if (v.marked) {
v.unmark();
chosen = null;
} else {
if (chosen != null) {
chosen.unmark();
}
v.mark();
chosen = v;
// System.out.println(v.key + " tento je vybraty");
}
}
}
@Override
public void changeKey(Node v, int value) {
if (v == null) {
// TODO: vypindat
} else {
start(new IntervalChangeKey(this, (IntervalNode) v, value));
}
}
@Override
public void ofinterval(int b, int e) {
start(new IntervalFindMin(this, b, e));
// start(new IntervalInsert(this, b));
}
IntervalNode getRoot() {
return root;
}
public IntervalNode setRoot(IntervalNode root) {
this.root = root;
return this.root;
}
public void reposition() {
x1 = x2 = y1 = y2 = 0;
if (getRoot() != null) {
getRoot().reposition();
}
panel.screen.V.setBounds(x1, y1, x2, y2);
}
int getHeight() {
int tmp = numLeafs;
int res = 1;
while (tmp > 1) {
tmp /= 2;
res++;
}
if (numLeafs > 0) {
return res;
} else {
return 0;
}
}
private int numL;
IntervalNode generateEmpty(int h) {
final IntervalNode w = new IntervalNode(this, Node.NOKEY, ZDepth.NODE);
if (h > 0) {
final IntervalNode tmp1 = generateEmpty(h - 1);
final IntervalNode tmp2 = generateEmpty(h - 1);
w.setLeft(tmp1);
tmp1.setParent(w);
w.setRight(tmp2);
tmp2.setParent(w);
w.setInterval(tmp1.b, tmp2.e);
} else {
w.setInterval(numL, numL);
numL++;
}
return w;
}
public void extend() {
final IntervalNode w = new IntervalNode(this, 0, ZDepth.NODE); // pre suctovy
// strom je
// 0,
// min je +inf, max je -inf
w.setKey(Node.NOKEY);
final IntervalNode w2 = root;
w.setLeft(w2);
w2.setParent(w);
root = w;
numL = numLeafs + 1;
final IntervalNode tmp = generateEmpty(getHeight() - 1);
root.setRight(tmp);
tmp.setParent(root);
// System.out.println(this.getHeight());
reposition();
// root.add();
}
public int getMinsepx() {
return IntervalTree.minsepx;
}
public void unfocus(IntervalNode w) {
if (w == null) {
return;
}
w.focused = focusType.FALSE;
w.unmark();
w.unmarkColor();
unfocus(w.getLeft());
unfocus(w.getRight());
}
public void markColor(IntervalNode w, int i, int j) {
if (w == null) {
return;
}
if (w.isLeaf() && w.b >= i && w.e <= j) {
w.markColor();
}
markColor(w.getLeft(), i, j);
markColor(w.getRight(), i, j);
}
@Override
public void storeState(Hashtable<Object, Object> state) {
super.storeState(state);
HashtableStoreSupport.store(state, hash + "root", root);
HashtableStoreSupport.store(state, hash + "numLeafs", numLeafs);
if (root != null) {
root.storeState(state);
}
}
@Override
public void restoreState(Hashtable<?, ?> state) {
super.restoreState(state);
final Object root = state.get(hash + "root");
if (root != null) {
this.root = (IntervalNode) HashtableStoreSupport.restore(root);
}
final Object numLeafs = state.get(hash + "numLeafs");
if (numLeafs != null) {
this.numLeafs = (Integer) HashtableStoreSupport.restore(numLeafs);
}
if (this.root != null) {
this.root.restoreState(state);
}
}
}