<commit_before>package de.fhpotsdam.unfolding.interactions;

import java.util.Arrays;
import java.util.List;
import java.util.Stack;

import org.apache.log4j.Logger;

import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PVector;
import TUIO.TuioClient;
import TUIO.TuioCursor;
import TUIO.TuioListener;
import TUIO.TuioObject;
import TUIO.TuioPoint;
import TUIO.TuioTime;
import de.fhpotsdam.unfolding.Map;
import de.fhpotsdam.unfolding.events.MapEventBroadcaster;
import de.fhpotsdam.unfolding.events.PanMapEvent;
import de.fhpotsdam.unfolding.geo.Location;

// FIXME Implement tuio to map interactions as events!
// REVISIT Check how to use simpletouch's TuioTransformableObject. For use in events, as in here.
public class TuioCursorHandler extends MapEventBroadcaster implements TuioListener {

	public static Logger log = Logger.getLogger(TuioCursorHandler.class);

	private PApplet p;

	protected TuioClient tuioClient;

	TuioCursor tuioCursor1;
	TuioCursor tuioCursor2;

	Stack<TuioCursor> unusedTuioCursorStack = new Stack<TuioCursor>();

	float oldAngle;
	float oldDist;
	PFont font;

	public TuioCursorHandler(PApplet p, Map... maps) {
		this(p, Arrays.asList(maps));
	}

	public TuioCursorHandler(PApplet p, boolean listenToTuio, Map... maps) {
		this(p, listenToTuio, Arrays.asList(maps));
	}

	public TuioCursorHandler(PApplet p, boolean listenToTuio, List<Map> maps) {
		super(maps);

		this.p = p;
		this.font = p.createFont("Sans-Serif", 12);

		tuioClient = new TuioClient();
		if (listenToTuio) {
			tuioClient.addTuioListener(this);
		}
		tuioClient.connect();

		p.registerDispose(this);
	}

	public TuioCursorHandler(PApplet p, List<Map> maps) {
		this(p, true, maps);
	}

	public void dispose() {
		tuioClient.disconnect();
	}

	public TuioClient getTuioClient() {
		return tuioClient;
	}

