<commit_before>package de.sonumina.simpledance;

import static de.sonumina.simpledance.core.I18n._;
import static java.lang.Math.atan;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;

import java.util.LinkedList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ScrollBar;

import de.sonumina.simpledance.core.graphics.Point;
import de.sonumina.simpledance.core.graphics.Render;
import de.sonumina.simpledance.core.model.Pattern;
import de.sonumina.simpledance.core.model.Step;
import de.sonumina.simpledance.core.model.WayPoint;
import de.sonumina.simpledance.graphics.swt.SWTContext;

/**
 * @author <NAME>
 */
public class Ballroom extends Canvas
{
	enum Drag
	{
		NO,
		ROTATE_BALE,
		ROTATE_HEEL,
		MOVE_WAYPOINT
	}

	private SWTContext context;
	private Render render;

	private Color ballroomColor;
	private Color countColor;
	private Cursor cursor;
	private Menu contextMenu;
	private Font countFont;

	private int horizontalScrollbarSelection;
	private int verticalScrollbarSelection;

	private int bufferWidth = -1;
	private int bufferHeight = -1;
	private Image bufferImage;
	private GC bufferGC;

	private Pattern pattern;
	private int zoomFactor = 300;
	private int rotation = 0;
	private int visibleLeft = 570;
	private int visibleTop = 650;
	private int coordinatesX = -1;
	private int coordinatesY = -1;
	private boolean showAnimationOutline = false;
	private boolean showNextStep = false;
	private boolean showPrevStep = false;
	private boolean showGent = true;
	private boolean showLady = true;
	private boolean showCoordinates = true;
	private boolean showGrid = true;
	private boolean showGradients = true;

	private int contextFeetIndex;
	private int contextStepIndex;

	private static class InputContext
	{
		public int selectedStep = -1;
		public int selectedFoot = -1;
		public int selectedWaypoint = -1;
		public boolean mousePressed = false;
		private Drag dragOperation;
		private Point rotationCenterBallroomPoint;
		private int distance;
	}
	private InputContext inputContext = new InputContext();

	private boolean [] selectedArray = new boolean[4];
	
	/* attributes used when painting */
	private boolean animation;
	private boolean animationSingleStep;
	private boolean animationBackward;
	private int animationDrawnSteps;
	private int animationNumber;
	private int animationMaxNumber;

	private LinkedList<BallroomListener> ballroomListenerList = new LinkedList<>();

	private int calculateBallroomAngle(int mx, int my, int x, int y)
	{
		int angle;
		
		if (x < mx)
		{
			if (my != y)
			{
				double t = (mx - x)/(double)(y - my);
				angle = (int)toDegrees(atan(t));
				if (my > y) angle = 180 + angle; 				
			} else angle = 90;
		} else
		if (x > mx)
		{
			if (my != y)
			{
				double t = (mx - x)/(double)(my - y);
				angle = (int)toDegrees(atan(t));
				if (my > y) angle = 180 - angle;
				else angle = 360 - angle; 				
			} else angle = 270;
		} else 
		{
			if (y < my) angle = 180;
			else angle = 0;
		}

		if (angle >= 360) angle -= 360;
		else if (angle < 0) angle += 360 * ((-angle + 359)/360);

		return angle;
	}

	public int calculatePixelAngle(int mx, int my, int x, int y)
	{
		int angle = 180 - calculateBallroomAngle(mx,my,x,y);
		if (angle >= 360) angle -= 360;
		else if (angle < 0) angle += 360 * ((-angle + 359)/360);
		return angle;
	}

