;(function (root, factory)
{
	if (typeof define === 'function' && define.amd)
	{
		define([], factory);
	}
	else if (typeof exports === 'object')
	{
		module.exports = factory();
	}
	else
	{
		root.haversine = factory();
	}
}(this, function ()
{
	'use strict';

	const earth = {
		MILE: 3959,
		KM: 6371,
		M: 6371000,
		NMI: 3440
	};

	function haversine(start, end, options)
	{
		options = defaults(options);

		const startLatitude = getRadians(start.latitude, options.isRadians);
		const endLatitude = getRadians(end.latitude, options.isRadians);
		const longitudeDelta = coordinateDifference(start.longitude, end.longitude, options.isRadians);

		const c = Math.acos(Math.sin(startLatitude) * Math.sin(endLatitude) + Math.cos(startLatitude) * Math.cos(endLatitude) * Math.cos(longitudeDelta));

		return options.radius * c;
	}

	function coordinateDifference(a, b, isRadians)
	{
		const delta = b - a;
		return getRadians(delta, isRadians);
	}

	function getRadians(input, isRadians)
	{
		return isRadians ? input : (input * (Math.PI / 180));
	}

	function defaults(options)
	{
		options = options || {};
		options.radius = options.radius || earth.M;
		options.isRadians = (typeof options.isRadians === 'boolean') ? options.isRadians : false;

		return options;
	}

	return haversine;
}));

