<commit_before>import * as utils from '../utils/utils';
import SVGUtils from '../utils/svgUtils';
import Circle from './Circle';
import Path from './Path';

/**
 * NOTES
 * - should separate Points into own class
 * - should generalise slopeController for every different 
 */

export default class PathData  {
	constructor(svg){

		this.$svg = svg;

		this.data = new utils.SortedArray([], function(a,b){		
	        if (a.x === b.x) {
	        	if (a.y === b.y){
	        		return 0
	        	}else{
	        		return a.y < b.y ? -1 : 1;
	        	}
	        }
	        return a.x < b.x ? -1 : 1;
		});
		this.logged = false;

		// this.onPointLeftClick = this.onPointLeftClick.bind(this);

	}

	/**
	 * Add an automation point to the controller
	 * @param {int} x x axis coordinate
	 * @param {int} y y axis coordinate
	 */
	addPoint(x, y, type = 'linear'){

		var point = new Circle({
			cx: x,
			cy: y,
			r: 6,
			fill: 'red',
		}, this.$svg);

		point.x = x;
		point.y = y;
		point.type = type;
		point.slope = 0;

		point.el.classList.add('automation-point');

		point.el.addEventListener('mousedown', (e) => {
			this.onPointLeftClick(e, point)	
		});
		point.el.addEventListener('contextmenu', (e) => {this.onPointRightClick(e, point);} )

		this.data.insert(point);

		this.redraw();
	}

	removePoint(point){

		if (point.el){
			point.el.remove();
		}
		if (point.path){
			point.path.el.remove();
		}
		if (point.slopeControl){
			point.slopeControl.el.remove();
		}
		this.data.remove(point);

		this.redraw();

	}

	/**
	 * Left mouse button click handler (changing position of automation points)
	 * @param  {Event} 	e 		default event passed from EventListenere
	 * @param  {Circle} point 	a Circle object on which the event is invoked
	 * @return {void} 
	 */
	onPointLeftClick(e, point){

		var self = this,
			selectedPoint = event.target,
			clickPos = SVGUtils.mousePos(e, this.$svg),
			posDiff = { 
				x: selectedPoint.getAttribute('cx') - clickPos.x,
				y: selectedPoint.getAttribute('cy') - clickPos.y
			};

		function dragHandler(e) {

			self.data.remove(point);

			var movePos = SVGUtils.mousePos(e, self.$svg),
				xPos = movePos.x + posDiff.x,
				yPos = movePos.y + posDiff.y;

			point.setOption('cx', xPos);
			point.setOption('cy', yPos);

			point.x = xPos;
			point.y = yPos;

			var newPoint = point;

			self.data.insert(newPoint);

			self.redraw();

		}

		function onMouseUp(){
			self.$svg.removeEventListener('mousemove', dragHandler);
			document.removeEventListener('mouseup', onMouseUp);<commit_msg>add first and last point guard<commit_after>import * as utils from '../utils/utils';
import SVGUtils from '../utils/svgUtils';
import Circle from './Circle';
import Path from './Path';

/**
 * NOTES
 * - should separate Points into own class
 * - should generalise slopeController for every different 
 */

export default class PathData  {
	constructor(svg){

		this.$svg = svg;

		this.data = new utils.SortedArray([], function(a,b){		
	        if (a.x === b.x) {
	        	if (a.y === b.y){
	        		return 0
	        	}else{
	        		return a.y < b.y ? -1 : 1;
	        	}
	        }
	        return a.x < b.x ? -1 : 1;
		});
		this.logged = false;

		// this.onPointLeftClick = this.onPointLeftClick.bind(this);

	}

	/**
	 * Add an automation point to the controller
	 * @param {int} x x axis coordinate
	 * @param {int} y y axis coordinate
	 */
	addPoint(x, y, type = 'linear'){

		var point = new Circle({
			cx: x,
			cy: y,
			r: 6,
			fill: 'red',
		}, this.$svg);

		point.x = x;
		point.y = y;
		point.type = type;
		point.slope = 0;

		point.el.classList.add('automation-point');

		point.el.addEventListener('mousedown', (e) => {
			this.onPointLeftClick(e, point)	
		});
		point.el.addEventListener('contextmenu', (e) => {this.onPointRightClick(e, point);} )

		var x = this.data.insert(point);

		this.redraw();
	}

	removePoint(point){

		if (point.el){
			point.el.remove();
		}
		if (point.path){
			point.path.el.remove();
		}
		if (point.slopeControl){
			point.slopeControl.el.remove();
		}
		this.data.remove(point);

		this.redraw();

	}

	/**
	 * Left mouse button click handler (changing position of automation points)
	 * @param  {Event} 	e 		default event passed from EventListenere
	 * @param  {Circle} point 	a Circle object on which the event is invoked
	 * @return {void} 
	 */
	onPointLeftClick(e, point){

		var self = this,
			selectedPoint = event.target,
			clickPos = SVGUtils.mousePos(e, this.$svg),
			posDiff = { 
				x: selectedPoint.getAttribute('cx') - clickPos.x,
				y: selectedPoint.getAttribute('cy') - clickPos.y
			};

		function dragHandler(e) {

			var pointLocation = self.data.search(point);

			self.data.remove(point);

			var movePos = SVGUtils.mousePos(e, self.$svg),
				xPos = movePos.x + posDiff.x,
				yPos = movePos.y + posDiff.y;

			// don't change the xPos for automation start and end
			if ( pointLocation != 0 && pointLocation < self.data.array.length){
				point.setOption('cx', xPos);
				point.x = xPos;
			}
			point.setOption('cy', yPos);
			point.y = yPos;

			var newPoint = point;

			self.data.insert(newPoint);

			self.redraw();

		}

		function onMouseUp(){
			self.$svg.removeEventListener('mousemove', dragHandler);
			document.removeEventListener('mouseup', onMouseUp);
{'fraction_non_alphanumeric': 0.15303430079155672, 'fraction_numerical': 0.0028269883151149644, 'mean_word_length': 2.7691761363636362, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 7, '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': '803946', 'n_tokens_mistral': 2115, 'n_tokens_neox': 1827, 'n_words': 447}