	/**
	 * Returns the current scene parameters relevant for rendering.
	 *
	 * @return the scene parameters.
	 */
	private Render.RenderSceneArgs getRenderSceneArgs()
	{
		Render.RenderSceneArgs rsa = new Render.RenderSceneArgs();
		rsa.pattern = pattern;
		rsa.stepNumber = pattern.getCurrentStepNum();
		int visibleWidth = getClientArea().width * 100 / zoomFactor;
		int visibleHeight = getClientArea().height * 100 / zoomFactor;
		rsa.visibleLeftTop = new Point(visibleLeft, visibleTop);
		rsa.visibleRightTop = rsa.visibleLeftTop.add(new Point(visibleWidth, 0).rotate(rotation));
		rsa.visibleLeftBottom = rsa.visibleLeftTop.add(new Point(0, -visibleHeight).rotate(rotation));
		rsa.visibleRightBottom = rsa.visibleLeftTop.add(new Point(visibleWidth, -visibleHeight).rotate(rotation));
		rsa.visibleRotation = rotation;
		rsa.pixelWidth = getClientArea().width;
		rsa.pixelHeight = getClientArea().height;

		rsa.showGrid = showGrid;
		rsa.showPrevStep = showPrevStep;
		rsa.showGradients = showGradients;
		rsa.showPrevStep = showPrevStep;
		rsa.insideAnimation = animation;
		rsa.animationNumber = animationNumber;
		rsa.animationMaxNumber = animationMaxNumber;
		rsa.showLady = showLady;
		rsa.showGent = showGent;
		rsa.showAnimationOutline = showAnimationOutline;
		for (int i=0;i<4;i++) rsa.selectedArray[i] = selectedArray[i];
		return rsa;
	}

	private void createImageBuffer()
	{
		if (bufferImage != null)
		{
			if (bufferWidth != getClientArea().width || 
				bufferHeight != getClientArea().height)
			{
				bufferGC.dispose();
				bufferGC = null;
				bufferImage.dispose();
				bufferImage = null;
			}
		}
				
		if (bufferImage == null)
		{
			bufferImage = new Image(getDisplay(),getClientArea().width,getClientArea().height);
			bufferGC = new GC(bufferImage);
			bufferWidth = getClientArea().width;
			bufferHeight = getClientArea().height;
			context.setGC(bufferGC);
		}
	}
	
	public void dispose()
	{
		super.dispose();

		ballroomColor.dispose();
		countFont.dispose();
		countColor.dispose();
		bufferGC.dispose();
		bufferImage.dispose();
		render.dispose();
		context.dispose();
	}
	
