/*
UI - filmstrip
#
# # BUILD  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#	jq(".ui-filmstrip").filmstrip({options});
#
# # HTML # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#	data-name - unique name of filmstrip
#	data-options - filmstrip optional settings (
#		dir: 'h', 					|> direcrion (h=horizontal, v=vertical)
#		spaceBetwenItems: false, 	|> add N space betwen items (N = number)
#		itemsPerSlide: false,		|> split slide to N equal fields (N = number),
#
#		autoplay: false,			|> number of miliseconds to automaticly perform animation,
#		animation: 'next',			|> type of animation to perform,
#		easing: 'easeInCubic'		|> jQuery build in easing functions (http://jqueryui.com/demos/effect/#easing),
#		duration: 1000				|> number of miliseconds of animation duration,
#	)
#		
#	<div class="ui-filmstrip" data-name="unique name" data-options="{dir:'h',spaceBetwenItems:0,autoplay:4000}">
#		<div class="ui-filmstrip-item" name="0">content</div>
#		<div class="ui-filmstrip-item" name="1">content</div>
#		<div class="ui-filmstrip-item" name="2">content</div>
#	</div>
#	
# # BUTTONS  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#	target - spceifies data-name of filmstrip and action (prev, next or item name) separated with -
#		
#	<div target="shopFilmGallery-prev"></div>
#	<a target="shopFilmGallery-next"></a>
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
*/

