/*******************************************************************************
 * Caleydo - Visualization for Molecular Biology - http://caleydo.org
 * Copyright (c) The Caleydo Team. All rights reserved.
 * Licensed under the new BSD license, available at http://caleydo.org/license
 *******************************************************************************/
package org.caleydo.view.domino.internal.toolbar;

import gleem.linalg.Vec2f;

import java.util.HashSet;
import java.util.Set;

import org.caleydo.core.data.selection.SelectionType;
import org.caleydo.core.util.base.ICallback;
import org.caleydo.core.util.color.Color;
import org.caleydo.core.view.opengl.layout2.GLElement;
import org.caleydo.core.view.opengl.layout2.GLElementDecorator;
import org.caleydo.core.view.opengl.layout2.GLGraphics;
import org.caleydo.core.view.opengl.layout2.geom.Rect;
import org.caleydo.core.view.opengl.layout2.layout.IGLLayoutElement;
import org.caleydo.core.view.opengl.layout2.renderer.RoundedRectRenderer;
import org.caleydo.core.view.opengl.picking.IPickingListener;
import org.caleydo.core.view.opengl.picking.Pick;
import org.caleydo.view.domino.internal.Node;
import org.caleydo.view.domino.internal.NodeGroup;
import org.caleydo.view.domino.internal.NodeSelections;

/**
 * a toolbar which sticks to the single node which is hovered
 *
 * @author Samuel Gratzl
 *
 */
public class DynamicToolBar extends GLElementDecorator implements ICallback<SelectionType>, IPickingListener {
	private NodeSelections selections;

	private boolean hideOnMouseOut = false;
	private boolean mouseOver = false;

	private int timerToHide = 0;

	public DynamicToolBar(NodeSelections selections) {
		this.selections = selections;
		this.selections.onSelectionChanges(this);
		setzDelta(2.f);
		setVisibility(EVisibility.PICKABLE);
		setPicker(null);
		onPick(this);
	}

	@Override
	public void on(SelectionType type) {
		Set<NodeGroup> s = selections.getSelection(type);
		if (type != SelectionType.MOUSE_OVER)
			return;
		Node act = getActNode();
		Node node = null;
		if (s.size() == 1)
			node = s.iterator().next().getNode();
		else
			node = NodeSelections.getSingleNode(s);

		if (node == null) {
			if (mouseOver) {
				hideOnMouseOut = true;
			} else
				timerToHide = 200;
			return;
		}
		timerToHide = 0;
		hideOnMouseOut = false;
		if (act == node)
			return;
		setVisibility(EVisibility.PICKABLE);
		setContent(new NodeTools(new HashSet<>(s)).setLayoutData(node));
	}

	@Override
	public void layout(int deltaTimeMs) {
		if (timerToHide > 0) {
			timerToHide -= deltaTimeMs;
			if (timerToHide <= 0) {
				setVisibility(EVisibility.HIDDEN);
				setContent(null);
			}
		}
		super.layout(deltaTimeMs);
	}

	/**
	 * @return
	 */
	private Node getActNode() {
		GLElement c = getContent();
		if (c == null)
			return null;
		Node node = ((NodeTools) c).getSelection().iterator().next().getNode();
		return node;
	}

	@Override
	public void pick(Pick pick) {
		switch (pick.getPickingMode()) {
		case MOUSE_OVER:
			mouseOver = true;
			timerToHide = 0;
			break;
		case MOUSE_OUT:
			mouseOver = false;
			if (hideOnMouseOut) {
				setVisibility(EVisibility.HIDDEN);
				setContent(null);
				hideOnMouseOut = false;
			}
			break;
		default:
			break;
		}
	}

	@Override
	protected void layoutContent(IGLLayoutElement content, float w, float h, int deltaTimeMs) {
		final NodeTools tools = (NodeTools) content.asElement();
		Node node = tools.getSelection().iterator().next().getNode();
		Vec2f loc = node.getAbsoluteLocation();
		Vec2f base = getAbsoluteLocation();
		Vec2f rel = loc.minus(base);
		float wi = tools.getWidth(24);
		float wl = node.getSize().x();
		if (wl < wi)
			content.setBounds(rel.x() - (wi - wl) * 0.5f, rel.y() - 24, wi, 24);
		else
			content.setBounds(rel.x(), rel.y() - 24, wl, 24);
	}

	@Override
	protected void renderImpl(GLGraphics g, float w, float h) {
		if (getContent() == null)
			return;
		Rect r = getContent().getRectBounds();
		g.color(Color.LIGHT_BLUE);
		RoundedRectRenderer.render(g, r.x(), r.y(), r.width(), r.height(), 5, 3, RoundedRectRenderer.FLAG_TOP
				| RoundedRectRenderer.FLAG_FILL);

		super.renderImpl(g, w, h);
	}

	@Override
	protected void renderPickImpl(GLGraphics g, float w, float h) {
		if (getContent() == null)
			return;
		if (getVisibility() != EVisibility.PICKABLE)
			return;
		Rect r = getContent().getRectBounds();
		g.fillRect(r);
		super.renderPickImpl(g, w, h);
	}
}

@@ -1625,16 +1625,38 @@
 ide = 0;
+%0A%09private float lastW;
 %0A%0A%09publi
@@ -2214,16 +2214,17 @@
 %0A%09%09%09if (
+!
 mouseOve
@@ -2236,62 +2236,56 @@
 %09%09%09%09
-hideOnMouseOut = true;%0A%09%09%09%7D else%0A%09%09%09%09timerToHide = 200
+timerToHide = 200;%0A%09%09%09%7D%0A%09%09%09hideOnMouseOut = true
 ;%0A%09%09
@@ -2685,16 +2685,152 @@
 %09%09%7D%0A%09%09%7D%0A
+%09%09Node act = getActNode();%0A%09%09if (act != null) %7B%0A%09%09%09float wi = act.getSize().x();%0A%09%09%09if (wi != lastW)%0A%09%09%09%09relayout();%0A%09%09%09lastW = wi;%0A%09%09%7D%0A
 %09%09super.

fix missing removal of dynamic toolbar