define(function() {
	"use strict";

	function Spinner(parent) {
		this.container = document.createElement('div');
		this.parent = parent || document.body;
		this.el = document.createElement('div');
		this.spinner = document.createElement('div');
		this.text = document.createElement('div');
		this.diameter = 30;
		this.animation = null;
	}

	Spinner.prototype = {
		init: function() {
			this.spinner.className = 'loader-spinner';
			this.spinner.style.display = 'inline-block';
			this.spinner.style.border = this.diameter / 4 + 'px solid #f3f3f3';
			this.spinner.style.borderTopColor = '#3498db';
			this.spinner.style.borderRadius = '50%';
			this.spinner.style.width = this.diameter + 'px';
			this.spinner.style.height = this.diameter + 'px';
			this.text.className = 'loader-text';
			this.text.innerHTML = 'Loading...';
			this.text.style.marginTop = '8px';
			this.el.className = 'loader';
			this.el.style.textAlign = 'center';
			this.el.style.position = 'absolute';
			this.el.style.top = '50%';
			this.el.style.left = '50%';
			this.el.style.transform = 'translate(-50%, -50%)';
			this.el.appendChild(this.spinner);
			this.el.appendChild(this.text);
			this.container.className = 'loader-container';
			this.container.style.height = this.parent.scrollHeight + 'px';
			this.container.style.position = 'relative';
			this.container.appendChild(this.el);
			this.parent.appendChild(this.container);
			this.start();
		},

		start: function() {
			var deg = 0;
			var unit = 10;

			(function spin() {
				this.spinner.style.transform = 'rotate(' + (deg += unit) + 'deg)';
				this.animation = requestAnimationFrame(spin.bind(this));
			}.bind(this))();
		},

		stop: function() {
			cancelAnimationFrame(this.animation);
			this.container.style.display = 'none';
		}
	};

	return {
		construct: function(parent) {
			return new Spinner(parent);
		}
	};
});