/*
 * Ext Core Library Examples 3.0 http://extjs.com/ Copyright(c) 2006-2009, Ext
 * JS, LLC.
 * 
 * The MIT License
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 */
Ext.ns('Ext.ux');

Ext.ux.Carousel = Ext.extend(Ext.util.Observable, {
			interval : 3,
			transitionDuration : 1,
			transitionType : 'carousel',
			transitionEasing : 'easeOut',
			itemSelector : 'img',
			activeSlide : 0,
			autoPlay : false,
			showPlayButton : false,
			pauseOnNavigate : false,
			wrap : false,
			loadedItems : [],
			freezeOnHover : false,
			navigationOnHover : false,
			hideNavigation : false,
			zIndex : 500,
			

			constructor : function(elId, config) {
				config = config || {};
				Ext.apply(this, config);

				Ext.ux.Carousel.superclass.constructor.call(this, config);

				this.addEvents('beforeprev', 'prev', 'beforenext', 'next',
						'change', 'play', 'pause', 'freeze', 'unfreeze');

				this.el = Ext.get(elId);
				this.slides = this.els = [];

				if (this.autoPlay || this.showPlayButton) {
					this.wrap = true;
				};

				if (this.autoPlay && config.showPlayButton === undefined) {
					this.showPlayButton = true;
				}

				this.initMarkup();

				if (this.slides.length <= 1) {
					this.autoPlay = false;
				}

				this.initEvents();
				
				
				
				if (this.carouselSize > 0) {
					this.refresh();
				}
			},

			initMarkup : function() {
				var dh = Ext.DomHelper;

				this.carouselSize = 0;

				this.els.container = dh.append(this.el, {
							cls : 'ux-carousel-container'
						}, true);
				this.els.slidesWrap = dh.append(this.els.container, {
							cls : 'ux-carousel-slides-wrap'
						}, true);

				this.els.navigation = dh.append(this.els.container, {
							cls : 'ux-carousel-nav'
						}, true).hide();
				this.els.caption = dh.append(this.els.navigation, {
							tag : 'h2',
							cls : 'ux-carousel-caption'
						}, true);
				this.els.navNext = dh.append(this.els.navigation, {
							tag : 'a',
							href : '#',
							cls : 'ux-carousel-nav-next'
						}, true);
				if (this.showPlayButton) {
					this.els.navPlay = dh.append(this.els.navigation, {
								tag : 'a',
								href : '#',
								cls : 'ux-carousel-nav-play'
							}, true)
				}
				this.els.navPrev = dh.append(this.els.navigation, {
							tag : 'a',
							href : '#',
							cls : 'ux-carousel-nav-prev'
						}, true);

				// set the dimensions of the container
				this.slideWidth = this.el.getWidth(true);
				this.slideHeight = this.el.getHeight(true);

				this.els.container.setStyle({
							width : this.slideWidth + 'px',
							height : this.slideHeight + 'px'
						});

				if (!this.hideNavigation) {
					this.els.container.setStyle({
								height : (this.slideHeight + this.els.navigation
										.getHeight(true))
										+ 'px'
							});

					this.els.navigation.setStyle({
								top : this.slideHeight + 'px'

							});

					this.el.setStyle({
								height : (this.slideHeight + this.els.navigation
										.getHeight(true))
										+ 'px',
								width : this.els.container.getWidth() + 'px'

							});
				}

				this.els.caption.setWidth((this.slideWidth
						- (this.els.navNext.getWidth() * 2)
						- (this.showPlayButton
								? this.els.navPlay.getWidth()
								: 0) - 20)
						+ 'px')
				var j = 0;
				this.loadedItems[0] = 0;
				var img1 = [];
				for (img in this.files) {
				
					if (Ext.isPrimitive(this.files[img])) {
						this.loadedItems[j] = 0;
				
							
								
							
														
							timeout = (Ext.isIE) ? 250 : 100;	
						 img1[j] = new Image();		
								
								
									img1[j].onload = (function(e) {
									
								
								
								(function(f) {
								
								
							if (f == 0){
			
					this.slides[0].fadeIn({
												duration : 1.5
														
											});
				}	
						
					this.loadedItems[e]  = 1;
					
					}).createDelegate(this, [e]).defer(timeout);
								
								
			
					
				}).createDelegate(this, [j]);		
								
						
								
						img1[j].src = this.files[img];		
j++;


	dh.append(this.els.slidesWrap, {
									tag : 'img',
								
									src : this.files[img]
								}, true)


					}
				}
				var c = 0;
				this.el.select(this.itemSelector).appendTo(this.els.slidesWrap)
						.each(function(item) {
							item = item.wrap({
										cls : 'ux-carousel-slide'
									});
							c++;		
							this.slides.push(item);
							item.setWidth(this.slideWidth + 'px')
									.setHeight(this.slideHeight + 'px');
							//if (c > 1){
							item.setStyle({'visibility':'hidden'});
							//}
						}, this);

				this.carouselSize = this.slides.length;
				if (this.navigationOnHover) {

					this.els.navigation.setStyle('top',
							(-1 * this.els.navigation.getHeight()) + 'px');
				}
				this.el.clip();
			},

			initEvents : function() {
				this.els.navPrev.on('click', function(ev) {
							ev.preventDefault();
							var target = ev.getTarget();
							target.blur();
							if (Ext.fly(target)
									.hasClass('ux-carousel-nav-disabled'))
								return;
							this.prev();
						}, this);

				this.els.navNext.on('click', function(ev) {
							ev.preventDefault();
							var target = ev.getTarget();
							target.blur();
							if (Ext.fly(target)
									.hasClass('ux-carousel-nav-disabled'))
								return;
							this.next();
						}, this);

				if (this.showPlayButton) {
					this.els.navPlay.on('click', function(ev) {
								ev.preventDefault();
								ev.getTarget().blur();
								if (this.playing) {
									this.pause();
								} else {
									this.play();
								}
							}, this);
				};

				if (this.freezeOnHover) {
					this.els.container.on('mouseenter', function() {
								if (this.playing) {
									this.fireEvent('freeze',
											this.slides[this.activeSlide]);
									Ext.TaskMgr.stop(this.playTask);
								}
							}, this);
					this.els.container.on('mouseleave', function() {
								if (this.playing) {
									this.fireEvent('unfreeze',
											this.slides[this.activeSlide]);
									Ext.TaskMgr.start(this.playTask);
								}
							}, this, {
								buffer : (this.interval / 2) * 1000
							});
				};

				if (this.navigationOnHover) {
					this.els.container.on('mouseenter', function() {
								if (!this.navigationShown) {
									this.navigationShown = true;
									this.els.navigation.stopFx(false).shift({
												y : this.els.container.getY(),
												duration : this.transitionDuration
											})
								}
							}, this);

					this.els.container.on('mouseleave', function() {
								if (this.navigationShown) {
									this.navigationShown = false;
									this.els.navigation.stopFx(false).shift({
										y : this.els.navigation.getHeight()
												- this.els.container.getY(),
										duration : this.transitionDuration
									})
								}
							}, this);
				}

				if (this.interval && this.autoPlay) {
					this.play();
				};
			},

			prev : function() {
				if (this.fireEvent('beforeprev') === false) {
					return;
				}
				if (this.pauseOnNavigate) {
					this.pause();
				}
				this.setSlide(this.activeSlide - 1);

				this.fireEvent('prev', this.activeSlide);
				return this;
			},

			next : function() {
				if (this.fireEvent('beforenext') === false) {
					return;
				}
				if (this.pauseOnNavigate) {
					this.pause();
				}
				this.setSlide(this.activeSlide + 1);

				this.fireEvent('next', this.activeSlide);
				return this;
			},

			play : function() {
				if (!this.playing) {
					this.playTask = this.playTask || {
						run : function() {
						
							
						
								this.playing = true;
								this.setSlide(this.activeSlide + 1);
						
						},
						interval : this.interval * 1000,
						scope : this
					};

					this.playTaskBuffer = this.playTaskBuffer
							|| new Ext.util.DelayedTask(function() {
										Ext.TaskMgr.start(this.playTask);
									}, this);

					this.playTaskBuffer.delay(this.interval * 1000);
					this.playing = true;
					if (this.showPlayButton)
						this.els.navPlay.addClass('ux-carousel-playing');
					this.fireEvent('play');
				}
				return this;
			},

			pause : function() {
				if (this.playing) {
					Ext.TaskMgr.stop(this.playTask);
					this.playTaskBuffer.cancel();
					this.playing = false;
					this.els.navPlay.removeClass('ux-carousel-playing');
					this.fireEvent('pause');
				}
				return this;
			},

			clear : function() {
				this.els.slidesWrap.update('');
				this.slides = [];
				this.carouselSize = 0;
				this.pause();
				return this;
			},

			add : function(el, refresh) {
				var item = Ext.fly(el).appendTo(this.els.slidesWrap).wrap({
							cls : 'ux-carousel-slide'
						});
				item.setWidth(this.slideWidth + 'px')
						.setHeight(this.slideHeight + 'px');
				this.slides.push(item);
				if (refresh) {
					this.refresh();
				}
				return this;
			},

			refresh : function() {
				this.carouselSize = this.slides.length;
				this.els.slidesWrap
						.setWidth((this.slideWidth * this.carouselSize) + 'px');
				if (this.carouselSize > 0) {
					if (!this.hideNavigation)
						this.els.navigation.show();
					this.activeSlide = 0;
					this.setSlide(0, true);
				}
				return this;
			},

			setSlide : function(index, initial) {
				if (!this.wrap && !this.slides[index]) {
					return;
				} else if (this.wrap) {
					if (index < 0) {
						index = this.carouselSize - 1;
					} else if (index > this.carouselSize - 1) {
						index = 0;
					}
				}
				if (!this.slides[index]) {
					return;
				}
				
				
			
				
				
					if (!initial && !this.loadedItems[index]){
					
						return;	
					}
				
				

				this.els.caption.update(this.slides[index].child(
						':first-child', true).title
						|| '');
				var offset = index * this.slideWidth;
				if (!initial) {

					switch (this.transitionType) {
						case 'fade' :
							this.slides[index].setOpacity(0);

							this.slides[this.activeSlide].stopFx(false)
									.fadeOut({
										duration : this.transitionDuration / 2,
										callback : function() {
											this.els.slidesWrap.setStyle(
													'left', (-1 * offset)
															+ 'px');
											this.slides[this.activeSlide]
													.setOpacity(1);
											this.slides[index].fadeIn({
												duration : this.transitionDuration
														/ 2
											});
										},
										scope : this
									})
							break;
						case 'blend' :

							this.slides[this.activeSlide].setOpacity(1);
							this.slides[index].setOpacity(0);

							this.slides[this.activeSlide].setStyle({
										zIndex : this.zIndex
									});
							this.zIndex = this.zIndex + 1;
							this.slides[index].setStyle({
										zIndex : this.zIndex
									});

							this.slides[index].stopFx(false).fadeIn({
										duration : this.transitionDuration / 2,
										callback : function() {

										},
										scope : this
									})

							break;
						default :
							var xNew = (-1 * offset)
									+ this.els.container.getX();
							this.els.slidesWrap.stopFx(false);
							this.els.slidesWrap.shift({
										duration : this.transitionDuration,
										x : xNew,
										easing : this.transitionEasing
									});
							break;
					}
				} else {
					this.els.slidesWrap.setStyle('left', '0');

					switch (this.transitionType) {

						case 'blend' :
							
							for (i = 0; i < this.slides.length; i++) {
								this.slides[i].setStyle({
											'position' : 'absolute'
										});
								this.zIndex = this.zIndex - 1;
								this.slides[index].setStyle({
											zIndex : this.zIndex
										});
							}

							break;
						default :

							break;
					}
				}

				this.activeSlide = index;
				this.updateNav();
				this.fireEvent('change', this.slides[index], index);
			},

			updateNav : function() {
				this.els.navPrev.removeClass('ux-carousel-nav-disabled');
				this.els.navNext.removeClass('ux-carousel-nav-disabled');
				if (!this.wrap) {
					if (this.activeSlide === 0) {
						this.els.navPrev.addClass('ux-carousel-nav-disabled');
					}
					if (this.activeSlide === this.carouselSize - 1) {
						this.els.navNext.addClass('ux-carousel-nav-disabled');
					}
				}
			}
		});
