if (typeof Shot == 'undefined') {
	var Shot = {};
}

if (typeof Shot.widget == 'undefined') {
	Shot.widget = {};
}

(function () {

	var Dom     = YAHOO.util.Dom;
	var Event   = YAHOO.util.Event;
	var Anim    = YAHOO.util.Anim;
	var Connect = YAHOO.util.Connect;
	var JSON    = YAHOO.lang.JSON;

	Shot.widget.FeaturedPhotoPager = function(id, featuredPhotoId, photoId,
		uri, username, full_name, price, user_featured)
	{
		this.photos       = [];
		this.photo_ids    = {};
		this.id           = id;
		this.link         = document.getElementById(this.id + '_link');
		this.currentPhoto = 0;
		this.container    = document.getElementById(this.id);
		this.price_container    = document.getElementById(this.id + '_price');
		this.draw_next_prev = true;

		if (user_featured)
			this.user_featured = username;
		else
			this.user_featured = false;

		this.attributionLink = Dom.getElementsByClassName(
			'featured-photo-pager-attribution', 'a', this.container)[0];

		// add initial featured photo to list of featured photos
		var photo = new Shot.widget.FeaturedPhotoPagerPhoto(
			featuredPhotoId, photoId, uri, username, full_name, price);

		_appendPhoto.call(this, photo);

		_init.call(this);
	};

	var proto = Shot.widget.FeaturedPhotoPager.prototype;

	var _originalImage = null;
	var _currentImage = null;
	var _allPhotosLoaded = false;
	var _interval = null;

	Shot.widget.FeaturedPhotoPager.crossFadePeriod = 1.0; // in seconds
	Shot.widget.FeaturedPhotoPager.nextText = 'Next Photo';
	Shot.widget.FeaturedPhotoPager.prevText = 'Previous Photo';
	Shot.widget.FeaturedPhotoPager.photographerText = 'Photographer: %s';
	Shot.widget.FeaturedPhotoPager.loadThreshold = 0.75;
	Shot.widget.FeaturedPhotoPager.interval = 30000; // in milliseconds

	var _appendPhoto = function(photo)
	{
		var id = 'photo-' + photo.id.toString();
		if (typeof this.photo_ids[id] == 'undefined') {
			this.photos.push(photo);
			this.photo_ids[id] = photo.id;
			_drawNextPrev.call(this);
		}
	}

	var _prependPhoto = function(photo)
	{
		var id = 'photo-' + photo.id.toString();
		if (typeof this.photo_ids[id] == 'undefined') {
			this.photos.unshift(photo);
			this.currentPhoto++;
			this.photo_ids[id] = photo.id;
			_drawNextPrev.call(this);
		}
	}

	var _drawNextPrev = function(photos)
	{
		if (this.photos.length > 1 && this.draw_next_prev) {
			this.draw_next_prev = false;

			// draw prev link
			var prevLink = document.createElement('a');
			prevLink.appendChild(document.createTextNode(
				Shot.widget.FeaturedPhotoPager.prevText));

			prevLink.title = Shot.widget.FeaturedPhotoPager.prevText;
			prevLink.className = 'featured-photo-pager-prev';
			prevLink.href = '#';

			Event.on(prevLink, 'click', function (e) {
				Event.preventDefault(e);
				this.clearInterval();
				this.setInterval();
				this.previousPhoto();
			}, this, true);

			this.container.appendChild(prevLink);

			// draw next link
			var nextLink = document.createElement('a');
			nextLink.appendChild(document.createTextNode(
				Shot.widget.FeaturedPhotoPager.nextText));

			nextLink.title = Shot.widget.FeaturedPhotoPager.nextText;
			nextLink.className = 'featured-photo-pager-next';
			nextLink.href = '#';

			Event.on(nextLink, 'click', function (e) {
				Event.preventDefault(e);
				this.clearInterval();
				this.setInterval();
				this.nextPhoto();
			}, this, true);

			this.container.appendChild(nextLink);
		}
	}

	var _init = function()
	{
		_originalImage = document.getElementById(this.id + '_image');


		_loadMorePhotos.call(this, 'middle');
		this.setInterval();
	}

	var _crossFadePhoto = function(photo)
	{
		var lastImage = _currentImage;

		var image       = document.createElement('img');
		image.src       = photo.uri;
		image.width     = _originalImage.width;
		image.height    = _originalImage.height;

		Dom.setStyle(image, 'opacity', 0);
		image.style.position = 'absolute';

		_currentImage = image;

		this.link.appendChild(image);
		var xy = Dom.getXY(_originalImage);
		Dom.setXY(image, xy);

		var animation = new Anim(image,
			{ opacity: { to: 1 } },
			Shot.widget.FeaturedPhotoPager.crossFadePeriod);

		_setPhotoAttribution.call(this, photo);

		if (this.user_featured) {
			var photo_href = 'photo' + photo.photo_id;
		} else {
			var photo_href = photo.username + '/photo' + photo.photo_id;
		}

		this.link.href = photo_href;
		this.price_container.href = photo_href;
		this.price_container.innerHTML = photo.price;

		animation.onComplete.subscribe(function()
		{
			if (lastImage) {
				lastImage.style.display = 'none';
				lastImage.parentNode.removeChild(lastImage);
			}
		}, this, true);

		animation.animate();
	};

	var _setPhotoAttribution = function(photo)
	{
		if (!this.attributionLink)
			return;

		var text = Shot.widget.FeaturedPhotoPager.photographerText.replace(
			/%s/, photo.full_name);

		while (this.attributionLink.firstChild) {
			this.attributionLink.removeChild(this.attributionLink.firstChild);
		}

		this.attributionLink.appendChild(document.createTextNode(text));
		this.attributionLink.href = photo.username;
	};

	var _loadMorePhotos = function(position)
	{
		if (position != 'prev' && position != 'next' && position != 'middle') {
			position = 'middle';
		}

		if (this.photos.length < 10) {
			var limit = 10;
		} else {
			var limit = this.photos.length * 2;
		}

		var excludeIds = [];
		for (var i = 0; i < this.photos.length; i++) {
			excludeIds.push(encodeURIComponent(this.photos[i].id));
		}

		// remove duplicates (which shouldn't exist)
		excludeIds.sort();
		current = null;
		for (var i = 0; i < excludeIds.length; i++) {

			// check if it is a duplicate
			if (current === excludeIds[i]) {
				excludeIds.splice(i, 1);
				i--;
			}

			current = excludeIds[i];
		}

		excludeIds = excludeIds.join(',');

		var callback =
		{
			success: function(o)
			{
				try {
					var photos = JSON.parse(o.responseText);
				} catch (e) {
					var photos = [];
				}

				if (photos.length == 0) {
					_allPhotosLoaded = true;
				}

				for (var i = 0; i < photos.length; i++) {
					var photo = new Shot.widget.FeaturedPhotoPagerPhoto(
						photos[i].id,
						photos[i].photo_id,
						photos[i].uri,
						photos[i].username,
						photos[i].full_name,
						photos[i].price);

					switch (position) {
					case 'prev':
						_prependPhoto.call(this, photo);
						break;

					case 'next':
						_appendPhoto.call(this, photo);
						break;

					default:
					case 'middle':
						if (i % 2 == 0) {
							_appendPhoto.call(this, photo);
						} else {
							_prependPhoto.call(this, photo);
						}
						break;
					}
				}
			},
			failure: function(o)
			{
			},
			argument: [],
			scope: this
		};

		var post_data = 'exclude_ids=' + excludeIds + '&limit=' + limit;

		if (this.user_featured) {
			post_data += '&username=' + this.user_featured;

			Connect.asyncRequest('POST', 'api/json/user-featured',
				callback, post_data);
		} else {
			Connect.asyncRequest('POST', 'api/json/featured',
				callback, post_data);
		}
	};

	var _getNextPhoto = function()
	{
		this.currentPhoto++;

		if (!_allPhotosLoaded && this.currentPhoto / this.photos.length >
			Shot.widget.FeaturedPhotoPager.loadThreshold) {
			_loadMorePhotos.call(this, 'next');
		}

		if (this.currentPhoto > this.photos.length - 1) {
			this.currentPhoto = 0;
		}

		return this.photos[this.currentPhoto];
	};

	var _getPreviousPhoto = function()
	{
		this.currentPhoto--;

		if (!_allPhotosLoaded && this.currentPhoto / this.photos.length <
			(1 - Shot.widget.FeaturedPhotoPager.loadThreshold)) {
			_loadMorePhotos.call(this, 'prev');
		}

		if (this.currentPhoto < 0) {
			this.currentPhoto = this.photos.length - 1;
		}

		return this.photos[this.currentPhoto];
	};

	proto.previousPhoto = function()
	{
		var photo = _getPreviousPhoto.call(this);
		_crossFadePhoto.call(this, photo);
	};

	proto.nextPhoto = function()
	{
		var photo = _getNextPhoto.call(this);
		_crossFadePhoto.call(this, photo);
	};

	proto.setInterval = function()
	{
		// set up next-photo interval
		var that = this;
		_interval = setInterval(function()
			{
				that.nextPhoto();
			}, Shot.widget.FeaturedPhotoPager.interval);
	};

	proto.clearInterval = function()
	{
		if (_interval) {
			clearInterval(_interval);
		}
	};

	Shot.widget.FeaturedPhotoPagerPhoto = function(id, photo_id, uri,
		username, full_name, price)
	{
		this.id        = id;
		this.photo_id  = photo_id;
		this.uri       = uri;
		this.username  = username;
		this.full_name = full_name;
		this.price     = price;

		// preload featured photo image
		if (!Shot.widget.FeaturedPhotoPagerPhoto.images[uri]) {
			var image = new Image();
			image.src = uri;
			Shot.widget.FeaturedPhotoPagerPhoto.images[uri] = image;
		}
	};

	Shot.widget.FeaturedPhotoPagerPhoto.images = {};

	var proto = Shot.widget.FeaturedPhotoPagerPhoto.prototype;

})();