	public Ballroom(Composite comp, int style)
	{
		/* Note since we use a border our client area is proably different */
		super(comp,style|SWT.NO_BACKGROUND|SWT.V_SCROLL|SWT.H_SCROLL|SWT.BORDER);

		context = new SWTContext(getDisplay());
		render = new Render(context);
		
		ballroomColor = new Color(getDisplay(),240,240,200);
		
		countColor = new Color(getDisplay(),255,255,255);
		countFont = new Font(getDisplay(),"Thorndale",20,0);

		SelectionListener selectionListener = new SelectionListener()
		{
			public void widgetSelected(SelectionEvent event)
			{
				ScrollBar scrollbar = (ScrollBar)(event.widget);
				Point diff;
				if ((scrollbar.getStyle() & SWT.V_SCROLL) != 0)
				{
					diff = new Point(0, verticalScrollbarSelection - scrollbar.getSelection()).rotate(rotation);
					verticalScrollbarSelection = scrollbar.getSelection();
				} else
				{
					diff = new Point(scrollbar.getSelection() - horizontalScrollbarSelection, 0).rotate(rotation);
					horizontalScrollbarSelection = scrollbar.getSelection();
				}
				visibleLeft += diff.x;
				visibleTop += diff.y;

				redraw();
				update();
			}
			public void widgetDefaultSelected(SelectionEvent event) {}
		};
		
		
		ScrollBar scrollbar = getVerticalBar();
		scrollbar.setMaximum(1199); 
		scrollbar.setMinimum(0);
		scrollbar.setIncrement(1);
		scrollbar.setSelection(1200 - visibleTop);
		scrollbar.addSelectionListener(selectionListener);
		verticalScrollbarSelection = scrollbar.getSelection();
		
		scrollbar = getHorizontalBar();
		scrollbar.setMaximum(1199); 
		scrollbar.setMinimum(0);
		scrollbar.setIncrement(1);
		scrollbar.setSelection(visibleLeft);
		scrollbar.addSelectionListener(selectionListener);
		horizontalScrollbarSelection = scrollbar.getSelection();
		
		addControlListener(new ControlAdapter()
		{
			public void controlResized(ControlEvent event)
			{
				refreshScrollBars();
			}
		});

		addPaintListener(new PaintListener()
		{
			public void paintControl(PaintEvent e)
			{
				createImageBuffer();
				GC gc = bufferGC;

				render.renderScence(getRenderSceneArgs());

				if (pattern != null)
				{
					if (showCoordinates)
					{
						if (coordinatesX != -1 && coordinatesY != -1)
						{
							StringBuffer buf = new StringBuffer();
							buf.append(coordinatesX);
							buf.append(" ");
							buf.append(coordinatesY);
							buf.append("   ");
							gc.setBackground(ballroomColor);
							gc.setFont(null);
							gc.drawText(buf.toString(),4,2);
						}
					}

					if (animation && pattern.getCurrentStep() != null)
					{
						String count = pattern.getCurrentStep().getCount();
						if (count != null)
						{
							gc.setBackground(ballroomColor);
							gc.setFont(countFont);
							org.eclipse.swt.graphics.Point p = gc.textExtent(count);
							gc.setForeground(countColor);
							gc.drawText(count,getClientArea().x + getClientArea().width - 1 - p.x - 20,2);
						}
					}
				}
				

				e.gc.drawImage(bufferImage,getClientArea().x,getClientArea().y);
			}
		});
		
		
		addMouseMoveListener(new MouseMoveListener()
		{
			public void mouseMove(MouseEvent event)
			{
				Point ballroomPoint = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
				if (coordinatesX != ballroomPoint.x || coordinatesY != ballroomPoint.y)
				{
					coordinatesX = ballroomPoint.x;
					coordinatesY = ballroomPoint.y;
					redraw();
					update();
				}

				if (inputContext.mousePressed && inputContext.dragOperation != Drag.NO)
				{
					if (inputContext.selectedFoot != -1)
					{
						switch (inputContext.dragOperation)
						{
							case	ROTATE_BALE:
									{
										Point p = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
										int winkel = calculateBallroomAngle(
											inputContext.rotationCenterBallroomPoint.x,
											inputContext.rotationCenterBallroomPoint.y,
											p.x,p.y);
										WayPoint feetCoord = pattern.getStep(inputContext.selectedStep).getFoot(inputContext.selectedFoot).getStartingWayPoint();
										feetCoord.x = inputContext.rotationCenterBallroomPoint.x - (int)((inputContext.distance * sin(toRadians(winkel))));
										feetCoord.y = inputContext.rotationCenterBallroomPoint.y + (int)((inputContext.distance * cos(toRadians(winkel))));
										feetCoord.a = winkel;
									}
									break;

							case	ROTATE_HEEL:
									{
										Point p = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
										int angle = calculateBallroomAngle(
											inputContext.rotationCenterBallroomPoint.x,
											inputContext.rotationCenterBallroomPoint.y,
											p.x,p.y) - 180;
										if (angle < 0) angle += 360;
										WayPoint feetCoord = pattern.getStep(inputContext.selectedStep).getFoot(inputContext.selectedFoot).getStartingWayPoint();
										feetCoord.x = inputContext.rotationCenterBallroomPoint.x + (int)((inputContext.distance * sin(toRadians(angle))));
										feetCoord.y = inputContext.rotationCenterBallroomPoint.y - (int)((inputContext.distance * cos(toRadians(angle))));
										feetCoord.a = angle;
									}
									break;
<commit_msg>Renamed winkel to angle.<commit_after>package de.sonumina.simpledance;

import static de.sonumina.simpledance.core.I18n._;
import static java.lang.Math.atan;
import static java.lang.Math.cos;
import static java.lang.Math.sin;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;

import java.util.LinkedList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ScrollBar;

import de.sonumina.simpledance.core.graphics.Point;
import de.sonumina.simpledance.core.graphics.Render;
import de.sonumina.simpledance.core.model.Pattern;
import de.sonumina.simpledance.core.model.Step;
import de.sonumina.simpledance.core.model.WayPoint;
import de.sonumina.simpledance.graphics.swt.SWTContext;

/**
 * @author <NAME>
 */
public class Ballroom extends Canvas
{
	enum Drag
	{
		NO,
		ROTATE_BALE,
		ROTATE_HEEL,
		MOVE_WAYPOINT
	}

	private SWTContext context;
	private Render render;

	private Color ballroomColor;
	private Color countColor;
	private Cursor cursor;
	private Menu contextMenu;
	private Font countFont;

	private int horizontalScrollbarSelection;
	private int verticalScrollbarSelection;

	private int bufferWidth = -1;
	private int bufferHeight = -1;
	private Image bufferImage;
	private GC bufferGC;

	private Pattern pattern;
	private int zoomFactor = 300;
	private int rotation = 0;
	private int visibleLeft = 570;
	private int visibleTop = 650;
	private int coordinatesX = -1;
	private int coordinatesY = -1;
	private boolean showAnimationOutline = false;
	private boolean showNextStep = false;
	private boolean showPrevStep = false;
	private boolean showGent = true;
	private boolean showLady = true;
	private boolean showCoordinates = true;
	private boolean showGrid = true;
	private boolean showGradients = true;

	private int contextFeetIndex;
	private int contextStepIndex;

	private static class InputContext
	{
		public int selectedStep = -1;
		public int selectedFoot = -1;
		public int selectedWaypoint = -1;
		public boolean mousePressed = false;
		private Drag dragOperation;
		private Point rotationCenterBallroomPoint;
		private int distance;
	}
	private InputContext inputContext = new InputContext();

	private boolean [] selectedArray = new boolean[4];
	
	/* attributes used when painting */
	private boolean animation;
	private boolean animationSingleStep;
	private boolean animationBackward;
	private int animationDrawnSteps;
	private int animationNumber;
	private int animationMaxNumber;

	private LinkedList<BallroomListener> ballroomListenerList = new LinkedList<>();

	private int calculateBallroomAngle(int mx, int my, int x, int y)
	{
		int angle;
		
		if (x < mx)
		{
			if (my != y)
			{
				double t = (mx - x)/(double)(y - my);
				angle = (int)toDegrees(atan(t));
				if (my > y) angle = 180 + angle; 				
			} else angle = 90;
		} else
		if (x > mx)
		{
			if (my != y)
			{
				double t = (mx - x)/(double)(my - y);
				angle = (int)toDegrees(atan(t));
				if (my > y) angle = 180 - angle;
				else angle = 360 - angle; 				
			} else angle = 270;
		} else 
		{
			if (y < my) angle = 180;
			else angle = 0;
		}

		if (angle >= 360) angle -= 360;
		else if (angle < 0) angle += 360 * ((-angle + 359)/360);

		return angle;
	}

	public int calculatePixelAngle(int mx, int my, int x, int y)
	{
		int angle = 180 - calculateBallroomAngle(mx,my,x,y);
		if (angle >= 360) angle -= 360;
		else if (angle < 0) angle += 360 * ((-angle + 359)/360);
		return angle;
	}

	/**
	 * Returns the current scene parameters relevant for rendering.
	 *
	 * @return the scene parameters.
	 */
	private Render.RenderSceneArgs getRenderSceneArgs()
	{
		Render.RenderSceneArgs rsa = new Render.RenderSceneArgs();
		rsa.pattern = pattern;
		rsa.stepNumber = pattern.getCurrentStepNum();
		int visibleWidth = getClientArea().width * 100 / zoomFactor;
		int visibleHeight = getClientArea().height * 100 / zoomFactor;
		rsa.visibleLeftTop = new Point(visibleLeft, visibleTop);
		rsa.visibleRightTop = rsa.visibleLeftTop.add(new Point(visibleWidth, 0).rotate(rotation));
		rsa.visibleLeftBottom = rsa.visibleLeftTop.add(new Point(0, -visibleHeight).rotate(rotation));
		rsa.visibleRightBottom = rsa.visibleLeftTop.add(new Point(visibleWidth, -visibleHeight).rotate(rotation));
		rsa.visibleRotation = rotation;
		rsa.pixelWidth = getClientArea().width;
		rsa.pixelHeight = getClientArea().height;

		rsa.showGrid = showGrid;
		rsa.showPrevStep = showPrevStep;
		rsa.showGradients = showGradients;
		rsa.showPrevStep = showPrevStep;
		rsa.insideAnimation = animation;
		rsa.animationNumber = animationNumber;
		rsa.animationMaxNumber = animationMaxNumber;
		rsa.showLady = showLady;
		rsa.showGent = showGent;
		rsa.showAnimationOutline = showAnimationOutline;
		for (int i=0;i<4;i++) rsa.selectedArray[i] = selectedArray[i];
		return rsa;
	}

	private void createImageBuffer()
	{
		if (bufferImage != null)
		{
			if (bufferWidth != getClientArea().width || 
				bufferHeight != getClientArea().height)
			{
				bufferGC.dispose();
				bufferGC = null;
				bufferImage.dispose();
				bufferImage = null;
			}
		}
				
		if (bufferImage == null)
		{
			bufferImage = new Image(getDisplay(),getClientArea().width,getClientArea().height);
			bufferGC = new GC(bufferImage);
			bufferWidth = getClientArea().width;
			bufferHeight = getClientArea().height;
			context.setGC(bufferGC);
		}
	}
	
	public void dispose()
	{
		super.dispose();

		ballroomColor.dispose();
		countFont.dispose();
		countColor.dispose();
		bufferGC.dispose();
		bufferImage.dispose();
		render.dispose();
		context.dispose();
	}
	
	public Ballroom(Composite comp, int style)
	{
		/* Note since we use a border our client area is proably different */
		super(comp,style|SWT.NO_BACKGROUND|SWT.V_SCROLL|SWT.H_SCROLL|SWT.BORDER);

		context = new SWTContext(getDisplay());
		render = new Render(context);
		
		ballroomColor = new Color(getDisplay(),240,240,200);
		
		countColor = new Color(getDisplay(),255,255,255);
		countFont = new Font(getDisplay(),"Thorndale",20,0);

		SelectionListener selectionListener = new SelectionListener()
		{
			public void widgetSelected(SelectionEvent event)
			{
				ScrollBar scrollbar = (ScrollBar)(event.widget);
				Point diff;
				if ((scrollbar.getStyle() & SWT.V_SCROLL) != 0)
				{
					diff = new Point(0, verticalScrollbarSelection - scrollbar.getSelection()).rotate(rotation);
					verticalScrollbarSelection = scrollbar.getSelection();
				} else
				{
					diff = new Point(scrollbar.getSelection() - horizontalScrollbarSelection, 0).rotate(rotation);
					horizontalScrollbarSelection = scrollbar.getSelection();
				}
				visibleLeft += diff.x;
				visibleTop += diff.y;

				redraw();
				update();
			}
			public void widgetDefaultSelected(SelectionEvent event) {}
		};
		
		
		ScrollBar scrollbar = getVerticalBar();
		scrollbar.setMaximum(1199); 
		scrollbar.setMinimum(0);
		scrollbar.setIncrement(1);
		scrollbar.setSelection(1200 - visibleTop);
		scrollbar.addSelectionListener(selectionListener);
		verticalScrollbarSelection = scrollbar.getSelection();
		
		scrollbar = getHorizontalBar();
		scrollbar.setMaximum(1199); 
		scrollbar.setMinimum(0);
		scrollbar.setIncrement(1);
		scrollbar.setSelection(visibleLeft);
		scrollbar.addSelectionListener(selectionListener);
		horizontalScrollbarSelection = scrollbar.getSelection();
		
		addControlListener(new ControlAdapter()
		{
			public void controlResized(ControlEvent event)
			{
				refreshScrollBars();
			}
		});

		addPaintListener(new PaintListener()
		{
			public void paintControl(PaintEvent e)
			{
				createImageBuffer();
				GC gc = bufferGC;

				render.renderScence(getRenderSceneArgs());

				if (pattern != null)
				{
					if (showCoordinates)
					{
						if (coordinatesX != -1 && coordinatesY != -1)
						{
							StringBuffer buf = new StringBuffer();
							buf.append(coordinatesX);
							buf.append(" ");
							buf.append(coordinatesY);
							buf.append("   ");
							gc.setBackground(ballroomColor);
							gc.setFont(null);
							gc.drawText(buf.toString(),4,2);
						}
					}

					if (animation && pattern.getCurrentStep() != null)
					{
						String count = pattern.getCurrentStep().getCount();
						if (count != null)
						{
							gc.setBackground(ballroomColor);
							gc.setFont(countFont);
							org.eclipse.swt.graphics.Point p = gc.textExtent(count);
							gc.setForeground(countColor);
							gc.drawText(count,getClientArea().x + getClientArea().width - 1 - p.x - 20,2);
						}
					}
				}
				

				e.gc.drawImage(bufferImage,getClientArea().x,getClientArea().y);
			}
		});
		
		
		addMouseMoveListener(new MouseMoveListener()
		{
			public void mouseMove(MouseEvent event)
			{
				Point ballroomPoint = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
				if (coordinatesX != ballroomPoint.x || coordinatesY != ballroomPoint.y)
				{
					coordinatesX = ballroomPoint.x;
					coordinatesY = ballroomPoint.y;
					redraw();
					update();
				}

				if (inputContext.mousePressed && inputContext.dragOperation != Drag.NO)
				{
					if (inputContext.selectedFoot != -1)
					{
						switch (inputContext.dragOperation)
						{
							case	ROTATE_BALE:
									{
										Point p = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
										int angle = calculateBallroomAngle(
											inputContext.rotationCenterBallroomPoint.x,
											inputContext.rotationCenterBallroomPoint.y,
											p.x,p.y);
										WayPoint feetCoord = pattern.getStep(inputContext.selectedStep).getFoot(inputContext.selectedFoot).getStartingWayPoint();
										feetCoord.x = inputContext.rotationCenterBallroomPoint.x - (int)((inputContext.distance * sin(toRadians(angle))));
										feetCoord.y = inputContext.rotationCenterBallroomPoint.y + (int)((inputContext.distance * cos(toRadians(angle))));
										feetCoord.a = angle;
									}
									break;

							case	ROTATE_HEEL:
									{
										Point p = render.transformPixToBallroom(getRenderSceneArgs(), event.x, event.y);
										int angle = calculateBallroomAngle(
											inputContext.rotationCenterBallroomPoint.x,
											inputContext.rotationCenterBallroomPoint.y,
											p.x,p.y) - 180;
										if (angle < 0) angle += 360;
										WayPoint feetCoord = pattern.getStep(inputContext.selectedStep).getFoot(inputContext.selectedFoot).getStartingWayPoint();
										feetCoord.x = inputContext.rotationCenterBallroomPoint.x + (int)((inputContext.distance * sin(toRadians(angle))));
										feetCoord.y = inputContext.rotationCenterBallroomPoint.y - (int)((inputContext.distance * cos(toRadians(angle))));
										feetCoord.a = angle;
									}
									break;

{'fraction_non_alphanumeric': 0.11448406709499374, 'fraction_numerical': 0.011987408908628348, 'mean_word_length': 3.728236493374108, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, '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': '1217633', 'n_tokens_mistral': 9000, 'n_tokens_neox': 7177, 'n_words': 1507}