/**
 * @author Vlad Yakovlev (red.scorpix@gmail.com)
 * @link www.scorpix.ru
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @version 0.2.10
 * @date 2009-12-15
 * @requires jQuery
 * @requires uGallery
 */

/**
 * @param {String|Element|jQuery} previewEl
 * @param {String|Element|jQuery} viewEl
 * @param {Number} imageId
 * @param {String} ajaxUrl
 * @param {String} ajaxParams
 */
function gallery(previewEl, viewEl, imageId, galleryId, ajaxUrl, ajaxParams) {
	previewEl = $(previewEl);

	var core = uGallery.core({
		previewEl: previewEl,
		previewContainerEl: previewEl.find('.container'),
		previewContentEl: previewEl.find('.content'),
		previewPicturesEl: previewEl.find('.pictures'),
		eventDispatcher: uGallery.eventDispatcher(),
		viewEl: $(viewEl),
		preloaderWidth: previewEl.find('.preloader').innerWidth()
	});

	core.loader = uGallery.ajaxLoader(core, {
		ajaxUrl: ajaxUrl,
		ajaxParams: ajaxParams,
		imageId: imageId,
		galleryId: galleryId
	});

	galleryPictures(core);
	galleryInfoChanger(core);

	//uGallery.previewRunner(core);
	uGallery.pictures(core)
	uGallery.previewArrowScrolling(core);
	uGallery.previewDnd(core);
	uGallery.previewMover(core);
	uGallery.previewPreloader(core);
	//var uGalleryHistory = uGallery.history(core, { firstId: imageId });
	//var firstImageId = uGalleryHistory.getId();

	uGallery.state(core, imageId, {
		maxHeight: 100,
		maxWidth: 150,
		margin: 4,
		screens: 0
	});
	return {
		pause: function() {
			core.eventDispatcher.dispatch('pause');
		},
		resume: function() {
			core.eventDispatcher.dispatch('resume');
		}
	};
}

/**
 * Управление информацией о текущей фотографии.
 * @param {uGallery.Core} core Ядро галереи.
 */
function galleryInfoChanger(core) {

	var infoEl = $('.picture_info');

	core.eventDispatcher.bind('imageSelected', function(evt) {
		update($(evt.data.imageInfo.info));
	});

	function update(info) {
		infoEl.text(info.find('description').text());
	}
}

/**
 * @param {uGallery.core} core
 * @param {Object} [animateParams] Параметры анимации для jTweener'а.
 */
