define([
	'jquery',
	'plugins/spinner',
], function($) {
	function Preview(container, id) {
		var _this = this;
		this.event = $({});
		this.id = id;
		this.page = 1;
		this.container = container;
		this.iframe = container.find('iframe');
		this.controls = container.find('.preview_controls');

		this.spinner = $('<div />').css({position: 'absolute', width: '100%', height: '100%'}).spinner({ colour: '100,100,100' }).hide();

		this.error = $('.preview_error');
		this.container.prepend(this.spinner);

		window.addEventListener('message', function(event) {
			if (event.origin !== document.location.origin) return;
			switch (event.data.type) {
				case 'loaded':
					_this.spinner.hide();
					break;
				case 'scroll':
					_this.event.trigger('preview:scroll', event.data);
					break;
			}
		}, false);
	}
	Preview.prototype.load = function(score) {
		var _this = this;
		this.spinner.show();
		this.error.hide();
		this.resize();
		score.id = this.id;
		$.post('/prepare_preview', score, function(response) {
			_this.handleResponse(response);
		}, 'json');
	};
	Preview.prototype.handleResponse = function(data) {
		var _this = this;
		if (data.error) {
			this.spinner.hide();
			this.error.show().find('.message').text(data.error);
			this.resize();
			return false;
		}
		this.cacheBuster = '?t=' + new Date().getTime();
		this.id = data.id;
		this.setPdfSrc();
	};
	Preview.prototype.setPdfSrc = function() {
		var msg = {
			id: this.id,
			url: 'https://s3-us-west-2.amazonaws.com/lilybin-scores/' + this.id + '.pdf' + this.cacheBuster
		};
		this.iframe[0].contentWindow.postMessage(
			msg,
			document.location.origin
		);
	};
	Preview.prototype.resize = function() {
		this.iframe.css({
			height: this.container.height() - this.error[0].offsetHeight + 'px'
		});
	};
	return Preview;
});

@@ -1058,16 +1058,559 @@
  'json')
+.fail(function(jqXHR, textStatus, errorThrown) %7B%0A%09%09%09switch (textStatus) %7B%0A%09%09%09%09case 'error':%0A%09%09%09%09%09error = 'Connection failed: ' + jqXHR.status;%0A%09%09%09%09%09error += ' ' + jqXHR.statusText;%0A%09%09%09%09%09break;%0A%09%09%09%09case 'timeout':%0A%09%09%09%09%09error = 'Connection timeout: ' + errorThrown;%0A%09%09%09%09%09break;%0A%09%09%09%09case 'abort':%0A%09%09%09%09%09error = 'Connection aborted: ' + errorThrown;%0A%09%09%09%09%09break;%0A%09%09%09%09case 'parsererror':%0A%09%09%09%09%09error = 'Unable to parse response:%5Cn' + errorThrown;%0A%09%09%09%09%09error += '%5CnResponse:%5Cn' + jqXHR.responseText;%0A%09%09%09%7D%0A%09%09%09_this.handleResponse(%7B error: error %7D);%0A%09%09%7D)
 ;%0A%09%7D;%0A%09P

Handle prepare_preview errors