/* global define */
/* eslint-env node, mocha */
(function() {

	var relativeTimeRe = /([-+<>])(\d*)\s*(minutes|minute|min|Min|Minute|Minutes|hr|Hr|hours|hour|Hour|Hours|days|day|Days|Day|weeks|week|Week|Weeks|isoWeek|months|month|mon|Month|Months|years|year|Year|Years|Quarters|Quarter|seconds|second|Seconds|Second|sec|s|m|h|d|D|M|y|Y|q|Q|Qr|qr|ms|w|wk|Wk)\s*/g,
		initialize,
		convertCase;

	convertCase = ({
		'ms': 'milliseconds',
		's': 'seconds',
		'sec': 'seconds',
		'second': 'seconds',
		'seconds': 'seconds',
		'Second': 'seconds',
		'Seconds': 'seconds',
		'm': 'minutes',
		'min': 'minutes',
		'minute': 'minutes',
		'minutes': 'minutes',
		'Min': 'minutes',
		'Minute': 'minutes',
		'Minutes': 'minutes',
		'h': 'hours',
		'hr': 'hours',
		'Hr': 'hours',
		'hour': 'hours',
		'hours': 'hours',
		'Hour': 'hours',
		'Hours': 'hours',
		'd': 'days',
		'D': 'days',
		'day': 'days',
		'days': 'days',
		'Day': 'days',
		'Days': 'days',
		'w': 'weeks',
		'W': 'weeks',
		'wk': 'weeks',
		'Wk': 'weeks',
		'week': 'weeks',
		'weeks': 'weeks',
		'Week': 'weeks',
		'Weeks': 'weeks',
		'isoWeek': 'isoWeek',
		'M': 'months',
		'mon': 'months',
		'month': 'months',
		'months': 'months',
		'Month': 'months',
		'Months': 'months',
		'y': 'years',
		'Y': 'years',
		'yr': 'years',
		'yrs': 'years',
		'year': 'years',
		'years': 'years',
		'Year': 'years',
		'Years': 'years',
		'q': 'quarters',
		'qr': 'quarters',
		'Q': 'quarters',
		'Qr': 'quarters',
		'qtr': 'quarters',
		'quarter': 'quarters',
		'quarters': 'quarters',
		'Quarter': 'quarters',
		'Quarters': 'quarters'
	});

	initialize = function(moment) {

		moment.fn.relativeTime = function(relativeTimeString) {
			var m = moment(this);

			var relativeTimeString = relativeTimeString.trim();

			var result;
			relativeTimeRe.lastIndex = 0;
			while ((result = relativeTimeRe.exec(relativeTimeString)) !== null) {
				if (result[1] === '-')
					m = m.subtract(result[2] ? result[2] : 1, convertCase[result[3]]);
				if (result[1] === '+')
					m = m.add(result[2] ? result[2] : 1, convertCase[result[3]]);
				if (result[1] === '<')
					m = m.startOf(convertCase[result[3]]);
				if (result[1] === '>')
					m = m.endOf(convertCase[result[3]]);
			}
			return m;
		};

		moment.fn.isRelativeTimeFormat = function(relativeTimeString) {
			relativeTimeString = relativeTimeString.trim();
			if (relativeTimeString === 'now') {
				return true;
			}
			return relativeTimeRe.test(relativeTimeString);
		};

		return moment;
	};

	if (typeof define === 'function' && define.amd) {
		define('moment-relative-time', ['moment'], function(moment) {
			return initialize(moment);
		});
	} else if (typeof module !== 'undefined') {
		module.exports = initialize(require('moment'));
	} else if (typeof window !== 'undefined' && window.moment) {
		this.moment = initialize(this.moment);
	}

}).call(this);