(function($) {

$.widget("ui.filmstrip", {
	attributeName: {
		options:'data-options',
		groupName:'data-name',
		target:'data-target'
	},
	options: {
		groupName:'filmstrip',
		settings: {
			dir:'h',
			itemsPerSlide:false,
			step: 1,
			spaceBetwenItems: false,
			autoplay:false,
			action: 'next',
			easing: 'easeInCubic',
			duration: 1000,
			delay: 0,
			startPoint: 0, endPoint: 0,
			onChange: function(self, pointer) {},
			onShow: function(self, pointer) {}
			
		},
		playback: {state:'stop',points:{}, length:0, pointer:0},
		item:  {offset: 0,outerSize:0,size:0,cssObj: {} },
		slide: {nodes: null,size: 0, items: 0},
		timer: false,
		buttons: null,
		binds: {menu:{},all:{}}
	},
	
	_create: function() {
		this.ele = this.element;
		this.ele.css('visibility','hidden');
		this.o = this.options;
		//$.ui.filmstrip.store(this.o.groupName, this);
		var content = this.ele.children('.ui-filmstrip-item');
		this.o.playback.pointer = this.o.settings.startPoint;
		
		// creates slide placeholder for items and append it to filmstrip
		this.o.slide.node = $("<div class='ui-filmstrip-slide'/>").appendTo(this.ele).html(content).css({'left':'0','top':'0','position':'absolute','padding':0})
		
		
		// get and overide options and settings from attribute values
		if(this.ele.attr(this.attributeName.options)) $.extend(true, this.o.settings, this.ele.getMeta(this.attributeName.options));
		if(this.ele.attr(this.attributeName.groupName)) this.o.groupName = this.ele.attr(this.attributeName.groupName);

		// convert space variable to number
		this.o.settings.spaceBetwenItems = this.o.settings.spaceBetwenItems != false ? Number(this.o.settings.spaceBetwenItems):0;
		this.o.settings.autoplay = this.o.settings.autoplay != false ? Number(this.o.settings.autoplay):false;
		
		// store function name for width or height depends on direction
		if(this.o.settings.dir=="h") {
			this.o.fn = {
				size : "width",
				_size : "height",
				iSize : "innerWidth",
				_iSize : "innerHeight",
				outerSize : "outerWidth",
				xy: "left"
			}
			this.o.settings.spaceBetwenItemsCss = {'width':this.o.settings.spaceBetwenItems+'px','float':'left'}
		}
		else {
			this.o.fn = {
				size : "height",
				_size : "width",
				iSize : "innerHeight",
				_iSize : "innerWidth",
				outerSize : "outerHeight",
				xy: "top"
			}
			this.o.settings.spaceBetwenItemsCss = {'height':this.o.settings.spaceBetwenItems+'px'}
		}
		// store element inner size for calculating fixed size of items
		this.ele.extend({
			size : this[this.o.fn.iSize](this.ele),
			_size : this[this.o.fn._iSize](this.ele)
			
		}).css({'position':'relative'});
//		}).css({'overflow':'hidden','position':'relative'});
		
				
		this.o.playback.state = this.o.settings.autoplay == false ? 'stop':'play';
		this.o.slide.size -= this.o.settings.spaceBetwenItems;
		
	},
	_init: function() {
		
		var items = this.o.slide.node.find(".ui-filmstrip-item"),
			self = this;
		items.css('overflow','hidden')
		// settings for FixedItems
		if(typeof this.o.settings.itemsPerSlide == "number") {
			this.o.settings.itemsPerSlide = (this.o.settings.itemsPerSlide > items.length) ? items.length:this.o.settings.itemsPerSlide;
			
			this.o.item.offset = items.eq(0)[this.o.fn.outerSize](true)- this[this.o.fn.iSize](items.eq(0));
			this.o.item.outerSize = (this.ele.size/this.o.settings.itemsPerSlide);
			this.o.item.size = this.o.item.outerSize-this.o.item.offset;
			this.o.item.cssObj['min-'+this.o.fn.size]='inherit';
			this.o.item.cssObj['max-'+this.o.fn.size]='inherit';
			this.o.slide.items = items.length;
			
			this.addFixedItems(items);
		} 
		// settings for RelativeItems
		else {
			this.o.item.size = [];
			
			this.addRelativeItems(items);
		}
		
		this.ele.css('visibility','visible');
		
		this.o.slide.node.css(this.o.fn.xy, this.o.playback.points[this.o.settings.action][this.o.playback.pointer]+'px')
		this.o.settings.onShow(this, this.o.playback.pointer-this.o.settings.startPoint)
		
		//css[this.o.fn.xy] = pos+'px';
		//console.log(this.o.fn.xy+" = "+this.o.playback.points[this.o.settings.action][this.o.playback.pointer])
		
		
		
		if(this.o.playback.length > 1) {
			var self = this;
			setTimeout(function(){self.build()}, this.o.settings.delay);
		}
			
	},
	
	
	build: function() {
		this.addEvents();
		if(this.o.binds.menu.length > 0) this.o.binds.menu.eq(this.o.playback.pointer-this.o.settings.startPoint).addClass('hover')
		if(this.o.playback.state == 'play') this.startAutoPlay();
		
	},
	
	
	innerWidth: function(items) {
		return items.innerWidth() - (parseInt(items.css('padding-right')) || 0) - ( parseInt(items.css('padding-left')) || 0);
	},
	innerHeight: function(items) {
		return items.innerHeight() - (parseInt(items.css('padding-top')) || 0) - ( parseInt(items.css('padding-bottom')) || 0);
	},
	addFixedItems: function(items) {
		var self = this,
			playback = this.o.playback;
			playback.points = {next: [],prev: []};
		
		// store slide size relative to number of items and item outerWidth
		this.o.slide.size += this.o.item.outerSize*items.length;
		playback.length = items.length
		// add items in slide node and execute css styles
		this.o.slide.node.append(items);
		
		items.each(function(i, ele) {
			var _this = $(this);
			// overide item size with fixed size
			_this[self.o.fn.size](self.o.item.size).css(self.o.item.cssObj);
			playback.points.prev[i] = -(self.o.item.outerSize*i)
			playback.points.next[i] = -(self.o.item.outerSize*i)
			
			
		})//.css('background','none');
		
		// update slide size, playback options
		this.updateSlideSettings();
		this.updateFixedPlaybackPoints();
		return;
	},
	updateFixedPlaybackPoints: function() {
		
	},
	
	addRelativeItems: function(items) {
		var self = this;

		// add items in slide node and execute css styles
		this.o.slide.node.append(items);
		
		items.each(function(i, ele) {
			var _this = $(this),
				_i = self.o.slide.items;
			// increase items length in slide
			++self.o.slide.items;
			// store slide size
			self.o.slide.size += _this[self.o.fn.outerSize](true)+self.o.settings.spaceBetwenItems;
			// store item size to object
			self.o.item.size[_i] = _this[self.o.fn.outerSize](true);
			
			
			// add space betwen items
			if(self.o.settings.spaceBetwenItems) {
				
				$("<div>&nbsp;</div>").insertAfter(_this).css(self.o.settings.spaceBetwenItemsCss);
			}
		});
		
		// update slide size, playback options
		this.updateSlideSettings();
		
		this.updateRelativePlaybackPoints();
		
		return;
	},
	updateRelativePlaybackPoints:function() {
		// get sliding size
		
		var playback = this.o.playback;
		playback.points = {next: [],prev: []};
		
		var slidingSize = this.ele.size - this.o.slide.size,
			prevSize = this.o.item.size,
			nextSize = $.extend([], this.o.item.size),
			stopFor = {prev:false,next:false};
		nextSize.reverse();
		
		var prevIncrement = 0,
			nextIncrement = slidingSize;
			
		for(var i = 0; i<prevSize.length; i++) {
			if(prevIncrement > slidingSize)
				playback.points.prev[i] = prevIncrement;
			else if(!stopFor.prev) {
				playback.points.prev[i] = slidingSize;
				stopFor.prev = true;
			}
			
			if(nextIncrement < 0)
				playback.points.next[i] = nextIncrement;
			else if(!stopFor.next) {
				playback.points.next[i] = 0;
				
				playback.points.next.reverse();
				stopFor.next = true;
			}
			
			if(stopFor.next && stopFor.prev) {
				playback.length = i+1;
				
				break;
			}
			prevIncrement -= prevSize[i]+this.o.settings.spaceBetwenItems;
			nextIncrement += nextSize[i]+this.o.settings.spaceBetwenItems;
		}
		//alert(SerializeObject(this.o.playback.points));
		
		
	},
	
	updateSlideSettings:function() {
		// overide slide size with new value
		var css = {};
		css[this.o.fn.size]=this.o.slide.size+'px';
		//alert(this.ele[this.o.fn._size]())
		css[this.o.fn._size]=this.ele._size+'px';
		this.o.slide.node.css(css);
		
		// set playback state to stop if slide size is smaller than filmstrip placeholder
		this.o.playback.state = this.o.slide.size <= this.ele.size ? 'stop':this.o.playback.state;
		
	},
	addSpaceBetwenItems: function(space) {
		if(!this.o.settings.spaceBetwenItems) return false;
		// .not(':last-child')
		this.o.slide.node.find(".ui-filmstrip-item")//.css({'margin':'0px 0'});
	},
	
	add:function(arg1, arg2) {
		var slide = this.o.slide.node;
			
		var items = $("<div class='ui-filmstrip-item' data-name='"+this.o.slide.items+"'/>").append(arg1);
			
		if(typeof this.o.settings.itemsPerSlide == "number")
			this.addFixedItems(items);
		else
			this.addRelativeItems(items);
			
		if(this.o.playback.length > 1)
			this.addEvents();
			
	},
	destroy: function() {
		var o = this.options;

		return this;
	},
	
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	Bind filmstrip events 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	action_next: function() {
		this.setNextPointer();
		this.goToBreakPoint('next')
	},
	action_prev: function() {
		this.setPrevPointer();
		this.goToBreakPoint('prev')
	},
	action_goTo: function(point) {
		this.o.playback.pointer = Number(point)+this.o.settings.startPoint;
		
		this.goToBreakPoint('prev')
		
	},
	addEvents: function() {
		//if(this.o.settings.step >= this.o.playback.length) this.o.settings.step = this.o.playback.length-
		var i = 0,
			self = this,
			groupName = this.o.groupName;
			buttonSelector = "*["+this.attributeName.target+"|="+groupName+"]";
			
		self.o.binds.menu = []
		
		//console.log(buttonSelector)
		self.o.binds.all = $(buttonSelector).each(function(i,ele) {
			var _this = $(this),
				action = _this.attr(self.attributeName.target).substr(groupName.length+1);
				
				
			if(action == "next" || action == 'prev') {
				_this.click(function(e) {
					self['action_'+action]();
				})
				
			} else {
				
				
				
				self.o.binds.menu[i] = _this[0]
				//console.log(self.o.binds.menu)
				_this.click(function(e) {
					//console.log(action)
					self.action_goTo(action);
					return false
				})
				
				
			}
		}).css({'cursor':'pointer'});
		self.o.binds.menu = $(self.o.binds.menu)
		
		
		this.addAutoPlayEvents(this.ele);
		this.addAutoPlayEvents(this.o.binds.all);
		
	},
	addAutoPlayEvents: function(items) {
		var self = this;
		
		items.mouseenter(function() {
		  	self.stopAutoPlay()
		  	
		}).mouseleave(function() {
			if(typeof self.o.settings.autoplay == "number") self.startAutoPlay()
		});
	},
	setNextPointer: function() {
		var playback = this.o.playback,
			set = this.o.settings,
			itemsPerSlide = this.o.settings.itemsPerSlide==false ? 0:(this.o.settings.itemsPerSlide-1);
				
		playback.pointer += set.step;
		
		if(playback.pointer == (playback.length-this.o.settings.endPoint-itemsPerSlide)) {
			playback.pointer = this.o.settings.startPoint;
		}
	},
	setPrevPointer: function() {
		var playback = this.o.playback,
			set = this.o.settings,
			itemsPerSlide = this.o.settings.itemsPerSlide==false ? 0:(this.o.settings.itemsPerSlide-1);
			
		playback.pointer -= set.step;
		
		if(playback.pointer == this.o.settings.startPoint-1) {
			playback.pointer = playback.length-1-this.o.settings.endPoint-itemsPerSlide;
		}
	},
	
	
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	Preform animation
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	goToBreakPoint: function(type) {
		// Show slide
		var pos = this.o.playback.points[type][this.o.playback.pointer],
				slide = this.o.slide.node,
				css = {};
				
				css[this.o.fn.xy] = pos+'px';
				
//		console.log(this.o.binds.menu)
//		this.o.binds.menu.addClass('hover')
//		return false
		if(this.o.binds.menu[this.o.playback.pointer-this.o.settings.startPoint]) {		
			this.o.binds.menu.removeClass('hover')	
			this.o.binds.menu.eq(this.o.playback.pointer-this.o.settings.startPoint).addClass("hover")
		}
		
		this.o.settings.onShow(this, this.o.playback.pointer-this.o.settings.startPoint)
		this.o.settings.onChange(this, this.o.playback.pointer-this.o.settings.startPoint)
		slide.animate(css, { queue:false, duration:this.o.settings.duration, ease:this.o.settings.easing});
		
	},
	
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	Autoplay timer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
	startAutoPlay: function() {
		var self = this;
		//console.log(self.o.settings.action);
		if(!this.o.timer) this.o.timer = setInterval(function() {self['action_'+self.o.settings.action]()},self.o.settings.autoplay);
	},
	stopAutoPlay: function() {
		clearInterval(this.o.timer);
		this.o.timer = false;
		
	}

	

});

$.extend($.ui.filmstrip, {
	version: '1.8.2',
	chd:[],
	store:function(name, target) {
		this.chd[name]= target;
		
	},
	get:function(name) {
		return this.chd[name];
	}
});

$.extend($.ui.filmstrip.prototype, {
	
});

})(jQuery);

