package pl.djvuhtml5.client.ui;

import java.util.ArrayList;

import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.user.client.ui.FlowPanel;

public class Scrollbar extends FlowPanel {

	public static interface ScrollPanListener {
		void thumbDragged(double newCenter, boolean isHorizontal);
	}

	private final boolean isHorizontal;

	private final ArrayList<ScrollPanListener> panListeners = new ArrayList<>();

	public Scrollbar(boolean horizontal) {
		isHorizontal = horizontal;
		setStyleName("scrollbar");
		addStyleName(horizontal ? "scrollbarHorizontal" : "scrollbarVertical");

		new PanHandler();
	}

	public void setThumb(double center, double width) {
		Style style = getElement().getStyle();
		if (width >= 1) {
			style.setVisibility(Visibility.HIDDEN);
			return;
		} else {
			style.setVisibility(Visibility.VISIBLE);
		}
		if (isHorizontal) {
			style.setLeft(100 * (center - width / 2), Unit.PCT);
			style.setRight(100 * (1 - center - width / 2), Unit.PCT);
		} else {
			style.setTop(100.0 * (center - width / 2), Unit.PCT);
			style.setBottom(100 * (1 - center - width / 2), Unit.PCT);
		}
	}

	public void addScrollPanListener(ScrollPanListener listener) {
		panListeners.add(listener);
	}

	private class PanHandler extends PanListener {

		public PanHandler() {
			super(Scrollbar.this);
		}

		@Override
		protected void pan(int dx, int dy) {
			int thumbStart, thumbWidth, fullRange;
			if (isHorizontal) {
				thumbStart = getElement().getOffsetLeft();
				thumbWidth = getOffsetWidth();
				fullRange = getParent().getOffsetWidth();
			} else {
				thumbStart = getElement().getOffsetTop();
				thumbWidth = getOffsetHeight();
				fullRange = getParent().getOffsetHeight();
			}
			double newCenter = ((thumbStart + thumbWidth * 0.5) + (isHorizontal ? dx : dy)) / fullRange;
			for (ScrollPanListener listener : panListeners)
				listener.thumbDragged(newCenter, isHorizontal);
		}

		@Override
		public void onMouseDown(MouseDownEvent event) {
			super.onMouseDown(event);
			if (isMouseDown)
				addStyleName("scrollbarClicked");
		}

		@Override
		public void onMouseUp(MouseUpEvent event) {
			super.onMouseUp(event);
			removeStyleName("scrollbarClicked");
		}
	}
}