/*
* GalleryItem
* ----------------------------------------
* @last_modified: 2007-06-29
* @author: Filatov Dmitry <alpha@design.ru>
*/

function GalleryItem(
	oContainerElement,
	oPreviewElement,
	oViewElement,
	sViewSrc,
	oCaptionElement,
	oParams
	) {

	GalleryItem.baseConstructor.call(this);

	var oParams = oParams || {};

	this.oContainerElement = oContainerElement;
	this.oPreviewElement = oPreviewElement;
	this.oViewElement = oViewElement;
	this.sViewSrc = sViewSrc;
	this.oCaptionElement = oCaptionElement;
	this.iState = GalleryItem.STATE_NORMAL;
	this.oCurrentAnimation = null;
	this.dProportion = this.oPreviewElement.offsetWidth / this.oPreviewElement.offsetHeight;
	this.iMinWidth = this.oPreviewElement.width;
	this.iMinHeight = this.oPreviewElement.height;
	this.iMaxWidth = this.iMinWidth + parseInt(this.iMinWidth * (oParams.dZoomFactor || 0.1), 10);
	this.iMaxHeight = this.iMinHeight + parseInt(this.iMinHeight * (oParams.dZoomFactor || 0.1), 10);
	this.oAnimationController = oParams.oAnimationController || new AnimationController(5);
	this.oController = null;
	this.bShowed = false;

	this.init();

}

GalleryItem.STATE_NORMAL    = 'normal';
GalleryItem.STATE_HILIGHT   = 'hilight';
GalleryItem.STATE_HILIGHTED = 'hilighted';
GalleryItem.STATE_UNHILIGHT = 'unhilight';
GalleryItem.STATE_SHOW      = 'show';
GalleryItem.STATE_SHOWED    = 'showed';
GalleryItem.STATE_HIDE      = 'hide';

GalleryItem.EVENT_TYPE_ON_BEFORE_SHOW = 'onbeforeshow';
GalleryItem.EVENT_TYPE_ON_BEFORE_HIDE = 'onbeforehide';

GalleryItem.CLASS_NAME_INVISIBLE = 'invisible';
GalleryItem.CLASS_NAME_SELECTED  = 'selected';

GalleryItem.inheritFrom(
	Observable,
	{

		init : function() {

			var oThis = this;

			Common.Event.add(
				this.oContainerElement,
				'mouseover',
				function() {

					oThis.hilight();

				}
				);

			Common.Event.add(
				this.oContainerElement,
				'mouseout',
				function() {

					oThis.unhilight();

				}
				);

			Common.Event.add(
				this.oContainerElement,
				'click',
				function(oEvent) {

					Common.Event.cancel(oEvent);

					oThis.show();

				}
				);

		},

		setController : function(oController) {

			this.oController = oController;

		},

		getState : function() {

			return this.iState;

		},

		setState : function(iState) {

			Common.Class.replace(
				this.oContainerElement,
				this.iState,
				iState
				);

			this.iState = iState;

		},

		hilight : function() {

			if(!this.shouldHilight()) {
				return;
			}

			if(this.oCurrentAnimation) {
				this.oCurrentAnimation.stop();
			}

			this.setState(GalleryItem.STATE_HILIGHT);

			this.zoom(true);

		},

		zoom : function(bHilight) {

			var oThis = this;

			this.oCurrentAnimation = new AnimationEquation(
				this.oPreviewElement,
				{
					fEquation    : AnimationEquation.Exponential.easeIn,
					aValuesStart  : [bHilight? this.iMinWidth : this.iMaxWidth],
					aValuesEnd    : [bHilight? this.iMaxWidth : this.iMinWidth],
					iFramesCount : 10,
					fCallbackFunction    : function(oAnimation) {

						var iMarginLeft = (oAnimation.getValuesCurrent()[0] - oThis.iMinWidth) / 2;

						Common.Dom.setStyle(
							oAnimation.oElement,
							'width: ' + oAnimation.getValuesCurrent()[0] + 'px; height: ' + (oAnimation.getValuesCurrent()[0] / oThis.dProportion) + 'px; margin-left: -' + iMarginLeft + 'px; margin-top: -' + (iMarginLeft / oThis.dProportion) + 'px'
							);

					},
					fStopCallbackFunction : function(oAnimation) {

						if(bHilight) {
							oThis.setState(GalleryItem.STATE_HILIGHTED);
						}
						else {
							oThis.setState(GalleryItem.STATE_NORMAL);
						}

					}
				}
				);

			this.oAnimationController.addAnimation(this.oCurrentAnimation);
			this.oAnimationController.start();

		},

		shouldHilight : function() {

			return this.getState() == GalleryItem.STATE_NORMAL || this.getState() == GalleryItem.STATE_UNHILIGHT;

		},

		unhilight : function(bIgnoreShowed) {

			if(!this.shouldUnhilight()) {
				return;
			}

			if(!this.isShowed() || bIgnoreShowed) {

				this.setState(GalleryItem.STATE_UNHILIGHT);
				
				this.zoom(false);
				
			}

		},

		shouldUnhilight : function() {

			return this.getState() == GalleryItem.STATE_HILIGHT || this.getState() == GalleryItem.STATE_HILIGHTED || this.getState() == GalleryItem.STATE_SHOWED;

		},

		show : function() {

			if(
				this.isShowed() ||
				!this.oController ||
				!this.oController.isAllowedShow(this)
				) {
				return;
			}

			this.notify(GalleryItem.EVENT_TYPE_ON_BEFORE_SHOW);

			this.setState(GalleryItem.STATE_SHOWED);

			this.oViewElement.src = this.sViewSrc;

			Common.Class.add(this.oContainerElement, GalleryItem.CLASS_NAME_SELECTED);
			Common.Class.remove(this.oCaptionElement, GalleryItem.CLASS_NAME_INVISIBLE);

			this.bShowed = true;

			this.oController.updateArrows();

		},

		hide : function() {

			if(!this.isShowed()) {
				return;
			}
			
			this.unhilight(true);

			this.notify(GalleryItem.EVENT_TYPE_ON_BEFORE_HIDE);

			this.setState(GalleryItem.STATE_NORMAL);

			Common.Class.remove(this.oContainerElement, GalleryItem.CLASS_NAME_SELECTED);
			Common.Class.add(this.oCaptionElement, GalleryItem.CLASS_NAME_INVISIBLE);

			this.bShowed = false;

		},

		isShowed : function() {

			return this.bShowed;

		}

	}
	);