	public void updateTuioCursor(TuioCursor tcur) {
		int x = tcur.getScreenX(p.width);
		int y = tcur.getScreenY(p.height);

		// Updates go to all hit ones, independent of z-index
		for (Map map : maps) {
			if (map.isHit(x, y)) {

				if (tuioCursor1 != null && tuioCursor2 != null) {
					// Two fingers: Zoom + Rotate
					// FIXME In very high zoom levels zooming is off. Precision problem?
					// (float/double)

					// Uses inner zoom and inner rotation, thus fingers are on same location
					// TODO Do study on usability for different interaction approaches.

					// Flags to test various combinations
					boolean zoom = true;
					boolean rotate = true;

					PVector transCenter = new PVector();
					if (tuioCursor2.getCursorID() == tcur.getCursorID()) {
						transCenter.x = tuioCursor1.getScreenX(p.width);
						transCenter.y = tuioCursor1.getScreenY(p.height);
					} else {
						transCenter.x = tuioCursor2.getScreenX(p.width);
						transCenter.y = tuioCursor2.getScreenY(p.height);
					}

					if (zoom) {
						// 1. pos of last finger
						map.mapDisplay.setInnerTransformationCenter(transCenter);

						// 2. object center: pinch gesture w/o fixed finger-location connection
						// float[] objectCenterXY =
						// map.mapDisplay.getScreenFromObjectPosition(map.mapDisplay.getWidth()/2,
						// map.mapDisplay.getHeight()/2);
						// PVector objectCenter = new PVector(objectCenterXY[0], objectCenterXY[1]);
						// map.mapDisplay.setInnerTransformationCenter(objectCenter);

						// TODO 3. middle pos between both fingers

						float newDist = getDistance(tuioCursor1, tuioCursor2);
						float scaleDelta = newDist / oldDist;
						oldDist = newDist;
						map.zoom(scaleDelta);
					}

					if (rotate) {
						// rotate center
						map.mapDisplay.setTransformationCenter(transCenter);

						float newAngle = getAngleBetween(tuioCursor1, tuioCursor2);
						float angle = newAngle - oldAngle;
						oldAngle = newAngle;
						map.rotate(angle);
					}

					// TODO Use events (instead of direct map manipulation)
					// ZoomMapEvent zoomMapEvent = new ZoomMapEvent(this, map.getId());
					// zoomMapEvent.setTransformationCenterLocation(transformationCenterLocation);

				} else if (tuioCursor1 != null) {<commit_msg>Use Events for Tuio zoom.<commit_after>package de.fhpotsdam.unfolding.interactions;

import java.util.Arrays;
import java.util.List;
import java.util.Stack;

import org.apache.log4j.Logger;

import processing.core.PApplet;
import processing.core.PFont;
import processing.core.PVector;
import TUIO.TuioClient;
import TUIO.TuioCursor;
import TUIO.TuioListener;
import TUIO.TuioObject;
import TUIO.TuioPoint;
import TUIO.TuioTime;
import de.fhpotsdam.unfolding.Map;
import de.fhpotsdam.unfolding.events.MapEventBroadcaster;
import de.fhpotsdam.unfolding.events.PanMapEvent;
import de.fhpotsdam.unfolding.events.ZoomMapEvent;
import de.fhpotsdam.unfolding.geo.Location;

// FIXME Implement tuio to map interactions as events!
// REVISIT Check how to use simpletouch's TuioTransformableObject. For use in events, as in here.
public class TuioCursorHandler extends MapEventBroadcaster implements TuioListener {

	public static Logger log = Logger.getLogger(TuioCursorHandler.class);

	private PApplet p;

	protected TuioClient tuioClient;

	TuioCursor tuioCursor1;
	TuioCursor tuioCursor2;

	Stack<TuioCursor> unusedTuioCursorStack = new Stack<TuioCursor>();

	float oldAngle;
	float oldDist;
	PFont font;

	public TuioCursorHandler(PApplet p, Map... maps) {
		this(p, Arrays.asList(maps));
	}

	public TuioCursorHandler(PApplet p, boolean listenToTuio, Map... maps) {
		this(p, listenToTuio, Arrays.asList(maps));
	}

	public TuioCursorHandler(PApplet p, boolean listenToTuio, List<Map> maps) {
		super(maps);

		this.p = p;
		this.font = p.createFont("Sans-Serif", 12);

		tuioClient = new TuioClient();
		if (listenToTuio) {
			tuioClient.addTuioListener(this);
		}
		tuioClient.connect();

		p.registerDispose(this);
	}

	public TuioCursorHandler(PApplet p, List<Map> maps) {
		this(p, true, maps);
	}

	public void dispose() {
		tuioClient.disconnect();
	}

	public TuioClient getTuioClient() {
		return tuioClient;
	}

	public void updateTuioCursor(TuioCursor tcur) {
		int x = tcur.getScreenX(p.width);
		int y = tcur.getScreenY(p.height);

		// Updates go to all hit ones, independent of z-index
		for (Map map : maps) {
			if (map.isHit(x, y)) {

				if (tuioCursor1 != null && tuioCursor2 != null) {
					// Two fingers: Zoom + Rotate
					// FIXME In very high zoom levels zooming is off. Precision problem?
					// (float/double)

					// Uses inner zoom and inner rotation, thus fingers are on same location
					// TODO Do study on usability for different interaction approaches.

					// Flags to test various combinations
					boolean zoom = true;
					boolean rotate = true;

					PVector transCenter = new PVector();
					if (tuioCursor2.getCursorID() == tcur.getCursorID()) {
						transCenter.x = tuioCursor1.getScreenX(p.width);
						transCenter.y = tuioCursor1.getScreenY(p.height);
					} else {
						transCenter.x = tuioCursor2.getScreenX(p.width);
						transCenter.y = tuioCursor2.getScreenY(p.height);
					}

					if (zoom) {
						ZoomMapEvent zoomMapEvent = new ZoomMapEvent(
								this, map.getId(), ZoomMapEvent.ZOOM_BY);

						// 1. pos of last finger
						//map.mapDisplay.setInnerTransformationCenter(transCenter);
						Location centerLocation = map.getLocationFromScreenPosition(transCenter.x, transCenter.y);
						zoomMapEvent.setTransformationCenterLocation(centerLocation);

						// 2. object center: pinch gesture w/o fixed finger-location connection
						// float[] objectCenterXY =
						// map.mapDisplay.getScreenFromObjectPosition(map.mapDisplay.getWidth()/2,
						// map.mapDisplay.getHeight()/2);
						// PVector objectCenter = new PVector(objectCenterXY[0], objectCenterXY[1]);
						// map.mapDisplay.setInnerTransformationCenter(objectCenter);

						// TODO 3. middle pos between both fingers

						float newDist = getDistance(tuioCursor1, tuioCursor2);
						float scaleDelta = newDist / oldDist;
						oldDist = newDist;
						zoomMapEvent.setZoomLevelDelta((int)scaleDelta);

						eventDispatcher.fireMapEvent(zoomMapEvent);
					}

					if (rotate) {
						// rotate center
						map.mapDisplay.setTransformationCenter(transCenter);

						float newAngle = getAngleBetween(tuioCursor1, tuioCursor2);
						float angle = newAngle - oldAngle;
						oldAngle = newAngle;
						map.rotate(angle);
					}

					// TODO Use events (instead of direct map manipulation)
					// ZoomMapEvent zoomMapEvent = new ZoomMapEvent(this, map.getId());
					// zoomMapEvent.setTransformationCenterLocation(transformationCenterLocation);

				} else if (tuioCursor1 != null) {
{'fraction_non_alphanumeric': 0.1040676787576776, 'fraction_numerical': 0.005562637617336887, 'mean_word_length': 3.6902173913043477, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4903120', 'n_tokens_mistral': 3335, 'n_tokens_neox': 2758, 'n_words': 657}