[Back]
import $ from 'jquery';

const $wnd = $(window);

/**
 * Check if lines cross
 *
 * @param {Object} a - first point of the first line
 * @param {Object} b - second point of the first line
 * @param {Object} c - first point of the second line
 * @param {Object} d - second point of the second line
 *
 * @return {boolean} cross lines
 */
function isCrossLine(a, b, c, d) {
	// Working code #1:
	//
	// var common = (b.x - a.x)*(d.y - c.y) - (b.y - a.y)*(d.x - c.x);
	// if (common === 0) {
	//     return false;
	// }
	//
	// var rH = (a.y - c.y)*(d.x - c.x) - (a.x - c.x)*(d.y - c.y);
	// var sH = (a.y - c.y)*(b.x - a.x) - (a.x - c.x)*(b.y - a.y);
	//
	// var r = rH / common;
	// var s = sH / common;
	//
	// return r >= 0 && r <= 1 && s >= 0 && s <= 1;

	// Working code #2:
	const v1 = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);
	const v2 = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);
	const v3 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
	const v4 = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);
	return v1 * v2 <= 0 && v3 * v4 <= 0;
}

// Init Events.
$(document).on('initEvents.vpf', (event, self) => {
	if (event.namespace !== 'vpf' || self.options.itemsStyle !== 'fly') {
		return;
	}

	const evp = `.vpf-uid-${self.uid}`;

	// determine cursor position
	let lastCursorPos = {};
	$wnd.on(`mousemove${evp}`, (e) => {
		lastCursorPos = {
			x: e.clientX,
			y: e.clientY,
		};
	});

	self.$item.on(
		`mouseenter${evp} mouseleave${evp}`,
		'.vp-portfolio__item',
		function (e) {
			const $this = $(this);
			const itemRect = $this[0].getBoundingClientRect();
			const $overlay = $this.find('.vp-portfolio__item-overlay');
			const enter = e.type === 'mouseenter';
			let endX = '0%';
			let endY = '0%';
			const curCursorPos = {
				x: e.clientX,
				y: e.clientY,
			};

			// find the corner that placed on cursor path.
			let isUp = isCrossLine(
				{ x: itemRect.left, y: itemRect.top },
				{ x: itemRect.left + itemRect.width, y: itemRect.top },
				curCursorPos,
				lastCursorPos
			);
			let isDown = isCrossLine(
				{ x: itemRect.left, y: itemRect.top + itemRect.height },
				{
					x: itemRect.left + itemRect.width,
					y: itemRect.top + itemRect.height,
				},
				curCursorPos,
				lastCursorPos
			);
			let isLeft = isCrossLine(
				{ x: itemRect.left, y: itemRect.top },
				{ x: itemRect.left, y: itemRect.top + itemRect.height },
				curCursorPos,
				lastCursorPos
			);
			let isRight = isCrossLine(
				{ x: itemRect.left + itemRect.width, y: itemRect.top },
				{
					x: itemRect.left + itemRect.width,
					y: itemRect.top + itemRect.height,
				},
				curCursorPos,
				lastCursorPos
			);

			// Sometimes isCrossLine returned false, so we need to check direction manually (less accurate, but it is not a big problem).
			if (!isUp && !isDown && !isLeft && !isRight) {
				const x =
					(itemRect.width / 2 - curCursorPos.x + itemRect.left) /
					(itemRect.width / 2);
				const y =
					(itemRect.height / 2 - curCursorPos.y + itemRect.top) /
					(itemRect.height / 2);
				if (Math.abs(x) > Math.abs(y)) {
					if (x > 0) {
						isLeft = true;
					} else {
						isRight = true;
					}
				} else if (y > 0) {
					isUp = true;
				} else {
					isDown = true;
				}
			}

			if (isUp) {
				endY = '-100.1%';
			} else if (isDown) {
				endY = '100.1%';
			} else if (isLeft) {
				endX = '-100.1%';
			} else if (isRight) {
				endX = '100.1%';
			}

			if (enter) {
				$overlay.css({
					transition: 'none',
					transform: `translateX(${endX}) translateY(${endY}) translateZ(0)`,
				});
				// Trigger a reflow, flushing the CSS changes. This need to fix some glitches in Safari and Firefox.
				// Info here - https://stackoverflow.com/questions/11131875/what-is-the-cleanest-way-to-disable-css-transition-effects-temporarily
				// eslint-disable-next-line no-unused-expressions
				$overlay[0].offsetHeight;
			}

			$overlay.css({
				transition: '.2s transform ease-in-out',
				transform: `translateX(${enter ? '0%' : endX}) translateY(${
					enter ? '0%' : endY
				}) translateZ(0)`,
			});
		}
	);
});

// Destroy Events.
$(document).on('destroyEvents.vpf', (event, self) => {
	if (event.namespace !== 'vpf' || self.options.itemsStyle !== 'fly') {
		return;
	}

	const evp = `.vpf-uid-${self.uid}`;

	$wnd.off(`mousemove${evp}`);
	self.$item.off(`mouseenter${evp} mouseleave${evp}`);
});