function galleryPictures(core, animateParams) {
	var
		tweenNsPrev = 'uGalleryPicturePrev' + Math.random(),
		tweenNsNext = 'uGalleryPictureNext' + Math.random();

	animateParams = $.extend({}, { time: .6 }, animateParams);

	var defaultCss = {
		height: '',
		left: '',
		opacity: '',
		position: '',
		top: '',
		width: ''
	};

	var currentIndex;

	jTweener.addNSAction({ onComplete: onPrevComplete }, tweenNsPrev);
	jTweener.addNSAction({ onComplete: onNextComplete }, tweenNsNext);
	core.viewEl.find('a.picture').click(onPictureClick);
	core.eventDispatcher.bind('previewClick', change);

	function onPictureClick(evt) {
		if (core.busy() || core.animated()) return false;

		evt.preventDefault();
		evt.stopPropagation();

		var isPrev = false;

		if ($(this).parent().hasClass('prev')) {
			isPrev = true;
		} else if (!$(this).parent().hasClass('next')) {
			return false;
		}

		var newIndex = isPrev ? core.loader.selectedIndex() - 1 : core.loader.selectedIndex() + 1;
		
		changeImage({
			current: core.loader.item(newIndex),
			prev: core.loader.item(newIndex - 1),
			next: core.loader.item(newIndex + 1)
		}, isPrev);

		return false;
	}

	function changeImage(imageData, isPrev) {

		core.animated(true);
		core.busy(true);

		var
			oldClass = isPrev ? 'next' : 'prev',
			newClass = isPrev ? 'prev' : 'next',

			rootBlockOffset = core.viewEl.offset(),

			/** Изображение, которое было главным. */
			oldCurImageData = isPrev ? imageData.next : imageData.prev,
			oldCurEl = core.viewEl.find('.current'),
			oldCurPicEl = oldCurEl.find('.picture'),
			oldCurImgEl = oldCurPicEl.find('img'),
			oldCurOffset = oldCurEl.offset(),
			oldCurImgOffset = oldCurPicEl.offset(),
			oldCurWidth1 = oldCurEl.width(),
			oldCurHeight1 = Math.round(oldCurWidth1 / oldCurImageData.image.width * oldCurImageData.image.height),

			/** Изображение, которое станет главным. */
			newCurImageData = imageData.current,
			newCurEl = core.viewEl.find('.' + newClass),
			newCurPicEl = newCurEl.find('.picture'),
			newCurImgEl = newCurPicEl.find('img'),
			newCurOffset = newCurEl.offset(),
			newCurImgOffset = newCurPicEl.offset(),
			newCurWidth1 = newCurEl.width(),
			newCurHeight1 = Math.round(newCurWidth1 / newCurImageData.image.width * newCurImageData.image.height),

			/** Изображение, которое исчезнет. */
			oldEl = core.viewEl.find('.' + oldClass),
			oldPicEl = oldEl.find('.picture'),
			oldImgEl = oldPicEl.find('img'),
			oldOffset = oldEl.offset(),
			oldImgOffset = oldPicEl.offset(),
			oldWidth1 = oldEl.width(),
			oldHeight1 = oldEl.height(),

			/** Изображение, которое появится. */
			newImageData = isPrev ? imageData.prev : imageData.next,
			newImgEl = createTempBlock(newImageData, !isPrev),
			newHeight2 = newImageData ? newCurWidth1 / newImageData.image.width * newImageData.image.height : 0,

			newCurHeight2 = Math.round(oldCurWidth1 / newCurImageData.image.width * newCurImageData.image.height),
			oldCurHeight2 = Math.round(oldWidth1 / oldCurImageData.image.width * oldCurImageData.image.height);

		oldCurPicEl.height(oldCurHeight1 > newCurHeight2 ? oldCurHeight1 : newCurHeight2);
		newCurPicEl.height(newCurHeight1 > newHeight2 ? newCurHeight1 : newHeight2);
		oldPicEl.height(oldHeight1 > oldCurHeight2 ? oldHeight1 : oldCurHeight2);

		core.viewEl.find('.picture img').css('position', 'absolute');
		oldImgEl.css({
			top: Math.round(oldImgOffset.top - oldOffset.top)
		});
		oldCurImgEl.css({
			top: Math.round(oldCurImgOffset.top - oldCurOffset.top)
		});
		newCurImgEl.css({
			top: Math.round(newCurImgOffset.top - newCurOffset.top)
		});
		newImgEl.css({
			top: Math.round(newCurImgOffset.top - newCurOffset.top)
		});

		$t(oldCurImgEl, animateParams).tween( {
			left: Math.round(oldOffset.left - oldCurImgOffset.left),
			top: Math.round(oldImgOffset.top - oldOffset.top),
			width: oldWidth1,
			namespace: isPrev ? tweenNsPrev : tweenNsNext
		});
		$t(newCurImgEl, animateParams).tween({
			left: Math.round(oldCurOffset.left - newCurImgOffset.left),
			top: Math.round(oldCurImgOffset.top - oldCurOffset.top),
			width: oldCurWidth1,
			namespace: isPrev ? tweenNsPrev : tweenNsNext
		});
		$t(oldImgEl, animateParams).tween({
			opacity: 0,
			namespace: isPrev ? tweenNsPrev : tweenNsNext
		});
		$t(newImgEl, animateParams).tween({
			opacity: 1,
			namespace: isPrev ? tweenNsPrev : tweenNsNext
		});

		currentIndex = imageData.current.index;
	}

	function onPrevComplete() {
		var
			curPicEl = core.viewEl.find('.current .picture'),
			nextPicEl = core.viewEl.find('.next .picture'),
			prevImgEls = core.viewEl.find('.prev .picture img'),
			curImgEl = curPicEl.find('img'),
			nextImgEl = nextPicEl.find('img');

		nextImgEl.remove();
		curImgEl.appendTo(nextPicEl);
		prevImgEls.eq(0).removeClass('hid');
		prevImgEls.eq(1).appendTo(curPicEl);

		core.viewEl.find('.picture').css('height', '');
		core.viewEl.find('.picture img').css(defaultCss);
		core.animated(false);
		core.busy(false);

		core.eventDispatcher.dispatch('imageSelect', {
			index: currentIndex,
			imageInfo: core.loader.item(currentIndex)
		});
	}

	function onNextComplete() {
		var
			curPicEl = core.viewEl.find('.current .picture'),
			prevPicEl = core.viewEl.find('.prev .picture'),
			nextImgEls = core.viewEl.find('.next .picture img'),
			curImgEl = curPicEl.find('img'),
			prevImgEl = prevPicEl.find('img');

		prevImgEl.remove();
		curImgEl.appendTo(prevPicEl);
		nextImgEls.eq(0).removeClass('hid');
		nextImgEls.eq(1).appendTo(curPicEl);

		core.viewEl.find('.picture').css('height', '');
		core.viewEl.find('.picture img').css(defaultCss);
		core.animated(false);
		core.busy(false);

		core.eventDispatcher.dispatch('imageSelect', {
			index: currentIndex,
			imageInfo: core.loader.item(currentIndex)
		});
	}

	function change(evt) {
		if (core.busy() || core.animated()) return;

		var
			prevPicture = core.viewEl.find('.prev .picture'),
			curPicture = core.viewEl.find('.current .picture'),
			nextPicture = core.viewEl.find('.next .picture');

		fillImage(prevPicture.find('img'), evt.data.prev);
		fillImage(curPicture.find('img'), evt.data.current);
		fillImage(nextPicture.find('img'), evt.data.next);

		evt.data.prev && prevPicture.attr('href', evt.data.prev.image.src);
		evt.data.next && nextPicture.attr('href', evt.data.next.image.src);

		core.eventDispatcher.dispatch('imageSelect', {
			index: evt.data.current.index,
			imageInfo: evt.data.current
		});
	}

	function createTempBlock(imageData, isAppend) {
		var el = $('<img alt="" class="hid" />');
		fillImage(el, imageData);

		return el.prependTo(core.viewEl.find(isAppend ? '.next .picture' : '.prev .picture'));
	}

	function fillImage(el, imageData) {
		if (imageData) {
			el.attr({
				height: imageData.image.height,
				src: imageData.image.src,
				width: imageData.image.width
			}).css('visibility', '');
		} else {
			el.removeAttr('height').removeAttr('src').removeAttr('width').css('visibility', 'hidden');
		}
	}
}

$.browser.msie && parseInt($.browser.version) < 8 && $(function() {
	var
		prevArrowEl = $('.gallery_previews .prev'),
		nextArrowEl = $('.gallery_previews .next');
	if (prevArrowEl.length && nextArrowEl.length) {
		var
			arrowTop = prevArrowEl.find('.icon ins').position().top;
	
		var arrowHoverIn = function() {
			$(this).addClass('hover').find('.icon ins').css('top', '');
		};
		var arrowHoverOut = function() {
			$(this).removeClass('hover').find('.icon ins').css('top', arrowTop);
		};
	
		prevArrowEl.hover(arrowHoverIn, arrowHoverOut);
		nextArrowEl.hover(arrowHoverIn, arrowHoverOut);
	}
});
